Documentation
¶
Overview ¶
Package oauthconfig loads mcp-oauth configuration from environment variables.
It exists because every in-tree consumer of mcp-oauth (muster, mcp-prometheus, mcp-observability-platform, and the examples under ./examples/) reimplements the same ~50 lines of env-reading, base64 decoding, and k8s secret-file handling. This package owns that plumbing.
Variables ¶
Base variables, all optional except OAUTH_ISSUER:
- OAUTH_ISSUER (required) — server issuer URL
- OAUTH_ALLOW_INSECURE_HTTP (default false) — permit http:// issuer
- OAUTH_ALLOW_PUBLIC_CLIENT_REGISTRATION (default false)
- OAUTH_REGISTRATION_ACCESS_TOKEN — registration bearer; see _FILE note below
- OAUTH_ENCRYPTION_KEY — 32-byte AES-GCM key, base64 (preferred) or hex
- OAUTH_SESSION_ID_HMAC_KEY — base64 32-byte HMAC key (see server.Config.SessionIDHMACKey for the operator caveat)
- OAUTH_ACCESS_TOKEN_TTL — Go duration (e.g. "1h")
- OAUTH_REFRESH_TOKEN_TTL — Go duration
- OAUTH_MAX_CLIENTS_PER_IP — positive integer
- OAUTH_TRUST_PROXY (default false)
- OAUTH_TRUSTED_AUDIENCES — comma-separated audience list
- OAUTH_ALLOW_LOCALHOST_REDIRECT_URIS (default false) — RFC 8252 native-app loopback support
- OAUTH_TRUSTED_REDIRECT_SCHEMES — comma-separated URI schemes (e.g. "cursor,vscode") populates server.Config.TrustedPublicRegistrationSchemes
Defaults are not applied in this package. FromEnv only populates the fields it reads; server.New runs applyDefaults afterwards and is the single source of truth for default values.
Secret files (*_FILE convention) ¶
Every secret variable above accepts a sibling "<NAME>_FILE" variant that names a file to read the value from — the standard Kubernetes mounted-secret convention. When both the plain and _FILE variants are set, _FILE wins (explicit path > env). The file's contents are trimmed of a single trailing newline (projected-volume files often have one).
- OAUTH_REGISTRATION_ACCESS_TOKEN_FILE
- OAUTH_ENCRYPTION_KEY_FILE
- OAUTH_SESSION_ID_HMAC_KEY_FILE
OAUTH_TRUSTED_AUDIENCES deliberately has NO _FILE variant — audience identifiers are not secrets. The asymmetry is intentional; the list lives in deployment configuration (Helm values / ConfigMap) rather than in a Secret.
OAUTH_TRUSTED_AUDIENCES charset and limits ¶
The value is split on literal commas, then each non-empty entry is validated through dex.ValidateAudiences. Allowed characters are [a-zA-Z0-9_-]; the per-entry length cap is 256 characters and the total list cap is 50. FromEnv returns an error at startup if any entry violates these rules.
This charset matches the Dex cross-client audience scope namespace (`audience:server:client_id:<id>`), which is the only context in which TrustedAudiences is currently consumed in production. Operators with URL-shaped audiences (RFC 8707) or other non-conforming values must populate oauth.Config.TrustedAudiences programmatically instead of relying on this loader.
FromEnv vs FromEnvWithPrefix ¶
FromEnv reads the names above. FromEnvWithPrefix reads the same names with a caller-supplied prefix (for consumers that scope env vars to their product, e.g. "MUSTER_OAUTH_"). The prefix is applied verbatim — include the trailing underscore if you want one.
Index ¶
- func DexFromEnv() (providers.Provider, error)
- func DexFromEnvWithPrefix(prefix string) (providers.Provider, error)
- func FromEnv() (*server.Config, error)
- func FromEnvWithPrefix(prefix string) (*server.Config, error)
- func GitHubFromEnv() (providers.Provider, error)
- func GitHubFromEnvWithPrefix(prefix string) (providers.Provider, error)
- func GoogleFromEnv() (providers.Provider, error)
- func GoogleFromEnvWithPrefix(prefix string) (providers.Provider, error)
- func NewEncryptorFromEnv() (*security.Encryptor, error)
- func NewEncryptorFromEnvWithPrefix(prefix string) (*security.Encryptor, error)
- func ProviderFromEnv() (providers.Provider, error)
- func ProviderFromEnvWithPrefix(prefix string) (providers.Provider, error)
- func StorageFromEnv(logger *slog.Logger) (storage.Combined, func() error, error)
- func StorageFromEnvWithPrefix(prefix string, logger *slog.Logger) (storage.Combined, func() error, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DexFromEnv ¶ added in v0.2.108
DexFromEnv reads OAUTH_DEX_* variables and returns a configured Dex provider.
OAUTH_DEX_ISSUER_URL (required) — e.g. https://dex.example.com OAUTH_DEX_CLIENT_ID (required) OAUTH_DEX_CLIENT_SECRET[_FILE] (required) OAUTH_DEX_REDIRECT_URL (required) OAUTH_DEX_CONNECTOR_ID (optional) — e.g. "github", "ldap"
Returned as providers.Provider (not *dex.Provider) so call sites stay provider-agnostic. Callers that need Dex-specific methods cast.
Deliberately NOT exposed as env vars (opinionated defaults):
- Scopes — the default Dex-optimized scope set is strictly better than what an operator would hand-configure; callers needing custom scopes build dex.Config themselves.
- HTTPClient — overriding the HTTP client is a programmatic concern (proxies, custom TLS, test doubles); the env surface would force the loader to invent a serialization for *http.Client.
- RequestTimeout — operators tune this via the upstream IdP's latency profile, which rarely varies per deployment. Default 30s is sound.
- MaxGroups — enterprise-specific tuning for very large AD group counts; the library default (oidc.DefaultMaxGroups = 600) covers the common case, and callers with unusual group counts construct Config manually.
Callers needing any of these construct dex.Config programmatically and call dex.NewProvider directly, bypassing this loader.
func DexFromEnvWithPrefix ¶ added in v0.2.108
DexFromEnvWithPrefix is DexFromEnv with a caller-supplied prefix.
func FromEnv ¶
FromEnv reads the standard OAUTH_* variables and returns a populated *server.Config. Defaults are NOT applied here — server.New runs applyDefaults and remains the single source of truth for default values. FromEnv only populates what the caller provided.
Returns an error for:
- missing required variables (OAUTH_ISSUER)
- malformed values (bad base64, bad duration, bad bool)
- secret _FILE paths that cannot be read
- insecure-HTTP issuer without the explicit opt-in
See the package doc for the full variable list and the _FILE convention.
func FromEnvWithPrefix ¶
FromEnvWithPrefix is FromEnv with a caller-supplied prefix. Useful for consumers that scope their env vars to their product name, e.g. FromEnvWithPrefix("MUSTER_OAUTH_"). The prefix is applied verbatim; include the trailing underscore if you want one.
func GitHubFromEnv ¶ added in v0.2.108
GitHubFromEnv reads OAUTH_GITHUB_* variables and returns a configured GitHub provider.
OAUTH_GITHUB_CLIENT_ID (required) OAUTH_GITHUB_CLIENT_SECRET[_FILE] (required) OAUTH_GITHUB_REDIRECT_URL (required) OAUTH_GITHUB_ALLOWED_ORGANIZATIONS (optional; comma-separated) — restrict login to members OAUTH_GITHUB_REQUIRE_VERIFIED_EMAIL (optional; defaults to provider default of true)
Deliberately NOT exposed as env vars:
- Scopes — the defaults ("user:email", "read:user") suit the vast majority of MCP deployments; custom scopes are programmatic.
- HTTPClient / RequestTimeout — same rationale as DexFromEnv.
GitHub is OAuth 2.0 only (no OIDC), so providers.IssuerOf returns "" for the resulting provider. Consumers that rely on [Server.AcceptForwardedIDToken] must not configure GitHub as the upstream.
func GitHubFromEnvWithPrefix ¶ added in v0.2.108
GitHubFromEnvWithPrefix is GitHubFromEnv with a caller-supplied prefix.
func GoogleFromEnv ¶ added in v0.2.108
GoogleFromEnv reads OAUTH_GOOGLE_* variables and returns a configured Google provider.
OAUTH_GOOGLE_CLIENT_ID (required) OAUTH_GOOGLE_CLIENT_SECRET[_FILE] (required) OAUTH_GOOGLE_REDIRECT_URL (required) OAUTH_GOOGLE_FORCE_CONSENT (optional; defaults to provider default of true)
Deliberately NOT exposed as env vars:
- Scopes — the Google-default set ("openid", "email", "profile") matches the overwhelmingly common case; custom scopes are a programmatic choice.
- HTTPClient / RequestTimeout — same rationale as DexFromEnv.
google.Config currently has no hosted-domain field (the Google provider doesn't implement Workspace domain restriction). Callers needing workspace restriction must construct google.Config programmatically once that field exists on the Config struct.
func GoogleFromEnvWithPrefix ¶ added in v0.2.108
GoogleFromEnvWithPrefix is GoogleFromEnv with a caller-supplied prefix.
func NewEncryptorFromEnv ¶
NewEncryptorFromEnv reads OAUTH_ENCRYPTION_KEY (or OAUTH_ENCRYPTION_KEY_FILE) as a 32-byte AES-GCM key and returns a *security.Encryptor ready to pass to server.SetEncryptor. Returns (nil, nil) when no key is configured — callers can decide whether to require encryption.
The key may be encoded as either base64 (canonical, produced by `openssl rand -base64 32`) or hex (`openssl rand -hex 32`). Base64 is tried first; on any failure (decode error or wrong length) the value is retried as hex. base64 is the recommended form.
Separate from FromEnv because token-at-rest encryption is wired via server.SetEncryptor after server construction, not through *server.Config.
func NewEncryptorFromEnvWithPrefix ¶
NewEncryptorFromEnvWithPrefix is NewEncryptorFromEnv with a caller-supplied prefix. See FromEnvWithPrefix for the convention.
func ProviderFromEnv ¶ added in v0.2.108
ProviderFromEnv reads OAUTH_PROVIDER (dex|google|github) and dispatches to the matching per-provider loader (DexFromEnv, GoogleFromEnv, GitHubFromEnv). Use this when the provider should be chosen at deploy time. Consumers that hard-code a single provider can call the specific loader directly.
Returns an error when OAUTH_PROVIDER is unset, empty, or not one of the three supported values. Unlike other variables in this package, there is deliberately no default — silently picking a provider would hide misconfiguration.
func ProviderFromEnvWithPrefix ¶ added in v0.2.108
ProviderFromEnvWithPrefix is ProviderFromEnv with a caller-supplied prefix. See FromEnvWithPrefix for the convention.
func StorageFromEnv ¶ added in v0.2.108
StorageFromEnv selects a storage backend from the STORAGE_BACKEND environment variable and returns a ready storage.Combined plus a close function the caller MUST defer. "memory" (default) and "valkey" are supported.
The returned close function is a no-op for memory and calls Store.Close() for valkey. It is always safe to call and always returns nil (close errors are swallowed and logged by the backend).
Valkey-specific variables (read only when STORAGE_BACKEND=valkey):
- VALKEY_ADDRESS (required when STORAGE_BACKEND=valkey)
- VALKEY_PASSWORD[_FILE] (optional)
- VALKEY_DB (optional; non-negative integer)
- VALKEY_KEY_PREFIX (optional; defaults to valkey.DefaultKeyPrefix)
- VALKEY_TLS (optional; "true" enables TLS)
- VALKEY_TLS_INSECURE_SKIP_VERIFY (optional; dev only)
- VALKEY_REFRESH_TOKEN_TTL (optional Go duration)
Pass the returned storage.Combined to server.NewWithCombined.
func StorageFromEnvWithPrefix ¶ added in v0.2.108
func StorageFromEnvWithPrefix(prefix string, logger *slog.Logger) (storage.Combined, func() error, error)
StorageFromEnvWithPrefix is StorageFromEnv with a caller-supplied prefix applied to STORAGE_BACKEND and VALKEY_*. The prefix is applied verbatim; include a trailing underscore if you want one. Useful for consumers that scope their env vars to their product name, e.g. StorageFromEnvWithPrefix("MUSTER_", logger).
Types ¶
This section is empty.