OASP
Spec Schemas GitHub
Home / Identity & Audit
// identity & audit

Who did what, as whom, when.

OASP treats identity and audit as part of the protocol, not a layer bolted on top. Scopes at every level, an IdP-agnostic Principal contract, on-behalf-of with scope-pinned containment — and an audit trail that is a conformance requirement.

normative

Every conformant Server MUST emit AuditEvents. Audit is not optional.

// scopes

Five scope dimensions. N at every level.

A Principal is placed by five independent dimensions — and can hold many values in each. Access composes across them; nothing is a single flat tenant id.

The model is a shape, not a schema for your IdP — you map your existing groups, roles, and tenancy onto it.

Principal scope each dimension: 0..N values
tenant 0..N acme
workspace 0..N field-ops
user 0..N alc
group 0..N dispatch supervisors
role 0..N operator
// claims contract

IdP-agnostic. OIDC-mappable.

The Principal claims contract says what a Principal must assert — not where it came from. A subject, its scopes, and a claims bag you populate from your identity provider.

OIDC is the common case and maps cleanly, but nothing in OASP is bound to it. Bring SAML, an internal directory, or a machine-identity system — the contract is the same.

Principal {
id: "prn_9x4",
kind: "user",
identity: { // OIDC-mappable, IdP-agnostic
subject: "user:alc", // → OIDC "sub"
issuer: "https://idp.acme.example", // → OIDC "iss"
displayName: "A. Crane",
},
scopeMemberships: [ // array of { level, id } — not a levels object
{ level: "tenant", id: "acme" },
{ level: "workspace", id: "field-ops" },
{ level: "group", id: "dispatch" },
{ level: "role", id: "operator" }
],
roles: ["operator"] // independent of scope membership
}

Field-accurate to principal.ts

// on-behalf-of

Agents act for people — inside a boundary.

When an agent acts on a user’s behalf, it carries a Credential pinned to a scope it cannot exceed. Delegation is explicit, bounded, and auditable.

containment — scope-pinned
tenant = acme · workspace = field-ops
Principal
prn_9x4
user:alc
on-behalf-of
Principal · agent
prn_agent_31
acts for alc
workspace = finance out of bounds — outside the pinned scope

Conceptual illustration of the containment rule — a spec MUST. No negative-authorization conformance test exists yet, so this is not a captured enforcement result.

Credential {
id: "cred_7fk2",
provider: "anthropic",
vaultId: "vault_ref_88c1", // never the secret itself
mcpServerUrl: "https://mcp.acme.example/field-ops",
scope: { level: "workspace", id: "field-ops" }, // the containment pin
onBehalfOf: { kind: "user", id: "prn_9x4" }
}

Field-accurate to credential.ts

// audit as conformance

The audit trail is part of the protocol.

In most systems, audit is a feature someone remembers to add. In OASP it is a conformance requirement: a conformant Server MUST emit an AuditEvent for every consequential action.

The result: “what did the agent do, as whom, when” is answerable by any implementation that passes the kit — a property a regulated-sector evaluator can rely on before choosing a vendor.

who.principal who.onBehalfOf what scope refs when
AuditEvent { // docs/spec/audit.md — normative shape
id: "aud_04b9",
who: {
principal: { kind: "agent", id: "prn_agent_31" },
onBehalfOf: { kind: "user", id: "prn_9x4" }
},
what: "migrate",
scope: { level: "workspace", id: "field-ops" },
when: "2026-07-09T17:04:12.882+12:00",
outcome: "success",
refs: { conversationId: "conv_7Q2f", sessionId: "sess_b" }
}

Field-accurate to audit-event.ts