Files
flex-auth/docs/topaz-adapter-operations.md
tegwick 1ce0181e8f
Some checks failed
CI / Build and Test (push) Has been cancelled
CI / Lint (push) Has been cancelled
Implement Topaz adapter
2026-05-17 06:58:04 +02:00

108 lines
4.2 KiB
Markdown

# 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:<subject>` 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/<package/path>.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.