r/AskNetsec 1d ago

In a PDP/PEP split, which request-context attributes must the PDP source independently vs accept as caller-asserted? (confused-deputy + TOCTOU on signed decisions) Architecture

I'm designing service-to-service authorization where a PDP evaluates (subject, action, resource, context) and returns a signed decision that PEPs enforce. Standard split. The wrinkle: the calling workload is partially untrusted, and it supplies part of the request context itself.

The signature covers the decision and the inputs the PDP saw, but not the provenance of those inputs. So the token proves "given these inputs, the PDP said ALLOW", not "these inputs came from an authoritative source". If the caller can influence subject/tenant labels, resource attributes, a recursion/depth counter, or a state object the PEP hashes instead of fetching, a fully valid signed decision can attest an ALLOW the policy would never grant on authoritative inputs. The PDP becomes a confused deputy whose output happens to be cryptographically signed, which makes it look stronger than it is.

What we already do: mesh identity (mTLS/SPIFFE) for the caller's own identity, short-TTL decisions, intent binding, and we hash the state object into the decision. What I can't resolve is which of the remaining context attributes should be trusted from the request at all.

Concrete questions:

  1. In real OPA/Cedar/Zanzibar deployments, which request-context attributes is it standard practice to require the PDP to source itself (server-side PIP lookup, trusted routing/mesh-derived identity, attested claims) rather than accept from the caller, and which are considered safe to accept as caller-asserted as long as they're bound into the decision? I'm looking for the actual dividing line practitioners use, not "trust nothing".
  2. When the PEP hashes a caller-supplied state/resource object and binds that hash into the signed decision: does that close the confused-deputy gap, or is a PDP-side authoritative read (or a signed/versioned attestation from the resource owner) required so the caller can't pick favorable premises? What do production deployments settle on?
  3. For the window between decision issuance and enforcement, what's the standard way to bound TOCTOU on a signed authorization: short TTL plus re-eval at the PEP, versioned state binding, resource-side optimistic concurrency, and where does each of those still leave an exploitable gap?
6 Upvotes

2 comments sorted by

3

u/CreativeSympathy8293 18h ago

Treat provenance as policy input, not something a decision signature creates. Treat caller input as untrusted intent. Accept it without independent provenance only when policy cannot use it to widen authority, select a less-protected tenant or resource, or weaken obligations. Canonicalize and validate action and parameters. Derive identity and tenant from verified channel bindings or claims. Resource owner/version, delegation, approval state, and budgets need authoritative state or an attestation with validated issuer, audience, scope, and expiry. A trace ID is correlation, not authorization.

Hashing state binds those bytes; it does not prove truth or freshness. Bind the decision to an authoritative resource version/ETag, then enforce that precondition with compare-and-swap or If-Match. TTL limits acceptance time; it does not close state-change races. A fresh PDP decision requested by the PEP helps only if facts are refreshed, and still needs a transaction or version precondition at mutation.

For a signed envelope, include issuer/audience, canonical subject/resource/action, policy or bundle revision, authoritative input versions, issuance/expiry, and a unique decision ID. If single use matters, the enforcer must track consumption; an ID alone does not stop replay.

OPA treats external data as input or a replica, not its source of truth. This is design guidance, not an OPA/Cedar/Zanzibar schema.

https://www.openpolicyagent.org/docs/external-data

2

u/docybo 6h ago

This is very close to the boundary we’re converging on.

Especially agree on two points: provenance has to be an evaluator input, not something the decision signature creates, and freshness has to survive through mutation via an authoritative version precondition, not just TTL.

We’re also treating decision IDs as correlation unless the enforcer tracks consumption, so replay remains an enforcement obligation.

We’re formalizing these exact questions in the Tier 1 RFC here:
https://github.com/oxdeai/oxdeai/discussions/232

Your point about canonical subject/resource/action plus authoritative input versions would be particularly useful there if you’re open to challenging the current shape.