ADORSYS-GIS / ADORSYS-GIS/lightbridge-authz

[Story]: Migrate the local stack's trust root to authz-idp, as prod already is

Offen
#614 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
user-story
Vorherrschende Sprache
Rust
Sterne
0
Forks
1
Ø Merge
6 Std. 42 Min.
Gemergte PRs (30 T.)
246

Beschreibung

### Story Statement

As the owner of the authz platform, I want the local compose stack to validate bearer tokens against `authz-idp` exactly as production does, so that "works locally" means the same trust topology as "works in prod" and nobody generalises the local shortcut into a platform claim again.

### Real Intent

The platform rule, stated by the repo owner on 2026-08-31: **every authz resource server validates against `authz-idp`'s JWKS; `authz-idp` alone brokers the Keycloak login leg.**

Production already complies — `ai-helm-values` `environments/prod/values/lightbridge-app.yaml` points the `api`, `mcp` and `budget` components at `https://auth.ai.camer.digital/.well-known/jwks.json`, and only the `idp` component validates Keycloak's JWKS.

The local compose stack does **not**: `.docker/authz/container.yaml` and `config/default.yaml` still set `oauth2.jwks_url` straight at the Keycloak realm. It was never migrated when ADR-0023 made `authz-idp` a full IdP, and it survives only because every integration suite mints raw Keycloak tokens and hands them to `authz-api` directly.

This is not cosmetic. The drift already caused a concrete defect: during #534/#604 the local topology was mistaken for the platform's, and "authz-api trusts only Keycloak, so machine tokens can never reach it" was written into ADR-0030, `docs/rbac.md` and `docs/auth-reference.md` as a *platform* limitation. It was caught only because the owner challenged the claim in review. #604 corrected the wording and added `⚠️ LOCAL-STACK DIVERGENCE` warnings at both `jwks_url` sites, but the divergence itself remains — so the trap is still armed for the next reader.

### Background and Context

The reason this was deferred rather than folded into #604: converting the trust root means converting how every IT suite obtains a token. Suites that currently POST to Keycloak's token endpoint and use the result as a bearer must instead obtain an `authz-idp`-issued token (device flow, RFC 8693 exchange, or `authorization_code` — whichever fits each suite's persona). That is broad, mechanical, and deserves its own change rather than riding along inside a feature PR.

### Source of truth (links)

- Owner's rule, stated on the #581 working thread, 2026-08-31 ("All authz services MUST validate against authz-idp")
- lightbridge-authz#604 (added the divergence warnings; its ADR-0030 Decision 6 records the local-only caveat)
- ADR-0023 (made the authz-idp surface mandatory and unconditional — the cutover this config never followed)
- `docs/local-testing.md` §trust-root (documents the current local divergence)

### Acceptance Criteria

- [ ] `oauth2.jwks_url` in `.docker/authz/container.yaml` and `config/default.yaml` points at `authz-idp`'s own JWKS for every resource-server component (api, mcp, budget, usage); only the `idp` component's Keycloak-facing configuration keeps a Keycloak URL.
- [ ] Every integration suite that currently mints a raw Keycloak token for a resource server obtains an `authz-idp`-issued token instead — `.docker/it/servers_it.py`, `authorino_it.py`, `idp_it.py`, and the Rust `it-tests` fixtures that build bearers. **`just it-servers`, `just it-authorino`, `just it-idp` and `just it-tests` all pass**, with evidence pasted.
- [ ] No suite is skipped, ignored, or narrowed to make this pass — a suite that cannot obtain an idp token is a finding to report, not a test to disable.
- [ ] The `⚠️ LOCAL-STACK DIVERGENCE` comment blocks at both `jwks_url` sites are **removed** (they exist only to describe the drift), and `docs/local-testing.md`'s trust-root section is rewritten to state one trust root everywhere.
- [ ] ADR-0030's Decision 6 / Negative-consequences local-only caveats are amended (in-file amendment idiom, original text intact) to record that the divergence is closed — and with it, the machine-token RPC leg becomes live-testable locally, so the `client_credentials` IT gains the RPC-403 assertion that was previously impossible.

### Out of Scope

- Changing prod (already compliant).
- Enforcing `aud` — separate story.
- Removing Keycloak from the local stack; it remains the upstream IdP that `authz-idp` brokers.

### Dependencies and Blockers

None external. Expect broad IT churn — this is the whole cost of the story.

### Assumptions

1. Every persona the IT suites need can obtain an `authz-idp` token by a supported grant. **Verify per suite before converting** — a persona with no viable grant is a design finding that should come back to the maintainer, not be worked around with a long-lived fixture token.
2. `authz-idp`'s JWKS is reachable from every other service on the compose network at stack-up time (startup ordering may need a `depends_on`/healthcheck, the same way `it-machine-keygen` was sequenced in #604).

### Implementation Notes

Convert one suite first (`idp_it.py` is closest to the idp already) to establish the token-acquisition helper, then reuse it. `.docker/it/` already has dependency-free helpers (`jwt_min.py`, `cbor_min.py`) — follow that posture rather than adding pip installs.

### Test Expectations

The existing suites *are* the test: they must pass unmodified in intent (assertions unchanged; only token acquisition changes). Add one assertion that a raw Keycloak token is now **refused** by `authz-api` locally — that is the property proving the migration actually happened, and it should be written to fail first (it passes trivially today).

### Verification evidence

To be supplied by the implementing PR: full output of the four `just` IT targets, plus the new refusal assertion's fail-first evidence.

### Human accountable owner

Stephane Segning Lambou

### AI Usage Declaration

AI-assisted (Claude): drafted during the 2026-08-31 working session, from a divergence discovered when the owner challenged a false platform-wide claim in #604's docs. Verified against prod values and the local config files before filing; no code written. Human review and prioritisation pending.

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.