Skip to content

Use typed context keys instead of string literals #4780

@dejanzele

Description

@dejanzele

Is your feature request related to a problem? Please describe.

Context values are stored using bare string keys throughout the codebase:

// internal/common/auth/common.go:14
const principalKey = "principal"  // named constant, but still a plain string type

// internal/common/auth/common.go:127
context.WithValue(ctx, "user", principal.GetName())

// internal/common/requestid/interceptors.go:46
context.WithValue(ctx, "requestId", id)

All three are plain string keys. If any other package stores a context value under the same string (e.g., "user"), the values silently overwrite each other. Go's recommended pattern is to use an unexported custom type so that keys from different packages can never collide, even if they have the same underlying string value:

type contextKey string
const principalKey contextKey = "principal"

Describe the solution you'd like

  1. Define an unexported contextKey type (e.g., in internal/common/auth/ or a shared location)
  2. Convert principalKey, the "user" key, and the "requestId" key to use this typed key
  3. Update all readers to use the same typed keys

Files to change

Writers:

  • internal/common/auth/common.go:14 - convert principalKey from plain string to typed key
  • internal/common/auth/common.go:127 - convert "user" literal to typed key constant
  • internal/common/requestid/interceptors.go:46 - convert "requestId" literal to typed key constant

Readers:

  • internal/common/auth/common.go:94 - reads principalKey (already uses the constant)
  • internal/common/armadacontext/armada_context.go:97-98 - reads "user" and "requestId"
  • internal/common/grpc/grpc.go:159-160 - reads "user" and "requestId"

Since the readers are in different packages than the writers, the key constants will need to be exported, or the defining packages should expose getter functions (e.g., auth.UserFromContext(ctx)). Either approach works.

Acceptance criteria

  • All context keys use a custom unexported type (not plain strings)
  • All readers and writers use the same typed keys
  • go test ./internal/common/... passes
  • golangci-lint run ./internal/common/... passes

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions