Skip to content

[docs] Publish the claim-level provider↔verifier claims contract — today it exists only as scattered comments and CHANGELOG asides #13

Description

@y1o1

Parent: #11 (finding 4). Verified against auth 4ea0484, auth.policy-verifier 73cebc6, auth.provider f49658a3.

Problem

The provider↔verifier contract is written down only at signature mechanics (alg/JWKS symmetry). The claim-level half — "claim X, written by the provider at P, is consumed by the verifier as Y" — exists only scattered: the verifier maps its side well (e.g., ResourceActionScopeRuleCollector's capability-ceiling comment), the provider's side lives in two CHANGELOG asides (CHANGELOG.md:463-469 iss pinning, :471-475 allowedScopes ceiling), and no durable document holds the correlation. The umbrella is the stack-level doc home (README.md:3), so the contract belongs here.

Plan

1. New docs/claims-contract.md (architecture.md is a short component overview whose sections all have .ja.md twins; a ~10-row table with per-claim prose would dwarf it). Link from architecture.md's Auth Flow section and from README. One row per claim that crosses (or pointedly does not cross) the boundary — all rows below are code-verified; anchor rows to stable names (collector class, config key), keep file:line as secondary hints:

Claim Provider writes Verifier reads Semantics
scope oauth/src/grants/authorization.mts:454,508 — space-joined string or omitted; ceiling = client allowedScopes PayloadScopeCollector → ATTR_SCOPES; ResourceActionScopeRuleCollector:94 demands {action}:{resourceType} capability ceiling, not a grant
sub authorization.mts:338-400 (user id, never session id); core token.mts:125 PayloadSubjectIdCollector → ATTR_USER_ID; verify.mts:525 echoes as subject identity travels intact
azp authorization.mts:506-507 (authenticated client, not raw body) PayloadSubjectIdCollector → ATTR_CLIENT_ID requesting client
aud RFC 8707 resource → audience, authorization.mts:408-449; dropped on refresh without resource jose pin tokenAuthenticator.mts:120,477; oauth.jwt.audience token addressed to this resource server
iss token.mts:123; required, never request-derived (CHANGELOG:463-469) jose pin tokenAuthenticator.mts:118,476; oauth.jwt.issuer deployment identity pin
typ (header) at+jwt :509 / rt+jwt :524 / id+jwt idToken.mts:59 oauth.jwt.tokenType default at+jwt the ONLY discriminator between token kinds
exp/iat token.mts:120-122 both required, tokenAuthenticator.mts:69-72; maxTokenAgeSeconds caps issuer's exp lifetime
jti token.mts:121; provider-side replay detection not read by the verifier one-sided claim — stated so
groups only via scope-gated claim filter into userinfo/id_token (claimFilter.mts:37), NOT the access token only from request context (RequestContextAttributeCollector) does NOT cross the AT boundary today — recorded to prevent assumed coupling

Each row also cites the existing in-repo mapping comment it consolidates (token-flow/abac assertions, verifier schema comments) so the doc is an index over the house's scattered mappings, not a new parallel truth.

2. Pointer edits so both sides can find it (separate PRs in each sibling; umbrella doc must merge first or the links 404):

  • auth.provider docs/design-vocabulary.md:53-56 ("Cross-repo contracts" bullet — currently delegates to the workspace-local Dependency_map.xml, which is not on GitHub): append the link to this doc.
  • auth.policy-verifier README.md "Connecting to auth.provider" (:370): one lead-in line linking this doc for claim-level semantics.

Notes / risks

  • docs/ convention keeps .ja.md twins — plan claims-contract.ja.md or the convention breaks.
  • file:line refs rot as siblings move; stable-name anchoring above is the mitigation.
  • The E2E already pins several rows executable (typ triple at token-flow:87-94, scope string-not-array at :78-85); the doc should cite those tests as its enforcement arm rather than inventing new ones.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions