Skip to main content

POST /api/v1/session/delegated

Mint a session acting as an externally-authenticated principal. Guarded.

WARNING: despite the path, this is not a login and it is not open. It is guarded, and the caller must already hold a certificate-login session belonging to a registered service permitted for the session:delegated operation. Open, it would let any unauthenticated caller impersonate any XAuth principal this Gateway's delegator covers.

You do not send the target identity. You send localUser, and the Gateway constructs the XAuth id by prefixing it with the xauthPrefix configured for your registered service. A body that tries to name the target itself is refused with CALLER_SUPPLIED_IDENTITY, because a caller-settable identity would defeat the whole construction.

Keys created on the resulting session are owned by the target, not by the delegator, which is what keeps per-user grant, revoke and audit intact.

The session inherits the minting service's sender key and is therefore sender-constrained: its holder is the same program holding a second credential, and that program has already proved possession of that key. Binding to the same key closes what would otherwise be the one credential on this surface that a constrained request could mint and an unconstrained one could then spend.

WARNING: the key server's delegation guard is operation-subset only. It has no tenant or namespace scoping, so this Gateway can impersonate any XAuth principal whose operation set its delegator covers. That is a property of the engine, not of this route.

Authentication​

Send the session id as Authorization: Bearer <session id>, and an RFC 9449 DPoP proof in the DPoP header if your session is bound to a key. The two are required together, not as alternatives — see Authenticating and Proving you hold your key.

This surface sets no cookie

There is no session cookie on any response and none is read on any request. Do not set credentials: "include" on a browser fetch.

Request​

FieldTypeRequiredDescription
localUserstringyesYour application's own user id. The Gateway prefixes it to build the XAuth identity; you cannot name that identity directly.

Example

{
"localUser": "..."
}

Responses​

200​

A delegated session, acting as the constructed target.

FieldTypeRequiredDescription
actingAsstringyesThe XAuth id this session acts as.
localUserstringno
servicestringno
delegatorstringnoThe subject of this Gateway's own delegating certificate.
sessionstringyesThe bearer credential.
ksKsAddressyes
systemSystemBlocknoThe cached boot snapshot of the key server this Gateway fronts. It carries no credential: the boot call that produces it cannot return one.
detailstringyes

KsAddress

FieldTypeRequiredDescription
hoststringno
portintegerno

Example

{
"actingAs": "...",
"localUser": "...",
"service": "...",
"delegator": "...",
"session": "...",
"ks": {
"host": "...",
"port": 0
},
"system": {},
"detail": "..."
}

400​

CALLER_SUPPLIED_IDENTITY -- the body named an identity field the caller may not set, or carried subjectToken, which only POST /api/v1/session/scoped takes. Or BAD_REQUEST -- localUser is missing or malformed, or the id the Gateway built from its own configured prefix is not a usable one, which is a fault in this Gateway's configuration rather than in your request.

401​

No live session, a DPoP proof that did not verify, or a certificate session whose certificate the key server now refuses.

SESSION_NOT_FOUND -- the credential names no session this Gateway holds. SESSION_EXPIRED -- it aged out. Both carry reauth: true; obtain a new credential rather than retrying.

PROOF_* -- the sender constraint refused. See the DPoP section of this document for the full table; PROOF_MALFORMED is a 400 and PROOF_REPLAY_CACHE_FULL a 503, and the rest are here.

SCOPED_CREDENTIAL_EXPIRED -- a scoped browser credential passed its fixed lifetime. Use does not extend it: an idle timeout would be refreshed by exactly the traffic a stolen handle produces.

CERTIFICATE_REVOKED -- on a session established by certificate login, the key server re-checks the certificate that session was established with on its operations, and it is now named by revocation evidence. detail is the key server's sentence. The Gateway answers this once and then ENDS everything that service holds or minted here -- its sessions, the delegated sessions and the scoped credentials it minted -- so a later operation on any of them is SESSION_NOT_FOUND. Log in with a different certificate.

