generated from coulomb/repo-seed
Add relationship PDP adapter boundary
This commit is contained in:
105
docs/relationship-pdp-adapter-boundary.md
Normal file
105
docs/relationship-pdp-adapter-boundary.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user