Document delegated mode operations
Some checks failed
CI / Build and Test (push) Has been cancelled
CI / Lint (push) Has been cancelled

This commit is contained in:
2026-05-17 07:27:45 +02:00
parent 1f5e9626e5
commit 99a521e176
2 changed files with 135 additions and 2 deletions

View File

@@ -0,0 +1,133 @@
# Delegated Mode Operations
Status: implemented for FLEX-WP-0004 P4.6.
## Purpose
Delegated mode lets flex-auth coordinate external authorization systems
without changing the protected-system-facing API. Protected systems keep
using flex-auth check, batch, list, explanation, and audit contracts.
Topaz, relationship PDPs, rule PDPs, Keycloak Authorization Services,
and directory resolvers stay behind adapter boundaries.
## Deployment Order
1. Load protected-system manifests and resource manifests into the
flex-auth registry.
2. Load subject manifests or configure directory resolvers.
3. Import resources and relationships into the delegated backend.
4. Import policy artifacts or backend-native policy mirrors.
5. Run adapter health checks.
6. Start serving delegated checks only after the backend reports healthy
and the latest import has a recorded consistency token.
For Topaz, the local reference topology is `examples/topaz`. For
Keycloak, register resources from flex-auth manifests before enabling
UMA permission checks. For OpenFGA/SpiceDB-style systems, import tuples
from the canonical registry snapshot. For OPA/Cedar-style systems,
import policy artifacts from validated flex-auth policy packages.
## Health Checks
Each delegated adapter exposes a health boundary. Runtime health should
be tracked separately for:
- backend reachability
- policy import freshness
- directory or tuple import freshness
- resolver freshness
- last successful decision time
Health failures should not silently fall back to stale allow decisions.
They should produce observable diagnostics and deny fail-closed unless a
deployment has explicitly accepted a narrower fail-open mode for a
non-sensitive action.
## Fail-Closed Default
The default behavior is fail-closed:
| Condition | Decision effect | Typical reason |
| --- | --- | --- |
| backend unavailable | deny | `topaz_unavailable`, `relationship_backend_unavailable`, `rule_backend_unavailable`, `keycloak_unavailable` |
| stale directory or tuple data | deny | `topaz_directory_stale`, `relationship_data_stale` |
| stale policy | deny | `rule_policy_stale`, `keycloak_policy_stale` |
| partial backend result | deny | `*_partial_result` |
| request cannot be translated | deny | `*_request_incomplete` |
Fail-open is only acceptable for explicitly classified low-risk
capabilities and must be recorded as a policy decision, not an adapter
default. Data, identity, policy, secret, audit, and commercial planes
should remain fail-closed.
## Caching
Recommended cache layers:
- resource manifest snapshot cache
- subject/group resolver cache
- delegated backend import token cache
- decision-result cache for idempotent low-risk checks
Cache entries must record source, retrieval time, max age, and expiry.
Directory resolver results already expose `Freshness`; tuple and
Topaz/Keycloak imports expose consistency metadata through the decision
provenance fields. Cache hits should still include provenance so audit
readers can tell whether evidence came from a fresh backend call or a
bounded cache.
## Consistency
flex-auth uses `DecisionEnvelope.provenance.directory_etag` as the
adapter-neutral consistency token field:
- Topaz: relation etag when available
- OpenFGA/SpiceDB-style backends: model id, zedtoken, or tuple-store
freshness token
- directory resolvers: freshness metadata attached to subject metadata
- Keycloak/rule PDPs: policy version in `provenance.policy_version`
Adapters should deny or mark stale when a request demands a newer token
than the backend can satisfy. Read-your-writes paths should import
registry data, record the returned token, and require that token for the
first protected-system checks after import.
## Audit Behavior
Delegated decisions must log the same canonical envelope as standalone
decisions:
- subject and resource references
- effect, reason, matched rule, matched policy version
- obligations
- diagnostics
- evaluator and mode
- consistency token
- CARING descriptor, restrictions, exposure modes, derived
capabilities, exposure events, and conformance findings
Backend-native traces can appear in diagnostics, but they must not
replace the canonical fields. Explanations should be generated from the
flex-auth envelope so switching backends does not change protected-system
or auditor vocabulary.
## Adapter Notes
- Topaz operations: `docs/topaz-adapter-operations.md`
- Relationship PDPs: `docs/relationship-pdp-adapter-boundary.md`
- Rule PDPs: `docs/rule-pdp-adapter-boundary.md`
- Keycloak Authorization Services:
`docs/keycloak-authz-adapter-path.md`
- Directory resolvers: `docs/directory-group-resolver-adapters.md`
## Operational Checklist
- Backend configured and reachable.
- Policy/resource/tuple import completed.
- Latest import token recorded.
- Directory resolver freshness thresholds configured.
- Fail-closed behavior tested for unavailable, stale, partial, and
invalid-request cases.
- Decision log captures delegated provenance and CARING metadata.
- Rollback path can switch a protected system back to standalone mode or
to another delegated adapter without changing the protected-system API.

View File

@@ -3,7 +3,7 @@ id: FLEX-WP-0004
type: workplan type: workplan
title: "Delegated PDP and Directory Adapters" title: "Delegated PDP and Directory Adapters"
domain: netkingdom domain: netkingdom
status: active status: completed
owner: flex-auth owner: flex-auth
topic_slug: flex-auth topic_slug: flex-auth
planning_priority: P2 planning_priority: P2
@@ -150,7 +150,7 @@ descriptor provenance remains inspectable.
```task ```task
id: FLEX-WP-0004-T006 id: FLEX-WP-0004-T006
status: todo status: done
priority: medium priority: medium
state_hub_task_id: "491260f9-b4d7-46fe-8220-d358597db33a" state_hub_task_id: "491260f9-b4d7-46fe-8220-d358597db33a"
``` ```