Files
flex-auth/docs/relationship-pdp-adapter-boundary.md
tegwick 4bb329c921
Some checks failed
CI / Build and Test (push) Has been cancelled
CI / Lint (push) Has been cancelled
Add relationship PDP adapter boundary
2026-05-17 07:06:14 +02:00

106 lines
3.6 KiB
Markdown

# Relationship PDP Adapter Boundary
Status: implemented for FLEX-WP-0004 P4.2.
## Role
The relationship PDP adapter is the common boundary for OpenFGA,
SpiceDB, and other tuple-oriented authorization systems. These backends
answer questions like:
```text
is subject S related to object O through relation R?
```
flex-auth keeps the protected-system API stable. The adapter translates
`CheckRequest`, `BatchCheckRequest`, registry relationships, and
`list_allowed` queries into tuple checks, then wraps backend responses
back into the canonical `DecisionEnvelope`.
## Tuple Mapping
Canonical flex-auth relationship facts map to:
| flex-auth | tuple field |
| --- | --- |
| resource type | `object_type` |
| resource id | `object_id` |
| action or relation | `relation` |
| subject type | `subject_type` |
| subject id | `subject_id` |
| group membership indirection | `subject_relation=member` |
Registry group and team membership become `group#member` tuples.
Resource parent edges become `parent` tuples. Resource owners become
`owner_team` tuples. Relationship facts keep conditions, provenance,
metadata, and CARING descriptors on the imported tuple so backend
results can preserve explanatory context.
## Inheritance
Relationship backends represent inheritance differently:
- OpenFGA usually models it in the authorization model through rewrites.
- SpiceDB usually models it through relation definitions and caveats.
- flex-auth records inherited evidence in
`TupleCheckResult.InheritedFrom`.
The envelope does not expose backend-native rewrite syntax. It records
the fact that inheritance participated through diagnostics and preserves
the matched CARING descriptor from direct or inherited tuples.
## Batch And List
`BatchCheck` preserves request order. If the backend returns a partial
batch, flex-auth emits fail-closed deny envelopes for the affected
resources.
`ListAllowed` returns a `ListAllowedResult` containing allow envelopes,
the backend consistency token, and diagnostics. It intentionally returns
envelopes instead of raw resource ids so downstream consumers keep the
same audit and CARING metadata they receive from single checks.
## Consistency Metadata
Tuple backends expose different consistency tokens:
- OpenFGA: model id plus optional tuple-store continuation/freshness
metadata.
- SpiceDB: zedtoken.
The adapter stores the backend token in
`DecisionEnvelope.provenance.directory_etag`. The field name is kept for
compatibility with the existing flex-auth envelope; for relationship PDPs
it means "relationship backend consistency token".
## Failure Behavior
The adapter fails closed for:
- backend unavailable: `relationship_backend_unavailable`
- stale consistency token: `relationship_data_stale`
- partial backend result: `relationship_partial_result`
- untranslatable request: `relationship_request_incomplete`
Each failure is a deny envelope with `diagnostics.relationship_failure`
and a CARING conformance finding. This keeps delegated tuple behavior
aligned with standalone fail-closed behavior.
## CARING Preservation
Tuple systems do not understand CARING directly. flex-auth therefore
keeps CARING metadata at the adapter boundary:
- request descriptor wins when supplied;
- backend result descriptor is next;
- matched tuple descriptor is next;
- inherited tuple descriptor is next;
- otherwise the envelope includes
`RELATIONSHIP-CARING-DESCRIPTOR-MISSING`.
The adapter copies scope, planes, capabilities, exposure modes,
restrictions, derived capabilities, conformance findings, and
exposure-event hooks into the decision envelope. Backend-native role or
relation names should not leak into protected systems as a replacement
for CARING canonical roles.