Skip to main content

Policy Contracts: SARAC and Payload Shapes

Blueprint · ← Foundation overview · Policy contracts · Token & session →

The PEP does not send natural language to the PDP. It maps session claims and tool proposals into a fixed four-field contract so every verdict is replayable.

THE CLAIM

SARAC (subject · action · resource · context) is the only shape the PDP evaluates. If your PEP sends prose, you do not have PGAR.

The four fields​

FieldSourceCarries
subjectIdP claims in agentic app sessionidentity, roles, emts, limits
actionTool proposal nameissue_refund, lookup_beneficiary, retrieve_documents
resourceProposal targetbeneficiary id, corpus, account
contextRuntime state + proposal argsamount, sanctions_status, approval

Example: wire initiation​

Wire initiation SARAC (JSON)
{
"subject": {
"sub": "officer-123",
"roles": ["corporate_banking_officer", "payments_initiator"],
"emts": {
"payments.wire.initiate": true
},
"limits": {
"wire.auto_approved": 25000
}
},
"action": "initiate_wire",
"resource": {
"type": "wire_payment",
"beneficiary_id": "bene-acme-441",
"source_account": "acct-operating-4412"
},
"context": {
"amount": 47500,
"sanctions_status": "clear",
"approval": null
}
}

After step-up, the same request returns with context.approval set and the PDP re-evaluates.

Example: RAG retrieval​

RAG retrieval SARAC (JSON)
{
"subject": {
"sub": "officer-123",
"doc_entitlements": ["policy-engine:read"]
},
"action": "retrieve_documents",
"resource": {
"type": "corpus",
"id": "policy-engine"
},
"context": {
"query": "wire limits EU corporate",
"classification_ceiling": "internal"
}
}

See RAG retrieval.

Worked example: refund agent​

Same uc-refund-agent as Operating. Three SARAC shapes, three verdicts. Subject always comes from the token, never from "refund this for Priya" in the user text.

issue_refund $80 → expected ALLOW (JSON)
{
"subject": {
"sub": "staff-priya-shah",
"roles": ["payments_ops"],
"emts": { "payments.refund.issue": true }
},
"action": "issue_refund",
"resource": {
"type": "customer_account",
"account_id": "acct-4412",
"use_case_id": "uc-refund-agent"
},
"context": {
"amount_aud": 80,
"purpose": "duplicate_charge",
"approval": null
}
}
issue_refund $750 → expected STEP_UP (JSON)
{
"subject": {
"sub": "staff-priya-shah",
"roles": ["payments_ops"],
"emts": { "payments.refund.issue": true }
},
"action": "issue_refund",
"resource": {
"type": "customer_account",
"account_id": "acct-4412",
"use_case_id": "uc-refund-agent"
},
"context": {
"amount_aud": 750,
"purpose": "duplicate_charge",
"approval": null
}
}
issue_refund $80 purpose mismatch → expected DENY (JSON)
{
"subject": {
"sub": "staff-priya-shah",
"roles": ["payments_ops"],
"emts": { "payments.refund.issue": true }
},
"action": "issue_refund",
"resource": {
"type": "customer_account",
"account_id": "acct-4412",
"use_case_id": "uc-refund-agent"
},
"context": {
"amount_aud": 80,
"purpose": "goodwill_unmapped",
"approval": null
}
}

After four-eyes, the same $750 request returns with context.approval.attestation_id: att-2026-03-11-1842. PDP re-evaluates to ALLOW. The HR FAQ never sends issue_refund. Its action is retrieve_documents on corpus hr-handbook.

Mapping rules (PEP responsibility)​

  1. Never infer subject from model text. Subject comes from validated token claims only.
  2. Action = tool name from manifest, not paraphrased intent.
  3. Resource = normalized target (ids, not display names the model invented).
  4. Context = proposal args + prior tool results the PDP needs (sanctions, approval, amount).

Failure classes​

  • Schema drift: PEP sends fields PDP no longer accepts
  • Subject substitution: claims from wrong session attached
  • Resource ambiguity: model string passed through without resolution
  • Context leakage: PII in context field not redacted in audit

Automated checks​

SARAC automated checks (pseudo-code)
assert pdp_request.has_fields(["subject", "action", "resource", "context"])
assert subject.sub == session.claims.sub
assert action in tool_manifest.names
assert audit.redacted_context == redact(context)

Trace fields​

pep_request_id, subject.sub, action, resource.type, resource.id, context_hash, pdp_policy_version

See: PEP Enforcement · Governance Blueprint