Add organization_id to JWT token metadata and request logging

Why

Follow-up from the organization parity assessment (WI #21, Q6.1) and investigation issue gitlab-org/gitlab#596900.

The Container Registry Go service logs have no organization_id, making per-organization debugging impossible. The investigation concluded that JWT token enrichment is the right mechanism — Rails includes organization_id in the JWT Meta claims, and the Go service extracts and logs it. This follows the existing pattern for project_id and root_namespace_id.

What

Add organization_id support to the Go service's JWT metadata extraction and request logging:

  1. Add OrganizationID int64 to the Meta struct — deserialized from JWT claims via encoding/json
  2. Add context key and extraction in metadata.go — new EgressOrganizationIdKey constant, extracted from pull action's Meta in WithEgressMetadata() (same pattern as namespace_id/project_id)
  3. Add to request loggers in app.go — add token.EgressOrganizationIdKey to the 3 logger lines in authorized(), dispatcher(), and dispatcherGitlab()
  4. Add to storage driver options in util.go — new OrganizationIdKey constant, extracted with > 0 guard in injectCustomKeyOpts()
  5. Update tests — metadata_test.go, token_test.go, util_test.go

Files to modify

File Change
registry/auth/token/token.go Add OrganizationID field to Meta struct
registry/auth/token/metadata.go Add context key, struct field, Value() case, extraction in WithEgressMetadata()
registry/handlers/app.go Add token import, add EgressOrganizationIdKey to 3 logger lines
registry/storage/util.go Add OrganizationIdKey constant and extraction block
registry/auth/token/metadata_test.go Add org ID to all test cases and assertions
registry/auth/token/token_test.go Add org ID to Meta literals, add round-trip assertion
registry/storage/util_test.go Add org ID to context and expected opts

Backwards compatibility

When Rails does not yet send organization_id in the JWT:

  • encoding/json unmarshals the missing field as int64(0)
  • Logger shows meta_organization_id: 0 (distinguishable from real IDs which are always positive)
  • Storage injectCustomKeyOpts() skips it via the > 0 guard

This MR can deploy independently before the Rails-side change. No feature flags needed.

Expected log output (after both Go and Rails changes)

{
  "auth_project_paths": ["group-a/project-a"],
  "auth_user_name": "user-a",
  "auth_user_type": "personal_access_token",
  "correlation_id": "01KNK3HD28QZN4H177YKGHMC9D",
  "meta_organization_id": 1000,
  "root_repo": "group-a",
  "vars_name": "group-a/project-a/image-a",
  "msg": "authorized request"
}