App Runtime API: schemas
The request and response bodies of the operations in this API.
AnonAuthDto
| Property | Type | Required | Description |
|---|
clientId | string | yes | AppClient public identifier. |
clientSecret | string | yes | Plaintext AppClient secret. Required on EVERY external-auth door, the anonymous one included: "anonymous" describes the subject, never the caller — the App owner controls who may open sessions in its name. |
requestedZone | string | no | Requested ExecutionEnvironment slug. Defaults to the App’s defaultZone, and either way must be in the resolved AudiencePolicy.allowedEnvironments[]. |
sessionHint | string | no | Optional client-supplied hint used for logging / debugging purposes. Not used for identity resolution — every call creates a fresh anon subject. |
AnonAuthResultDto
| Property | Type | Required | Description |
|---|
accessToken | string | yes | Signed delegated-session JWT. |
environment | string | yes | ExecutionEnvironment slug the session was minted into. |
expiresAt | string | yes | Token expiry (ISO-8601). |
sessionId | string | yes | Server-side DelegatedSession row id. |
subjectRef | string | yes | Subject ref minted into the token. |
AnonAuthResultDtoDataEnvelope
CreatePublicSessionDto
| Property | Type | Required | Description |
|---|
clientId | string | yes | AppClient public identifier. |
clientSecret | string | yes | Plaintext AppClient secret. Required even for public-anon sessions so the App owner controls who may open anon sessions. |
requestedZone | string | no | Requested ExecutionEnvironment slug (e.g. public-session). Defaults to the App's defaultZone when omitted. Must be in the resolved AudiencePolicy.allowedEnvironments[]. |
subjectAnon | boolean | no | Set true to mint a public-anon session (no externalId). Mutually exclusive with subjectExternalId. |
subjectExternalId | string | no | Upstream subject id (for external-subject audiences). Mutually exclusive with subjectAnon: true. |
CreatedPublicSessionDto
| Property | Type | Required | Description |
|---|
accessToken | string | yes | Signed delegated-session JWT. |
actorRef | string | yes | Actor ref (the AppClient). |
capabilities | array of string | yes | Capabilities the token authorizes at the gateway. |
environment | string | yes | Execution environment slug stamped on the session. |
expiresAt | string | yes | Token expiry (ISO-8601). |
externalId | string | no | The subjectExternalId this App client asserted. Absent for an anonymous session. |
sessionId | string | yes | Server-side DelegatedSession row id. |
subjectRef | string | yes | The opaque PDP subject ref minted into the token: external-subject:<id> (app-platform's ExternalSubject id, NOT the asserted subjectExternalId) or anon:<random>. Never parse it for the upstream id; read externalId. |
CreatedPublicSessionDtoDataEnvelope
DelegatedSessionActorDto
| Property | Type | Required | Description |
|---|
sub | string | yes | The acting party’s BARE identifier — an AppClient.clientId, never a "<kind>:<id>" composite. |
subjectKind | SubjectKind | yes | The acting party’s subject kind, stated explicitly by the issuer (wire claim subject_kind). Always app-client for a delegated session minted by app-platform-api. |
DelegatedSessionDto
| Property | Type | Required | Description |
|---|
actorRef | string | yes | |
appClientId | string | yes | |
appId | string | yes | |
capabilities | array of string | yes | |
createdAt | string | yes | |
environment | string | yes | |
expiresAt | string | yes | |
externalSubjectId | object or null | no | |
id | string | yes | |
orgId | string | yes | |
projectId | string | yes | |
revokedAt | object or null | no | |
subjectRef | string | yes | |
tokenJti | string | yes | |
DelegatedSessionDtoDataEnvelope
DelegatedSessionStatus
Type: one of "active", "expired", "revoked"
DelegatedSessionStatusDto
| Property | Type | Required | Description |
|---|
actorRef | string | yes | |
appClientId | string | yes | |
appId | string | yes | |
capabilities | array of string | yes | |
createdAt | string | yes | |
environment | string | yes | |
expiresAt | string | yes | |
externalSubjectId | object or null | no | |
id | string | yes | |
orgId | string | yes | |
projectId | string | yes | |
revokedAt | object or null | no | |
status | DelegatedSessionStatus | yes | |
subjectRef | string | yes | |
tokenJti | string | yes | |
DelegatedSessionStatusDtoDataEnvelope
OidcAuthDto
| Property | Type | Required | Description |
|---|
clientId | string | yes | AppClient public identifier. |
clientSecret | string | yes | Plaintext AppClient secret. Required on EVERY external-auth door, the anonymous one included: "anonymous" describes the subject, never the caller — the App owner controls who may open sessions in its name. |
idToken | string | yes | OIDC id_token issued by the upstream identity provider configured for this App. |
requestedZone | string | no | Requested ExecutionEnvironment slug. Defaults to the App’s defaultZone, and either way must be in the resolved AudiencePolicy.allowedEnvironments[]. |
OidcAuthResultDto
| Property | Type | Required | Description |
|---|
accessToken | string | yes | Signed delegated-session JWT. |
environment | string | yes | ExecutionEnvironment slug the session was minted into. |
expiresAt | string | yes | Token expiry (ISO-8601). |
externalId | string | yes | The upstream subject id: the verified id_token sub. Unique only together with the identity provider that issued it. |
sessionId | string | yes | Server-side DelegatedSession row id. |
subjectRef | string | yes | The opaque PDP subject ref minted into the token: external-subject:<id>, where <id> is app-platform's ExternalSubject id. It is NOT the upstream subject id and must never be parsed for one; read externalId for that. |
OidcAuthResultDtoDataEnvelope
PutResourceShareDto
| Property | Type | Required | Description |
|---|
expiresAt | string (date-time) | no | When the share lapses. |
level | string | yes | The level to grant — one of the type's share relations. |
subjectId | string | yes | |
subjectKind | ShareGranteeKind | yes | A user grantee is bound to that user's current membership of the org (422 when not a member). |
RequestMagicLinkDto
| Property | Type | Required | Description |
|---|
clientId | string | yes | AppClient public identifier. |
clientSecret | string | yes | Plaintext AppClient secret. Required on EVERY external-auth door, the anonymous one included: "anonymous" describes the subject, never the caller — the App owner controls who may open sessions in its name. |
email | string (email) | yes | Email address to send the magic-link to. Used as the external subject identifier. |
RequestMagicLinkResultDto
| Property | Type | Required | Description |
|---|
queued | boolean | yes | Whether the magic-link was successfully queued for delivery. Always true on success — a 2xx response means the token was created and the delivery event was published. |
RequestMagicLinkResultDtoDataEnvelope
ResourceShareDto
| Property | Type | Required | Description |
|---|
expiresAt | string (date-time) or null | yes | |
grantedBy | string | yes | <kind>:<id> of the principal who granted it. |
level | string | yes | The relation the share grants (a level of the type). |
membershipActive | boolean or null | yes | For a membership share, whether it is still the user's current membership of the org; false means the user left and the share grants nothing (it can still be removed). Null for every other kind. |
refusalCode | string or null | yes | The typed refusal code (tenant_mismatch, subject_unresolvable, ...) when state is refused, else null. |
state | ShareState | yes | Whether the share is in force. refused: the authorization plane refused its facts for good, so it grants nothing; re-put it with a valid subject, or remove it. |
subjectId | string | yes | For a membership share, the membership id (one stay of the user in the org). |
subjectKind | ShareSubjectKind | yes | |
userId | string or null | yes | The user of a membership share; null for every other kind. |
ResourceSharesDto
| Property | Type | Required | Description |
|---|
canManage | boolean | yes | Whether the caller may share or unshare this resource. |
expirable | boolean | yes | Whether a share of this type may carry an expiry; when false an expiry is refused. |
levels | array of string | yes | The levels a share of this type may grant, lowest first. A sharer may grant only a level it holds. |
shares | array of ResourceShareDto | yes | |
ResourceSharesDtoDataEnvelope
ShareGranteeKind
A user grantee is bound to that user's current membership of the org (422 when not a member).
Type: one of "user", "agent", "external-subject", "team", "role"
ShareState
Whether the share is in force. refused: the authorization plane refused its facts for good, so it grants nothing; re-put it with a valid subject, or remove it.
Type: one of "active", "refused"
ShareSubjectKind
Type: one of "membership", "agent", "external-subject", "team", "role"
SubjectKind
The acting party’s subject kind, stated explicitly by the issuer (wire claim subject_kind). Always app-client for a delegated session minted by app-platform-api.
Type: string (12 values)
TokenClass
The minted token class. Always external_session_token for a delegated session — a consumer edge can enforce it via @RequireTokenClass(TokenClass.ExternalSessionToken).
Type: one of "user_jwt", "service_jwt", "agent_runtime_token", "external_session_token", "organization_delegation"
VerifyDelegatedSessionRequestDto
| Property | Type | Required | Description |
|---|
token | string | yes | The opaque JWT. |
VerifyDelegatedSessionResponseDto
| Property | Type | Required | Description |
|---|
act | DelegatedSessionActorDto | yes | |
appId | string | yes | Id of the App this delegated session was minted FOR (the owning App.id, resolved from the backing session row). A consumer edge MUST bind the session to exactly this app before serving app data. |
capabilities | array of string | yes | |
environment | string | yes | |
exp | number | yes | |
jti | string | yes | |
org | string | yes | |
project | string | no | ABSENT when the session belongs to no project — and absent is an ANSWER, not a degenerate case (.claude/rules/project-is-optional.md). A delegated session is not an intrinsically project-scoped domain: it is an external subject holding a scoped credential against an App, and an App may be an org-scoped PORTAL whose own project_id is NULL. So the kernel's DelegatedSessionClaims.project is string | undefined, and this projection of it must be too. This field was project!: string — REQUIRED — for a while after the kernel widened the claim (422064d, "a delegated session may belong to NO project"). That is a producer that moved and a consumer that was not taught: the contract's own docblock enumerated three readers of the claim and named "the verify response DTO" as one of them. The two token-service readers pass the value through loose positions and kept compiling; this one is the only DTO-typed site, so it is where the widening surfaced — as TS2322: Type 'string | undefined' is not assignable to type 'string' at the controller's mapping, which red-lined every xema-base build and four consecutive Release (npmjs) runs. Do NOT close that error by coercing. ?? '', a non-null assertion or a cast would each satisfy the compiler by putting a BLANK tenant-scope qualifier on the wire, which callers compile against as a real project id — the silently-empty-scope shape this fleet has already paid for. Omit the claim instead; .min(1) on the kernel schema keeps '' and a fabricated 'system' equally unsatisfiable. |
session | string | yes | |
sub | string | yes | |
tenant | string | no | The subject's TENANT DISCRIMINATOR — the customer ORGANISATION it belongs to — ABSENT when it has none. This is what lets a consuming edge serve an org's customer that is itself an organisation: app-forge binds it to tenancy — an unbypassable field = subject.tenant row filter plus a stamp that stops a write crossing tenants. Before it existed that mechanism could never resolve for an external subject, so such a customer saw zero rows — safe, and silent. It is resolved from the ExternalSubject ROW, never from the presented token, and it is written only from a signature-verified id_token claim the org's own IdP issued. A consumer must therefore treat it as authoritative and must NOT accept a tenant from its own callers. ABSENT is an ANSWER — "this subject belongs to no customer organisation" — and a consumer must read it fail-closed: no tenant means a tenancy-declaring entity serves nothing, never that the filter is skipped. An anonymous session has no external subject at all and so never carries one. |
tokenClass | TokenClass | yes | The minted token class. Always external_session_token for a delegated session — a consumer edge can enforce it via @RequireTokenClass(TokenClass.ExternalSessionToken). |
VerifyDelegatedSessionResponseDtoDataEnvelope
VerifyMagicLinkDto
| Property | Type | Required | Description |
|---|
token | string | yes | The one-time magic-link token. |
VerifyMagicLinkResultDto
| Property | Type | Required | Description |
|---|
accessToken | string | yes | Signed delegated-session JWT. |
environment | string | yes | ExecutionEnvironment slug the session was minted into. |
expiresAt | string | yes | Token expiry (ISO-8601). |
externalId | string | yes | The upstream subject id: the lower-cased email address the magic link proved. |
sessionId | string | yes | Server-side DelegatedSession row id. |
subjectRef | string | yes | The opaque PDP subject ref minted into the token: external-subject:<id>, where <id> is app-platform's ExternalSubject id. It is NOT the upstream subject id and must never be parsed for one; read externalId for that. |
VerifyMagicLinkResultDtoDataEnvelope