ADORSYS-GIS / ADORSYS-GIS/lightbridge-authz
[Story]: Authenticated multi-source ingest — source identity from credential, never payload
- Linguagem predominante
- Rust
- Estrelas
- 0
- Forks
- 1
- Merge médio
- 6h 42min
- PRs com merge (30d)
- 246
Descrição
Parent epic: #581
### Story Statement
As a security owner, I know every non-gateway telemetry row in the usage store entered through an authenticated door whose credential names the collector — developer-attributed data never rides the unauthenticated listener.
### Real Intent
ADR-0027 Decision 4 makes authenticated ingest a **prerequisite** of any non-gateway source going live. This story builds that door: per-collector identity for in-cluster callers, the aiCliOtel collector path for laptop CLIs, and refusal tests for every pattern.
### Background and Context
The current ingest listener is unauthenticated by design — acceptable only because its sole emitter (the gateway's Envoy sink) is pinned by deployment topology and the data carries no developer attribution. #535 named this the strongest argument against consolidation; governance#169/#191 already scoped the fix pattern for in-cluster callers (per-collector projected ServiceAccount tokens, `kubernetesTokenReview` — in production use on this cluster), sidestepping the authz-idp M2M gap (#534). Laptop CLIs already have a path: the `aiCliOtel` collector OIDC-validates authz-issued tokens (once governance#84's wrong-issuer 401 is fixed) and can forward with workload identity.
### Source of truth (links)
ADR-0027 Decision 4 · #534 · governance#160 · governance#169 · governance#170 · governance#191 · governance#84 · governance ADR-0013 invariant 2
### Acceptance Criteria
1. A distinct authenticated ingest surface (listener or route class) for multi-source telemetry; the trusted source string is bound to the presented credential, not to any payload field.
2. In-cluster collectors authenticate with per-collector projected SA tokens (audience names the endpoint); the stored principal is the SA identity.
3. The aiCliOtel forwarding path presents workload identity to usage; end-to-end proven with a **live 200** from a real CLI push (governance#189's bar), not a clean collector start.
4. Refusal tests, each written to fail first: no credential; wrong audience; disallowed principal; auth-dependency unreachable ⇒ refusal, never accept (fail-closed). No env-var opt-out that can silently skip them in CI (governance#170).
5. The gateway's existing path is unchanged in this story and documented as the one deliberate exception, with its topology pinning stated.
### Out of Scope
authz-idp `client_credentials` (that's #534's own decision); rotating the gateway path onto workload identity; Codex/VS Code static-credential gap (governance#144).
### Dependencies and Blockers
governance#84 (issuer fix) for the CLI leg; coordination with governance#169 so the SA-token pattern is implemented once, consistently.
### Assumptions
TokenReview-based validation is reachable from the usage pod (same cluster). If usage ever runs outside the cluster, this decision reopens.
### Implementation Notes
Keep the fail-closed posture symmetrical with the rest of the platform: unavailable validator ⇒ refuse, never `unwrap_or(true)`. Constant-time comparisons where shared secrets appear transitionally — but no new shared secrets: governance#191 removes `X-Internal-Token`, it must not reappear here.
### Test Expectations
Per-pattern refusal tests (fail-first, then guard); a dependency-down test asserting refusal; live-push integration evidence.
### Verification evidence
To be attached on the implementing PR.
### Human accountable owner
Stephane Segning Lambou
### AI Usage
AI-assisted (Claude): research and drafting. Reviewed and owned by Stephane Segning Lambou.
### Design addendum (2026-08-31): collector fan-out is the canonical ingest topology
Settled with the repo owner: **everyone writes to the authenticated edge OTEL collector** (the `aiCliOtel` pattern), which stamps the trusted `source` after OIDC validation and fans out **at the edge**, in parallel legs: (1) Alloy → Mimir/Loki/Tempo (observability copy), (2) the authz-usage governed ingest, (3) the raw OTLP object-storage archive (see the raw-archive story, #589). Consequences for this story's ACs:
- AC 3's aiCliOtel forwarding path is not one option among several — it is the canonical door for push sources; the usage-side authenticated surface primarily trusts the collector's workload identity plus its stamped source.
- The authz leg attaches to the **edge collector**, not behind Alloy: the governed/billing path must not share fate with the observability pipeline, and the source stamp must not have to survive an extra hop.
- Pull sources may adopt the same door by emitting OTLP (see governance#196's addendum) — the per-collector SA-token leg (AC 2) then covers the collector itself and any caller that cannot ride it.
Guia de contribuição
Avaliação
Esta issue ainda não foi avaliada.