feat: report bounded verified access dependency readiness
Some checks failed
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / pytest-smoke (push) Failing after 3s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0e747-8f27-7242-8df8-8bc44f88c929
This commit is contained in:
tegwick 2026-09-28 14:32:36 +02:00
parent 7f0dc78607
commit c0383c9c2b
9 changed files with 294 additions and 17 deletions

56
docs/access-readiness.md Normal file
View file

@ -0,0 +1,56 @@
# Access dependency readiness
HUB-WP-0012 source candidate, 2026-09-28.
Protected `GET /readyz` now reports `access_identity`, `access_facts`,
`access_policy` and `access_audit`, plus their aggregate `access_profile`.
Controller configuration alone cannot mark these dependencies ready.
Each observation records the completion of a real verified dependency operation:
- Identity: the configured verifier returns a verified actor.
- Facts: the authoritative result matches that actor, includes evidence and is
fresh. Revoked or inactive state is a valid owner response, not an outage.
- Policy: the configured evaluator returns a verified decision. A signed denial
demonstrates usable policy evaluation while still denying the operation.
- Audit: the configured sink acknowledges authorization or refusal custody.
Committed-outcome delivery has its separate durable backlog readiness check.
Before an observation exists, its status is `unavailable`. Dependency errors or
cancellation mark it unavailable immediately. Successful observations expire to
`stale` after ten seconds using a monotonic clock. Invalid user-token refusals
neither poison a previously healthy identity sample nor refresh its age. Invalid
facts and malformed policy adapter results do not count as success. A fact that
expires while policy/audit run also becomes unavailable. The aggregate is `ok`
only when all four samples are fresh successes.
These process-local observations are diagnostics, never cached authorization.
Every request continues through token verification, current facts, signed policy
and durable audit. The controller itself now enforces a ten-second deadline,
including for direct SDK callers; HTTP/browser deadlines remain in place. No
credentials, owner URLs, token contents or raw exceptions appear in readiness.
`/readyz` remains protected: its own authorization refreshes the observations
before the handler reads them. If that authorization fails, the boundary returns
its normal 401/403/503 response instead of exposing dependency details to an
unauthorized caller. `AccessController.readiness_checks()` provides the same
read-only snapshot to an admitted host composition without making network calls.
Only minimal `/healthz` remains publicly available in the default composition.
This is **recent usability**, not an independent promise of owner reachability.
OIDC verification may use the admitted bounded JWKS cache; it does not prove that
the issuer is reachable at that instant. Flex-auth's reviewed `/healthz` reports
liveness only, and the facts adapter has no admitted independent health contract.
Hub therefore does not invent health endpoints, send synthetic root requests or
interpret liveness as an authorization grant. Independent owner probes, monitoring
admission and live outage/recovery receipts remain integration work.
Local tests cover cold/stale state, named failures and recovery, invalid-token
isolation, policy denial, bad facts/adapter results, cancellation/deadline behavior,
protected readiness and unchanged liveness. Conformance checks include access and
outcome-delivery dependencies when present, so correctly degraded readiness is
recognized rather than mistaken for a healthy dependency set.
Validation on 2026-09-28: 372 ordinary tests, five disposable PostgreSQL tests and
six owner-source Audit Core tests passed. Inventory, build and installed-wheel
checks passed. These are local receipts, not deployed owner acceptance.