Trust & security
read as.mdHosted ggui sits between your agent and your user, so it necessarily handles both sides’ data. This page says what it holds, for how long, and which parts a language model sees. Where the honest answer is a limit rather than a guarantee — the host controls the sandbox, a signature is not an audit, one contract field can carry data into the prompt — it says that instead of reassuring you.
Your data in hosted ggui
Section titled “Your data in hosted ggui”A render is one generated interface. Everything below is scoped to a render, an app, or your account.
| Data | Stored where | Reaches a language model? |
|---|---|---|
| The intent and contract your agent sends | The render row in DynamoDB, and — if the render becomes a reusable blueprint — a blueprint row | Yes. This is the generation prompt |
| The generated component code | Inline on the render row; durable blueprints go to S3 keyed by content hash; a copy of the TSX lands in a per-user render cache | It is the model’s output |
| The props your agent renders with | On the render row, next to the code | No. Props values are not part of the generation prompt |
| What your user does in the UI — action payloads and the context snapshot taken at that moment | Buffered on the render row until the agent consumes them, and appended to a per-render event log | Not by ggui. They are handed back to your agent, which is itself a model — see below |
| The end-user identity your auth adapter supplies | An endUserIdentity column on the render row |
No |
Connector keys (ggui_user_*) |
A SHA-256 hash plus an 8-character prefix. Plaintext is returned once at mint time and never written | No |
| Your own provider keys (BYOK) | KMS ciphertext, decrypted into memory for the duration of one call | No — the key authenticates the provider call, it is never prompt content |
What generation actually sees
Section titled “What generation actually sees”The generation prompt is built from your agent’s intent, the contract’s schemas (field names, JSON-Schema types, and any default / example values you declare on them — so treat contract examples as prompt content), the variance signals, the rendering context the host reports (device, shell, viewport), the gadget catalogue, and ggui’s own design-system documentation. Runtime props are carried alongside the generation input and deliberately not spread into it.
Blueprint matching has two tiers. An exact contract-key match is deterministic and calls no model at all. When that misses, a reranking model is asked to choose among cached candidates — and it is shown the intent plus summaries of the contracts (name:type pairs), never props or event payloads.
ggui_amend performs no generation. It swaps props and pushes them down the live channel; no model is involved. ggui_update is the same swap plus a new history card (it also mints no generation, but does advance the epoch).
The event loop is a model, by design
Section titled “The event loop is a model, by design”When your user submits a form, that payload travels back to your agent through ggui_consume. Your agent is a language model. That is the entire point of the protocol — the user’s answer becomes structured input to the next turn — but it means “does my user’s form input reach an LLM?” has the honest answer yes, yours. ggui’s own generation and matching models never see it.
What changes with your own key
Section titled “What changes with your own key”If you store a provider key and the app is configured to use it, the generation call is made with your key, so the prompt goes to your provider account under your agreement with that provider rather than through ggui’s pool. Storing a key alone does not do this — the app’s generation billing has to select it, via the Generation billing card on the app’s Keys or Settings tab in the console. See Credits, billing & BYOK for that gate and what it does to billing.
Connector keys. A key is 32 bytes of randomness prefixed ggui_user_. What gets stored is a SHA-256 hash of the whole string plus the first 8 characters, which is what the console lists. The plaintext is handed to you exactly once and is not recoverable afterwards — if you lose it, mint a new one. Revocation is a soft flag: the row survives for audit and later requests with that key are rejected. Full mechanics in Connector keys.
Provider keys. Keys you bring are validated, then encrypted with AWS KMS under an encryption context that binds them to their scope — {userId, provider} for an account-wide key, {appId, provider} for a per-app one. The plaintext is never persisted — only the KMS ciphertext, a hash, and the last four characters; decryption happens in memory for the call. Because the encryption context is cryptographically bound to the ciphertext, a key encrypted for one scope fails to decrypt in another rather than silently working. The console only ever displays the last four characters.
Publisher keys. Signing keys for the marketplace are Ed25519 and stay on your machine; the registry holds the public half. See ggui keys register.
Sandboxing
Section titled “Sandboxing”Generated code is code a model wrote. It runs in an iframe, and it never runs with access to the host document.
When ggui mounts the iframe itself, the sandbox grants allow-scripts allow-forms and deliberately withholds allow-same-origin, so the frame cannot read the page that embeds it. Camera, microphone, geolocation, and clipboard-write are only enabled when the render’s contract asked for them. Component bundles are content-addressed and served with their SHA-256 alongside; gadgets load behind an SRI integrity gate at iframe boot.
Three honest limits:
- In a third-party host, the host owns the sandbox. When your interface renders inside Claude Desktop or claude.ai, that host sets the iframe’s sandbox tokens and Content-Security-Policy. ggui declares which origins the frame needs to reach; enforcement is the host’s, and that surface is opaque to ggui.
- Marketplace gadgets are signed, not audited. Signature verification proves a bundle came from the author who published it and has not been altered since. It says nothing about what the bundle does. Public gadgets verify through sigstore, private ones through a pinned Ed25519 key — the marketplace page has both postures.
- The integrity gate is only as strong as the descriptor. A gadget installed from the registry carries a SHA-384 SRI hash that the runtime enforces. A hand-authored gadget entry with no
bundleSrifalls back to an integrity-less dynamic import, and installing a legacy artifact whose version has no pinned public key warns and continues unless you pass--strict. See Gadgets.
The channel model and where the SRI gate sits are in the architecture overview.
Operator access
Section titled “Operator access”A small operator group exists for support and monitoring, and it can read render records — the contract, the generated code, and event payloads — across accounts, through the same access-controlled admin surface that runs the service. Three facts bound it:
- Membership is manual. The group has no self-join path; an operator is added by an infrastructure command, not a sign-up flow.
- It cannot read provider keys. The BYOK key table deliberately carries no operator grant — an operator never sees your provider keys, even in encrypted form.
- Every read is individually audit-logged. Operator reads of render data go through a single audited query — the underlying models carry no direct operator grant, so a read that skips the log is structurally impossible. Each entry records the operator’s identity and the target keys, and lands in a dedicated log group retained for two years.
Deletion & retention
Section titled “Deletion & retention”Renders and their event logs. By default a render is kept indefinitely — reopening an old card from chat history always finds it, which is the point of the protocol’s rehydration story. An agent that wants a bounded lifetime sets a per-render TTL; bounded renders are purged by DynamoDB at that TTL plus a seven-day grace window, and activity on a render slides the expiry forward. Deletion of unbounded renders happens through the paths below, not a schedule.
Blueprints. A blueprint is the durable artefact — a render promoted to something reusable. Blueprints carry no TTL. Their bodies are content-addressed and reclaimed only by an operator-invoked purge (takedown, app retirement, or collection of bodies that have been unreferenced long enough to be safely orphaned), never on a schedule.
Your account. /account in the console has a type-to-confirm Delete account control. It is blockers-first: the request is refused, with the reason stated and nothing deleted, if you own a platform-managed app or if you are the last owner of an org that still has other members. If it is accepted, the account is frozen immediately — global sign-out plus disable — and an asynchronous worker then walks the deletion in order: org memberships, then each app with its keys, blueprints and renders, then your connector keys, provider keys, render cache, credit balance, renders, coupon attribution, and status subscription, then your user row. Cognito sign-in is deleted last, and only after a verification pass re-runs every finder query and finds nothing left. If anything remains, the erasure is marked failed and sign-in is deliberately preserved so the leftover can be traced.
Two things survive on purpose, both stated in the console’s own confirmation: billing records required for accounting are kept with your personal details scrubbed rather than deleted, and CLI session tokens are left to their own expiry (they are hashed and time-bounded) instead of being swept.
One gap worth naming: if you were an end user of somebody else’s hosted app, your identity data on their render rows is not reachable by your own account erasure. It persists as long as those renders do — until the app’s per-render TTL fires, the app owner deletes their account, or an operator takedown removes the rows.
Policies and status
Section titled “Policies and status”- Privacy policy — the binding statement, including subprocessors and analytics.
- Terms of service
- status.ggui.ai — live service status.
For anything this page does not answer, the privacy policy lists a contact address.