# Topaz Adapter Operations Status: implemented for FLEX-WP-0004 P4.1. ## Role The Topaz adapter is a delegated PDP and directory adapter behind the stable flex-auth API. Protected systems still send `CheckRequest`, `BatchCheckRequest`, registry snapshots, and Rego-in-Markdown policy packages to flex-auth. The adapter translates those into Topaz directory objects, relations, permission checks, and an OPA bundle, then wraps the result back into the same `DecisionEnvelope` used by standalone mode. ## Wire Protocol The production recommendation remains gRPC because it is Topaz's native API and gives the strongest typed client surface for authorizer, reader, writer, and model operations. The implementation added in P4.1 keeps that choice behind `internal/adapters/topaz.Client` and ships an HTTP REST client for the runnable `examples/topaz` topology. This split is deliberate: - `Client` is the stable flex-auth boundary. - `HTTPClient` speaks the same REST endpoints used by the spike (`/api/v3/directory/check`, `/object`, `/relation`, `/manifest`). - A future gRPC client can replace `HTTPClient` without changing protected-system contracts or CARING envelope behavior. - Embedded Topaz remains out of scope because it would couple flex-auth releases to Topaz internals. ## Startup 1. Start Topaz with the manifest and bundle paths mounted. The `examples/topaz/docker-compose.yml` file is the local reference. 2. Create a `topaz.HTTPClient` with the directory REST gateway URL. 3. Configure a `topaz.FileBundleSink` that points at the mounted bundle directory. 4. Build a `topaz.Adapter` with the client and policy metadata. 5. Call `ImportManifest`, `ImportDirectory`, and `ImportPolicy` before accepting delegated checks. For local verification: ```sh cd examples/topaz docker compose up --abort-on-container-exit --exit-code-from probe ``` The Go integration test is present but skipped by default. Run it with: ```sh FLEX_AUTH_RUN_TOPAZ_INTEGRATION=1 go test ./internal/adapters/topaz ``` ## Directory Consistency `ImportDirectory` converts the canonical registry snapshot into Topaz objects and relations. Subjects and service accounts become Topaz `user` objects. Each subject also receives an `identity:` object with an `identifier` relation to the user. Groups and teams become Topaz `group` objects; teams keep the `team:` prefix. Resources keep their canonical type names, labels, trust zone, path, owner, and system in properties. Relation writes return an optional etag. The adapter records the latest etag in `DecisionEnvelope.provenance.directory_etag` when Topaz returns one. Reads may be served from flex-auth's local registry for explanation or from Topaz for authorization. The decision envelope must say which backend produced the answer through `provenance.evaluator` and `provenance.mode`. ## Policy Import `ImportPolicy` extracts the validated Rego module from a Rego-in-Markdown package without translation. `FileBundleSink` writes: - `.manifest` with the package root. - `policy/.rego` with the exact extracted module. This matches the local-bundle mode used by the Topaz example. Clustered Topaz deployments can replace the bundle sink with a remote bundle publisher without changing the adapter contract. ## Fail-Closed Defaults Delegated checks do not leak backend errors to protected systems as ambiguous success. The adapter returns a deny envelope for: - Topaz unavailable: `reason=topaz_unavailable`. - Stale directory: `reason=topaz_directory_stale`. - Partial result: `reason=topaz_partial_result`. - Untranslatable request: `reason=topaz_request_incomplete`. Each failure includes a CARING conformance finding and `diagnostics.topaz_failure`. This keeps delegated mode behavior compatible with standalone fail-closed decisions and makes backend health visible to audits. ## CARING Preservation The adapter preserves CARING descriptors from the request or backend result. It copies descriptor, restrictions, exposure modes, derived capabilities, conformance findings, and exposure-event hooks into the decision envelope. If no descriptor is available, the decision still contains a `TOPAZ-CARING-DESCRIPTOR-MISSING` warning so conformance checks can distinguish an authorization deny from a metadata gap.