SSO_SESSION_EXPIRED -- a single-sign-on session (POST /api/v1/session/oidc) reached its lifetime, or was idle past its binding's idle bound; it has been ended. Sign in again.

SENDER_KEY_RETIRED -- the session's registered sender key was rotated out and its overlap has passed (see "The registered service's credential lifecycle"); the session is closed with this answer. SERVICE_REGISTRATION_ENDED -- the registration a service credential was issued under was removed or narrowed on this Gateway; it has ended. Both are final for that credential.

403​

NOT_A_SERVICE_SESSION -- the caller's session is not a certificate login. SERVICE_NOT_REGISTERED -- it is, and no registration matches its principal. SERVICE_OPERATION_NOT_PERMITTED -- it is registered and this operation is not on its permitted list. DELEGATOR_NOT_PERMITTED -- the key server refused this Gateway's own certificate principal as a delegator: either no client certificate was bound for the connection, or the enrolled principal does not carry the DELEGATION flag (0x400). DELEGATOR_TOO_NARROW -- the TARGET holds at least one operation the DELEGATOR does not. The guard is a superset test with no administrator carve-out, so the fix is to widen the delegator, never to narrow the check. TARGET_DISABLED -- the key server refused the delegation because a principal in it is disabled: the target, or this Gateway's own certificate principal (the key server names neither; target and delegator are echoed). An administrator enables it; retrying changes nothing.

404​

TARGET_NOT_FOUND -- no XAuth principal with that id exists, so there is nobody to become. This is the lazy-provisioning signal: create the target with POST /api/v1/principals/xauth, which is idempotent, and retry.

500​

A fault rather than a refusal.

OP_FAILED is the catch-all: the key server refused in words that match no classified pattern, so the Gateway cannot say more than that the operation did not happen. Some key server refusals that are conceptually a caller error arrive here rather than as a 4xx, because the wire carries no distinguishing code -- where a route can recognise one from its message it maps it, and each such mapping is documented on the operation.

503​

MAJORDOMO_NOT_CONFIGURED or DELEGATION_NOT_CONFIGURED -- this Gateway holds no delegator identity, so it cannot impersonate anybody; nothing was sent to the key server. SERVICE_REGISTRY_NOT_CONFIGURED -- no service registry is loaded. SENDER_BINDING_UNAVAILABLE -- the Gateway is holding its maximum of sender-key bindings and could not record another; the session was not handed out, because a delegated credential this Gateway cannot bind would be spendable by anyone holding it. Retryable. Or CAPACITY_UNAVAILABLE (scope: process, Retry-After) -- this Gateway is at its request ceiling (see "Rate and capacity limits").

413​

PAYLOAD_TOO_LARGE (retryable: false) -- the request body is larger than this deployment accepts. It was refused before it was parsed, and the connection is closed. Nothing was sent to the key server.

429​

RATE_LIMITED (retryable: true, Retry-After) -- the allowance this request is charged to is spent: the login allowance of its network source (before authentication), or the allowance, the concurrency ceiling or the live-session ceiling of the identity it was verified as -- shared by every session that identity holds, including every delegated and scoped credential a service minted. It carries no scope. Nothing was sent to the key server; on a login refused after authentication, the session it created has been closed. See "Rate and capacity limits" above.

Error handling​

Every failure answers JSON carrying at least code and detail. Match on code — detail is written for a human debugging the call and its wording is not part of the contract. See the error model.

