# 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.