Skip to content

Authentication

Every /osl/* call carries a JWT Bearer token. The engine authorizes against the token’s scopes and roles, and the policy enforcement point applies the caller’s ACL server-side.

Authorization: Bearer <jwt>

The JWT carries:

Claim Meaning
chain[] The delegation chain, root → leaf (the acting subject is the last link)
sub Optional; if present, must equal chain[-1]
roles[] Assigned roles
tenant The tenant’s cell
scopes[] osl:read, osl:write, osl:execute, osl:admin
exp Expiry (required)

Access is evaluated over a chain of subjects (root → leaf), not a single identity — see Access & capabilities. The chain is inside the signed payload (HS256), so a caller cannot shorten or forge it without breaking the signature:

{
"iss": "opendome",
"chain": ["ana@company.com", "agent://copilot-finance"],
"roles": ["analyst"],
"iat": 1750000000,
"exp": 1750000300
}
Edition Issuer
OSS standalone Apache-2.0 The cell mints HS256 tokens locally. The tenant-semantic-api chart generates a signing Secret; use scripts/osl-token.sh <tenant> --roles <r> to mint one. The standalone engine does not trust the X-Actor-Roles header — a public Ingress caller cannot spoof roles.
Enterprise / managed Enterprise The control-plane issues and rotates JWTs. You may also front the engine with your own IdP-aware proxy that sets X-Actor-Roles and flip auth.trustActorRolesHeader=true (BYO-OIDC).

Defaults, per subject:

Endpoint Limit
POST /osl/query 60 rps
POST /osl/sample 30 rps
GET /osl/schema 5 rps (cached)

Exceeded → 429 Too Many Requests with Retry-After. Limits are configured per tenant in the managed tier.

Every request — 200 or not — produces an immutable, hash-chained audit entry with request_id, subject, action, the object FQNs touched, the decision and a timestamp.