5.0 KiB
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
- Load protected-system manifests and resource manifests into the flex-auth registry.
- Load subject manifests or configure directory resolvers.
- Import resources and relationships into the delegated backend.
- Import policy artifacts or backend-native policy mirrors.
- Run adapter health checks.
- 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.