Grants
Grants are the permission system in BYOK API. They control what each consumer app can do with your AI providers.
Capabilities
Each grant is associated with one or more capabilities:
| Capability | Description |
|---|---|
language | Text generation (chat, completion) |
image | Image generation (DALL-E, etc.) |
speech | Text-to-speech |
transcription | Speech-to-text |
Grant lifecycle
Request → Pending → Approved/Denied → Active → Revoked/Expired1. Request
A consumer app calls client.requestGrant() with the capabilities it needs:
const result = await client.requestGrant({
capabilities: ["language", "image"],
})2. Consent popup
The bridge opens a popup window on its own origin showing:
- The requesting app's name and domain
- The capabilities being requested
- Approve/Deny buttons
The user makes a decision entirely within the bridge's UI — the consumer app cannot influence or read the popup.
3. Grant record
On approval, the bridge creates a GrantRecord in IndexedDB:
type GrantRecord = {
grantId: string
consumerId: string
requirementId: string
capabilities: Capability[]
status: "active" | "revoked" | "expired"
createdAt: number
expiresAt: number | null
}4. Auto-restore
When a consumer app reconnects (e.g., page refresh), the client's handshake() call checks for existing active grants. If found, they're automatically restored without showing the consent popup again.
5. Revocation
Grants can be revoked at any time:
- By the user — through the bridge dashboard
- By the app — calling
client.revokeGrant(grantId) - By expiration — if the grant has an
expiresAttimestamp
When a grant is revoked, the bridge notifies the consumer app via the onGrantStateChanged callback.
Grant state machine
The consumer app observes grant state changes through MobX:
type GrantState =
| { type: "none" }
| { type: "pending"; requestId: string }
| { type: "granted"; grantId: string; capabilities: Capability[] }
| { type: "denied" }
| { type: "revoked" }
| { type: "expired" }All state transitions are delivered via the onGrantStateChanged callback in the ConsumerAPI.
Security model
- Grants are stored in the bridge's IndexedDB, inaccessible to consumer apps
- The consent popup runs on the bridge origin — consumer apps cannot forge approvals
- Each grant is scoped to a specific consumer ID and set of capabilities
- The bridge validates every API request against the active grant before forwarding