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
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.