Documentation
¶
Overview ¶
Package file implements the default file-backed jwt.Signer for the identity service. Private RSA keys live in a JSON document on disk; the running process reads it at startup and on SIGHUP, with each entry carrying its own not_before / expires_at envelope so multiple generations of keys can coexist during rotation.
The on-disk format is intentionally human-editable so a small deployer can rotate keys by writing one extra entry and sending SIGHUP, without bringing the process down. KMS-backed deployments use pkg/jwt/kmsaws instead.
Index ¶
- func WatchSIGHUP(s *Signer, onError func(error)) (stop func())
- type Options
- type Signer
- func (s *Signer) ActiveKID() string
- func (s *Signer) Get(kid string) (*rsa.PublicKey, bool)
- func (s *Signer) Keys() []jwt.PublicKey
- func (s *Signer) Reload() error
- func (s *Signer) SignAccessToken(ctx context.Context, claims jwt.Claims, expiry time.Duration) (string, error)
- func (s *Signer) SignClaims(_ context.Context, claims map[string]any) (string, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func WatchSIGHUP ¶
WatchSIGHUP installs a SIGHUP handler that triggers Signer.Reload each time the process receives the signal. Returns a stop function the caller MUST invoke during shutdown to detach the handler and drain the goroutine. Reload errors are passed to the supplied callback so the caller can decide whether to log, increment a metric, or abort.
Rationale: existing identity entrypoints already use signal.Notify for SIGTERM/SIGINT (see cmd/identity/main.go). Reusing the same pattern keeps process-signal handling in one place. Operators who prefer file-watching can wrap the deployment in a sidecar that re-renders keys.json and sends SIGHUP, or extend this package with an fsnotify-based driver later — the Signer.Reload method is the single source of truth either way.
Types ¶
type Options ¶
type Options struct {
// Now overrides time.Now() for tests. Production wiring leaves
// this nil; the signer falls back to time.Now().UTC().
Now func() time.Time
// Logf is a hook for logging Reload outcomes. nil disables logging.
Logf func(format string, args ...any)
}
Options tunes how the Signer reads the file. Zero values give the production defaults.
type Signer ¶
type Signer struct {
// contains filtered or unexported fields
}
Signer is the file-backed implementation of jwt.Signer. It is safe for concurrent use; Reload swaps the snapshot atomically.
func GenerateAndWrite ¶
GenerateAndWrite is a convenience used by tests when they specifically want a keys.json file on disk: it creates a fresh RSA-2048 key, writes a one-entry keys file at path, and returns the resulting Signer. Production deployments always ship their own keys file.
func GenerateInMemory ¶
GenerateInMemory constructs a Signer with a freshly-generated RSA key. The key never touches disk. This is the dev-fallback path cmd/identity uses when no keys file is configured — the scratch Docker image has no /tmp to write to, and a deployer who hasn't set GATEWAY_JWT_KEYS_FILE never wanted persistent keys anyway.
Production deployments always set GATEWAY_JWT_KEYS_FILE; this fallback exists only so a freshly-pulled binary boots cleanly.
func New ¶
New constructs a Signer by reading the keys file at path. Returns an error when the file is missing, unparseable, or contains no usable active key. The caller wires up reload triggers separately (see WatchSIGHUP).
func (*Signer) Keys ¶
Keys returns every public key the signer currently advertises, including keys past their ExpiresAt. The slice is freshly allocated; callers may modify it.
func (*Signer) Reload ¶
Reload re-reads the keys file and atomically swaps the in-memory snapshot. Existing in-flight signing operations continue to use the previous snapshot; new operations after Reload returns use the new one. Returns an error without changing state when the new file cannot be parsed or has no active key.