ADORSYS-GIS / ADORSYS-GIS/converse-frontends

[Ticket]: authz-idp initialises with roles_claim "roles", not lightbridge_api_roles

Aperta
#359 0 commenti 0 reazioni 1 assegnatario Rivendicata da @stephane-segning Vedi su GitHub
bug
Lingua principale
TypeScript
Stelle
0
Fork
0
Merge medio
1h 49m
PR unite (30g)
253

Descrizione

## Type

Bug (configuration drift) — cross-team, `ai-helm-values`

## Summary

`authz-idp` initialises with **`roles_claim: "roles"`** while every other authz component uses `lightbridge_api_roles`. The `idp:` release in `lightbridge-app.yaml` has no `oauth2.rbac` block at all, so it falls back to the built-in default.

Observed from the running pods:

| component | `roles_claim` |
| --- | --- |
| `lightbridge-api-main` | `lightbridge_api_roles` |
| `lightbridge-budget-main` | `lightbridge_api_roles` |
| **`lightbridge-idp-main`** | **`roles`** |

## Intent

The IdP block's own comment states the invariant this breaks:

> authz-api derives permissions from `oauth2.rbac.roles_claim` (`lightbridge_api_roles`, **set in every block below**) and default-denies without it

It is not set in every block. `grep -n "rbac:"` returns three hits — `api` (376), `mcp` (764), `budget` (1658) — and the file has six releases (`api`, `mcp`, `idp`, `opa`, `budget`, `usage`). The `idp` release, the one the comment is attached to, is the omission.

That matters more than an ordinary typo because the surrounding comments are unusually careful about exactly this hazard — the `claim_mappers` note immediately above explains that the block is "kept BYTE-IDENTICAL across api/mcp/idp/budget" precisely so these do not drift. This one drifted anyway, and the comment now asserts something the file contradicts.

## Source of truth (links)

- `ai-helm-values` `environments/prod/values/lightbridge-app.yaml` — `idp:` release at line 978; `rbac:` blocks at 376 / 764 / 1658; the quoted comment at ~1042.
- Running pod: `Initializing BearerTokenService with audience config: Some(["lightbridge-api-key", "lightbridge-console"]), roles_claim: "roles"`

## Current Behavior

`start_idp_server` constructs a `BearerTokenService` from the `idp` release's own config. With no `oauth2.rbac.roles_claim`, it takes the default `"roles"`, so any role the IdP reads off an inbound bearer comes from a claim nothing in this deployment mints. `claim_mappers` stamps `lightbridge_api_roles`.

## Impact — stated honestly

**Not currently breaking anything observable.** The console authenticates via `authorization_code`, and the roles it depends on are read by **authz-api**, which is configured correctly. Verified working end to end on 2026-08-29: RPC `200`, real data, admin gating intact.

The exposure is **latent**, on the IdP's own bearer-validating paths — principally RFC 8693 token exchange, where a `subject_token`'s roles would resolve to an empty set and default-deny. Nothing exercises that today from the console, which is precisely why it is worth fixing before something does: the failure mode is a silent, correct-looking default-deny, not an error.

## Expected Behavior

The `idp` release sets `oauth2.rbac.roles_claim: "lightbridge_api_roles"`, matching `api`/`mcp`/`budget` — or, if the IdP genuinely must not read roles, the comment is corrected to say so and the divergence is made deliberate rather than accidental.

## Acceptance Criteria

- [ ] `lightbridge-idp-main` logs `roles_claim: "lightbridge_api_roles"` on start, or the file documents why it should not.
- [ ] The "set in every block below" comment is true, or reworded.
- [ ] Whichever way it goes, `usage` (also missing an `rbac` block) is checked at the same time rather than left as the next instance of this.

## Out of Scope

- The refresh-token bug (`lightbridge-authz` `797b95a`) and the console's 401 loop (`converse-frontends#358`) — both already fixed; this was found while verifying those.

## Human accountable owner

@stephane-segning

## AI Usage Declaration

Found by reading the live pods' startup logs while verifying an unrelated fix; the divergence was confirmed across three components and traced to the specific missing block, not inferred from the log alone.

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.