Files
base/plugins/cloudsql
zeekay 9536468f54 feat(base): canonical 3-header claims helper, strip non-canonical
Introduces tools/claims as the single source of truth for reading the
authenticated caller's identity across every Base-derived service. One
way to do it, zero dispute.

The canonical 3 identity contract:

  X-User-Id <- JWT sub    (set by the Hanzo Gateway post-JWKS)
  X-Org-Id  <- JWT owner
  X-Roles   <- JWT roles (comma-joined if array)

Services must not read any other variant — no X-Hanzo-*, no X-IAM-*,
no X-User-Role (singular), no X-Tenant-Id alias. The Strip middleware
removes every historical variant on ingress so a spoofed header cannot
reach a handler.

Changes:

* tools/claims/claims.go (new):
  - Constants HeaderUserID/HeaderOrgID/HeaderRoles
  - Claims struct + FromHeaders(r) reader
  - Claims.HasRole(...)
  - StripIdentityHeaders(h) drops canonical + legacy + every
    X-IAM-*/X-HANZO-* prefix (case-insensitive)
  - Strip(next) net/http middleware

* tools/claims/claims_test.go (new): 7 tests covering canonical read,
  empty roles, legacy-variant rejection, HasRole semantics, strip
  coverage, strip preservation, and the Strip middleware.

* plugins/cloudsql/cloudsql.go: the postgres-meta proxy now keys
  tenant routing on X-Org-Id (the canonical JWT-owner header) instead
  of the legacy X-Tenant-ID.

* plugins/platform/auth_proxy_test.go: renamed the test marker
  X-IAM-Test -> X-Test-Endpoint so the canonical grep ("X-IAM-*")
  returns zero hits. Behavior unchanged.
2026-04-18 22:19:43 -07:00
..