StatusMeaning
400CALLER_SUPPLIED_IDENTITY -- the body named an identity field the caller may not set, or carried subjectToken, which only POST /api/v1/session/scoped takes. Or BAD_REQUEST -- localUser is missing or malformed, or the id the Gateway built from its own configured prefix is not a usable one, which is a fault in this Gateway's configuration rather than in your request.
401No live session, a DPoP proof that did not verify, or a certificate session whose certificate the key server now refuses. SESSION_NOT_FOUND -- the credential names no session this Gateway holds. SESSION_EXPIRED -- it aged out. Both carry reauth: true; obtain a new credential rather than retrying. PROOF_* -- the sender constraint refused. See the DPoP section of this document for the full table; PROOF_MALFORMED is a 400 and PROOF_REPLAY_CACHE_FULL a 503, and the rest are here. SCOPED_CREDENTIAL_EXPIRED -- a scoped browser credential passed its fixed lifetime. Use does not extend it: an idle timeout would be refreshed by exactly the traffic a stolen handle produces. CERTIFICATE_REVOKED -- on a session established by certificate login, the key server re-checks the certificate that session was established with on its operations, and it is now named by revocation evidence. detail is the key server's sentence. The Gateway answers this once and then ENDS everything that service holds or minted here -- its sessions, the delegated sessions and the scoped credentials it minted -- so a later operation on any of them is SESSION_NOT_FOUND. Log in with a different certificate. SSO_SESSION_EXPIRED -- a single-sign-on session (POST /api/v1/session/oidc) reached its lifetime, or was idle past its binding's idle bound; it has been ended. Sign in again. SENDER_KEY_RETIRED -- the session's registered sender key was rotated out and its overlap has passed (see "The registered service's credential lifecycle"); the session is closed with this answer. SERVICE_REGISTRATION_ENDED -- the registration a service credential was issued under was removed or narrowed on this Gateway; it has ended. Both are final for that credential.
403NOT_A_SERVICE_SESSION -- the caller's session is not a certificate login. SERVICE_NOT_REGISTERED -- it is, and no registration matches its principal. SERVICE_OPERATION_NOT_PERMITTED -- it is registered and this operation is not on its permitted list. DELEGATOR_NOT_PERMITTED -- the key server refused this Gateway's own certificate principal as a delegator: either no client certificate was bound for the connection, or the enrolled principal does not carry the DELEGATION flag (0x400). DELEGATOR_TOO_NARROW -- the TARGET holds at least one operation the DELEGATOR does not. The guard is a superset test with no administrator carve-out, so the fix is to widen the delegator, never to narrow the check. TARGET_DISABLED -- the key server refused the delegation because a principal in it is disabled: the target, or this Gateway's own certificate principal (the key server names neither; target and delegator are echoed). An administrator enables it; retrying changes nothing.
404TARGET_NOT_FOUND -- no XAuth principal with that id exists, so there is nobody to become. This is the lazy-provisioning signal: create the target with POST /api/v1/principals/xauth, which is idempotent, and retry.
500A fault rather than a refusal. OP_FAILED is the catch-all: the key server refused in words that match no classified pattern, so the Gateway cannot say more than that the operation did not happen. Some key server refusals that are conceptually a caller error arrive here rather than as a 4xx, because the wire carries no distinguishing code -- where a route can recognise one from its message it maps it, and each such mapping is documented on the operation.
503MAJORDOMO_NOT_CONFIGURED or DELEGATION_NOT_CONFIGURED -- this Gateway holds no delegator identity, so it cannot impersonate anybody; nothing was sent to the key server. SERVICE_REGISTRY_NOT_CONFIGURED -- no service registry is loaded. SENDER_BINDING_UNAVAILABLE -- the Gateway is holding its maximum of sender-key bindings and could not record another; the session was not handed out, because a delegated credential this Gateway cannot bind would be spendable by anyone holding it. Retryable. Or CAPACITY_UNAVAILABLE (scope: process, Retry-After) -- this Gateway is at its request ceiling (see "Rate and capacity limits").
413PAYLOAD_TOO_LARGE (retryable: false) -- the request body is larger than this deployment accepts. It was refused before it was parsed, and the connection is closed. Nothing was sent to the key server.
429RATE_LIMITED (retryable: true, Retry-After) -- the allowance this request is charged to is spent: the login allowance of its network source (before authentication), or the allowance, the concurrency ceiling or the live-session ceiling of the identity it was verified as -- shared by every session that identity holds, including every delegated and scoped credential a service minted. It carries no scope. Nothing was sent to the key server; on a login refused after authentication, the session it created has been closed. See "Rate and capacity limits" above.