Documentation
¶
Overview ¶
Package internalauth is the gateway <-> service identity assertion: the gateway mints a short-lived ES256 token asserting the verified caller, and services verify it with the gateway's PUBLIC key before trusting that identity. It wraps the shared jwtx primitives and loads keys from the environment.
Only the gateway holds the private key, so only the gateway can mint an assertion - a compromised service holds the public key alone and cannot forge one. Internal service-to-service calls forward the inbound assertion (see identity.GatewayToken) rather than minting, so caller identity always traces back to a single gateway signature.
Index ¶
- Constants
- func Check(v *jwtx.Verifier, token string) (sub string, role identity.Role, ok bool)
- func Middleware() (gin.HandlerFunc, error)
- func Mint(s *jwtx.Signer, sub string, role identity.Role) (string, error)
- func SelfCheck(s *jwtx.Signer, v *jwtx.Verifier) error
- func SignerFromEnv() (*jwtx.Signer, error)
- func VerifierFromEnv() (*jwtx.Verifier, error)
- func VerifyFunc(v *jwtx.Verifier) func(token string) (string, identity.Role, bool)
Constants ¶
const ( EnvPrivateKey = "INTERNAL_AUTH_PRIVATE_KEY" EnvKID = "INTERNAL_AUTH_KID" EnvPublicKeys = "INTERNAL_AUTH_PUBLIC_KEYS" // EnvMode, set to ModePermissive, is the explicit opt-in to run WITHOUT // gateway-assertion verification/signing. Without it, a missing key is a // startup error rather than a silent trust-on-network-isolation // downgrade - so the security control can't ship off by accident. EnvMode = "INTERNAL_AUTH_MODE" ModePermissive = "permissive" )
Env var names. The private key is secret; the public keyset is not.
const ClockSkewLeeway = 60 * time.Second
ClockSkewLeeway tolerates clock drift between the gateway (issuer) and a verifying service when checking the assertion's exp. The assertion is minted on one host and verified on another and forwarded across hops, so strict expiry would 401 on ordinary NTP drift; this gives headroom. It widens the worst-case replay window to TTL+leeway, an internal-network-only exposure already bounded by the gateway-sole-ingress assumption.
const TTL = 60 * time.Second
TTL is how long a minted assertion stays valid. It only needs to outlive a single request's downstream fan-out (gateway -> service -> service), so it's kept short to bound the replay window if one is ever captured.
Variables ¶
This section is empty.
Functions ¶
func Check ¶
Check verifies an assertion's signature, expiry, issuer and purpose, returning the asserted subject, the caller's staff role, and ok=true. A bad/expired/foreign token returns ok=false. An out-of-range role claim is clamped to RoleUser so a malformed assertion never yields a privileged tier.
func Middleware ¶
func Middleware() (gin.HandlerFunc, error)
Middleware builds the gateway-assertion verification middleware from the environment, so every service mounts it identically in one line:
mw, err := internalauth.Middleware() ... r.Use(..., mw)
Centralizing the VerifierFromEnv + VerifyFunc + VerifyGateway wiring here means a change to how services verify (a metrics hook, a required-key mode) lands in one place rather than being re-edited across every service. A malformed keyset surfaces as the returned error.
func Mint ¶
Mint signs an assertion for sub (the verified caller id, or "" for a public request that carries no user - the assertion then only proves gateway origin) carrying the caller's staff role. role travels in the signed claim, so a downstream service derives the tier from the gateway's signature rather than a spoofable header - the same trust path as the subject. It signs a minimal claim set directly (iss/sub/role/exp + purpose); unlike the jwtx Issue* helpers it omits a per-token jti, which an ephemeral assertion has no use for and which would cost a crypto/rand read on every proxied request.
func SelfCheck ¶
SelfCheck confirms the gateway's signing key and the published verifying keyset actually correspond: it mints a probe assertion and verifies it. A mismatch (wrong kid, a key rotated on one side only, the wrong keyset) fails here at startup, loudly, instead of surfacing as opaque 401s on the first real request. Call it only when both halves are configured.
func SignerFromEnv ¶
SignerFromEnv builds the gateway's assertion signer from EnvPrivateKey (a base64-encoded or raw PEM EC private key) and EnvKID. Returns (nil, nil) when unset, so the gateway can run un-keyed during rollout (it then falls back to injecting a raw X-User-Id and logs a warning).
func VerifierFromEnv ¶
VerifierFromEnv builds the assertion verifier from EnvPublicKeys (a base64-encoded or raw JSON {kid: PEM} keyset - jwtx.ParseKeyset handles both). Returns (nil, nil) when unset, so a service can run un-keyed during rollout (ginx.VerifyGateway then passes through with a warning).
func VerifyFunc ¶
VerifyFunc adapts a verifier into the closure ginx.VerifyGateway expects. It returns nil when v is nil (key unset) so VerifyGateway runs in its pass-through rollout mode rather than rejecting every request.
Types ¶
This section is empty.