CreatorOS capability showcase
Standalone preview. Identity uses the DEV_IDENTITY_SUB stub; the credits/tasks panels are embed-only, so they report “not embedded” here — open the app inside CreatorOS to run them live.
Who is the caller?
user.readThe iframe asks this app’s backend, which introspects the injected context server-to-server (a verified user.read) and relays the platform’s authoritative answer — the sole trust anchor for identity.
Raw context vs. verified identity
X-Platform-Context (unverified claims)These claims are decoded from the JWT payload without a signature check. They must never authorize anything — compare them with the introspected identity above. Shown only to make the trust boundary concrete.
Move the user’s credits
credits.spend · credits.gain · credits.refundAuthorized by the app backend, never the browser: D holds the client secret and calls the platform with the echoed context. Idempotency keys are scoped per (app, user, operation) — one key per logical event.
Start a tool task & read generations
tasks.create · generations.readCreating a task charges the user’s real credits and only works for tools in the app’s allowed_tools. Keep the returned id to poll the task and pull its produced assets; generations lists the user’s work across tasks.
Injected secrets
secret_bindings (server-side injection)The platform injects each admin-configured secret toward this backend as a header or query param, stripping any client-supplied one of the same name first. This reports which arrived, masked — a real app validates them and never ships a value to the browser.
Every call hits this app’s own backend (/api/embed/*), which alone holds the client secret. See .claude/rfc/apps.md for the full contract.