ADORSYS-GIS / ADORSYS-GIS/lightbridge-authz
[Ticket]: The stack TLS job mints no shared CA — default installs can't satisfy the usage listener's mTLS
- Lingua principale
- Rust
- Stelle
- 0
- Fork
- 1
- Merge medio
- 6h 42m
- PR unite (30g)
- 246
Descrizione
### Type
Bug
### Summary
The umbrella chart's built-in TLS job mints independent self-signed leaf certs with **no shared CA and no `ca.crt`** in the secret it creates, and it creates only one secret while the `usage` and `mcp` subcharts are wired to mount differently-named ones. A default stack install therefore cannot satisfy the usage query listener's mTLS, which since #603 defaults to requiring `/etc/lightbridge/tls/ca.crt`.
### Intent
Make `helm install charts/lightbridge-authz-stack` with `global.tls.enabled=true` produce a stack that actually starts and can serve its own mutual-TLS surface — without an operator having to discover, by crash-loop, that the chart's own TLS mechanism cannot produce the material its own defaults demand.
### Source of truth (links)
- lightbridge-authz#593 (rendered the mandatory `server.query` listener; mTLS on by default)
- lightbridge-authz#603 (made `config.query.tls.clientCaBundlePath: /etc/lightbridge/tls/ca.crt` the chart default, so a CA is now required, not optional)
- `charts/lightbridge-authz-stack/templates/global-tls-job.yaml` (the job in question)
- `compose.yaml`'s `authz-tls` service — the working reference implementation of the shape wanted here
### Current Behavior
1. **No shared CA.** `global-tls-job.yaml` runs a series of independent `openssl req -x509` invocations, one self-signed leaf per service. Nothing signs anything else, and the secret it creates carries `tls.crt`/`tls.key` only — **no `ca.crt` key exists**. Any consumer configured to verify a peer against that bundle has nothing to point at.
2. **Secret-name mismatch.** The job creates a single secret (default `lightbridge-authz-tls`), while the stack's values override the `usage` and `mcp` subcharts to mount `lightbridge-authz-usage-tls` / `lightbridge-authz-mcp-tls` — names nothing creates. Those pods mount a secret that does not exist.
3. Consequence since #603: the usage chart now defaults `clientCaBundlePath` to a path inside that secret. An unreadable/absent CA bundle is a deliberate **hard startup failure** (fail-closed, correct direction) — so the default stack fails loudly rather than serving unauthenticated, but it does fail.
Prod is unaffected: it uses cert-manager, which emits `ca.crt` alongside `tls.crt`/`tls.key`, and overrides the secret names. This is a dev/test/default-install defect.
### Expected Behavior
The built-in TLS job mints one CA, signs every service leaf off it with both `serverAuth` and `clientAuth` EKUs, and publishes `ca.crt` alongside each leaf — i.e. the same shape `compose.yaml`'s `authz-tls` service already produces and which the compose stack's mTLS relies on. Secret naming is reconciled so every subchart mounts something that exists.
### Acceptance Criteria
- [ ] The TLS job creates a CA and signs each service leaf from it; the rendered secret(s) contain `ca.crt` in addition to `tls.crt`/`tls.key`.
- [ ] Leaf certs carry `extendedKeyUsage = serverAuth, clientAuth` (the usage query listener's client identity and the budget spend-reader's client cert both depend on this — see `docs/architecture` on the mTLS posture).
- [ ] The `usage` and `mcp` secret-name mismatch is resolved in one direction — either the job creates per-service secrets, or the subcharts mount the one it creates. Whichever is chosen is stated in a values comment so the next reader does not re-derive it.
- [ ] A default `helm install`/`helm template` of `charts/lightbridge-authz-stack` with `global.tls.enabled=true` renders a coherent set: every mounted secret is one the release actually creates.
- [ ] cert-manager path unaffected — the job remains disableable, and the docs' two documented TLS flows both still work (`docs/platform-guides.md`).
### Out of Scope
- Prod/cert-manager configuration (already correct).
- Rotation, renewal, or moving to cert-manager by default.
- The chart-version/image-pin drift noted in passing during review (`values.yaml` pins vs `Chart.yaml` version) — unrelated, pre-existing.
### Technical Context
`compose.yaml`'s `authz-tls` service is a working, readable implementation of exactly the wanted behaviour (mint CA → `issue_leaf` per service with the right EKUs → ship `ca.crt` beside the leaves); porting its logic into the job is the bulk of the change.
**Render-verification gotcha, learned the hard way during #593's review:** `helm template` on the umbrella fails with a spurious bjw-s `dig: interface conversion` error if you run `helm dependency update` on the umbrella without first building each subchart's own dependencies. Follow CI's order (`.github/actions/helm-oci-publish/action.yml`: `helm dependency build` per leaf chart, *then* the umbrella) or you will chase a chart bug that does not exist.
### Risks
- Changing the secret's contents/shape affects anything already mounting it; check the `authz`/`opa` subcharts before renaming keys.
- A CA-signing change alters every rendered cert, so any environment pinning a fingerprint would need a rollout — none known, but worth confirming before merge.
### Test Plan
- `helm template` the umbrella at defaults (correct dependency-build order) and assert every `secretName` referenced by a mount is created by the release.
- Assert the rendered secret manifest contains a `ca.crt` key.
- Ideally: a `kind`/local cluster install where the usage pod starts with mTLS at chart defaults — the property that is broken today.
### Verification evidence
To be supplied by the implementing PR.
### Human accountable owner
Stephane Segning Lambou
### AI Usage Declaration
AI-assisted (Claude): found by an adversarial review of #593 during the 2026-08-31 session and re-surfaced when #603 made the CA a default requirement. Chart contents were read and the `helm template` behaviour reproduced during that review; no fix has been attempted. Human review and prioritisation pending.
Guida per i contributori
Apri la guida per i contributori
Valutazione
Questa issue non è ancora stata valutata.