Documentation
¶
Overview ¶
Package auth provides authentication primitives for the Berth API server.
The core abstraction is the Authenticator interface, which validates a bearer token and returns an Identity describing the authenticated caller.
Static API keys ¶
StaticAuthenticator is the production implementation. Keys are stored as SHA-256 hashes — both the on-disk file format and the in-memory representation are hashed — so raw token material lives only on the caller's side (e.g., a Kubernetes Secret mounted by the operator). Use NewStaticAuthenticatorFromKeysFile for the production deployment and NewStaticAuthenticator for tests.
The keys file is one entry per line:
# comments and blank lines are ignored team-a:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef team-b:fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210
StaticAuthenticator.Reload re-reads the file on demand; the cmd/apiserver binary wires this to SIGHUP so operators can rotate keys without restarting the server.
Dev / no-auth ¶
NoOpAuthenticator accepts every request and returns a synthetic anonymous Identity. It is selected by `--auth-mode=none` and exists so the API server can run end-to-end against the in-memory lease store without secret material. cmd/apiserver logs a loud warning at startup when this authenticator is selected.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ValidateTenant ¶ added in v0.4.1
ValidateTenant checks that a tenant cannot overlap another tenant's holder prefix. Tenant IDs are exact strings: "/" is reserved for holder scoping and is never decoded or normalized. Missing tenants are rejected by authorization.
Types ¶
type Authenticator ¶
Authenticator validates a bearer token and returns the corresponding Identity. Implementations return a non-nil error when authentication fails.
type Identity ¶
type Identity struct {
// Holder is the identity name used as the lease holder.
Holder string
// Tenant is the resolved tenant identifier for access control. It must not contain "/".
Tenant string
// Raw is the original credential string presented by the caller.
Raw string
}
Identity represents an authenticated caller. It carries the holder name used for lease operations, the tenant for namespace isolation, and the raw credential string.
type NoOpAuthenticator ¶
type NoOpAuthenticator struct{}
NoOpAuthenticator is an Authenticator that accepts every request, including those with no Authorization header (the API server's middleware can bypass header parsing when the configured authenticator is this type — see internal/api).
It exists for `--auth-mode=none` development setups alongside the in-memory lease store. cmd/apiserver logs a loud startup warning when this authenticator is selected so production deployments cannot silently end up unauthenticated.
func (NoOpAuthenticator) Authenticate ¶
Authenticate returns a synthetic anonymous identity regardless of the supplied token (which may be empty).
type OIDCAuthenticator ¶
type OIDCAuthenticator struct {
// contains filtered or unexported fields
}
OIDCAuthenticator validates JWTs issued by an OIDC provider. The signature is verified against the provider's JWKS (cached and refreshed on `kid` miss by the underlying go-oidc library); the standard JWT claims (iss, aud, exp, nbf) are validated; and any caller-supplied required claims are enforced.
Construct via NewOIDCAuthenticator. The constructor performs an HTTP fetch against the issuer's discovery endpoint, so the API server fails fast at startup if the issuer is unreachable or misconfigured.
func NewOIDCAuthenticator ¶
func NewOIDCAuthenticator(ctx context.Context, cfg OIDCConfig) (*OIDCAuthenticator, error)
NewOIDCAuthenticator constructs an OIDCAuthenticator. ctx is used for the discovery + JWKS HTTP fetches; pass a context with a sensible timeout in production.
func (*OIDCAuthenticator) Authenticate ¶
Authenticate verifies token. Returns a deliberately generic error on any failure to avoid signaling whether a key id is known, an audience is wrong, etc.
type OIDCConfig ¶
type OIDCConfig struct {
// IssuerURL is the OIDC provider's issuer (e.g. "https://your-org.okta.com/oauth2/default",
// "https://pingfed.example.com"). The provider's discovery document is
// fetched from <IssuerURL>/.well-known/openid-configuration unless
// JWKSURL overrides it.
IssuerURL string
// Audience is the expected `aud` claim value. JWTs not issued for this
// audience are rejected.
Audience string
// JWKSURL, when non-empty, overrides the JWKS URL discovered from the
// issuer. Useful when a provider serves discovery and JWKS at different
// hosts (some legacy deployments).
JWKSURL string
// RequiredClaims is an optional set of claim/value pairs that must all
// be present on the token for authentication to succeed. The check
// matches both string-valued and string-array-valued claims (so
// `{"groups": "berth-clients"}` is satisfied when the `groups` claim is
// either the literal string "berth-clients" or a JSON array containing it).
RequiredClaims map[string]string
// UsernameClaim is the JWT claim copied into [Identity.Holder]. Default: "sub".
UsernameClaim string
// TenantClaim is the JWT claim copied into [Identity.Tenant]. When the
// claim is array-valued the first element is used. It must not contain "/".
// Default: "sub".
TenantClaim string
}
OIDCConfig configures an OIDCAuthenticator.
type StaticAuthenticator ¶
type StaticAuthenticator struct {
// contains filtered or unexported fields
}
StaticAuthenticator implements Authenticator using a fixed set of SHA-256-hashed bearer tokens.
Tokens are never stored in their raw form. The on-disk file format expects the hash so secret material only lives wherever the operator's raw token is mounted (typically a Kubernetes Secret on the operator side); the API server only ever holds hashes.
Use NewStaticAuthenticator to construct from raw tokens (typical for tests / in-process dev). Use NewStaticAuthenticatorFromKeysFile for production deployments that mount a hashed-keys file.
func NewStaticAuthenticator ¶
func NewStaticAuthenticator(keys map[string]Identity) *StaticAuthenticator
NewStaticAuthenticator constructs a StaticAuthenticator from a map of raw token strings to identities. Tokens are hashed before storage. Intended for tests and single-process dev setups; production should prefer NewStaticAuthenticatorFromKeysFile.
func NewStaticAuthenticatorFromKeysFile ¶
func NewStaticAuthenticatorFromKeysFile(path string) (*StaticAuthenticator, error)
NewStaticAuthenticatorFromKeysFile reads path and constructs a StaticAuthenticator. The file format is one entry per line:
<key-id>:<sha256-of-token-as-hex>
Lines beginning with `#` and blank lines are ignored. The key id is applied to Identity.Holder and Identity.Tenant.
The path is retained so StaticAuthenticator.Reload can re-read on demand (e.g., on SIGHUP) without restarting the server.
func (*StaticAuthenticator) Authenticate ¶
Authenticate hashes token, looks it up in the key set, and returns the matching Identity. Returns a deliberately generic error on any failure to avoid leaking which key ids exist.
func (*StaticAuthenticator) Reload ¶
func (a *StaticAuthenticator) Reload() error
Reload re-reads the keys file the authenticator was constructed from and atomically replaces its in-memory key set on success. On error, the existing key set is left unchanged so a malformed update can't silently lock the system out.