Files
0pt/src
admin d40360aabc
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (pull_request) Successful in 7s
masterplan-lock / check (push) Successful in 7s
CI (SIAX Cloud) / Component conformance (blocking) (pull_request) Successful in 13s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 17s
CI (SIAX Cloud) / security (pull_request) Successful in 18s
CI (SIAX Cloud) / integration (pull_request) Successful in 27s
CI (SIAX Cloud) / quality (pull_request) Successful in 10m5s
feat(auth): dual-accept CL0UD workload identity on the machine routes
The internal machine routes (`quality/bridge-run`, `canonical/facts`,
`internal/evidence-outbox/dispatch`, `internal/er/candidates`,
`search/definitions`) trusted a shared `X-Internal-Token` with NO tenant
authority: middleware let it through without setting any verified tenant, so
`assertTenantMatchesVerified` was a no-op and a caller-chosen `tenant_id` in
the body was authoritative.

This closes that gap while keeping the engine working during the transition
to CL0UD workload tokens:

- `src/auth/internal-service-tenant.ts` — the server-configured
  `INTERNAL_SERVICE_TENANTS` scope, a scope header that only middleware may
  set, and a parser that strips/ignores client values.
- `src/auth/cl0ud-workload.ts` — a real `jose`/JWKS verifier for CL0UD
  workload JWTs (`iss`/`aud`/`exp`), deriving `tenant_id` and `capabilities`
  from verified claims only. Fail-closed when a token is presented but the
  issuer/JWKS/audience/tenant claim does not verify.
- `middleware.ts` — strips every `x-0pt-verified-*` header on all forwarded
  paths. Legacy internal tokens get the single configured tenant as scope
  (an ambiguous multi-tenant list is refused with 401 instead of widened);
  a Bearer CL0UD workload token is verified and its claims become the
  verified tenant/subject/capabilities.
- `src/http/tenant-guard.ts` — enforces the service scope on tenant-scoped
  writes (deny when the tenant is outside the scope) and adds
  `assertWorkloadCapabilities` for capability-scoped principals.
- `quality/bridge-run` now calls `assertTenantMatchesVerified` like
  `canonical/facts` already did.

Tests: `tests/auth/workload-identity-dual-accept.test.ts` (10 cases) covers
forged-header stripping, ambiguous-scope refusal, wrong audience, missing
tenant claim, cross-tenant denial and missing-capability denial.

Real CL0UD provisioning (service accounts + published JWKS) is still
required before a workload token exists in production; until then the
legacy token path is the only one that authenticates, now tenant-scoped.
2026-11-09 18:34:34 +01:00
..