config

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 15, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

Documentation

Overview

Package config loads the identity service configuration from environment variables with the GATEWAY_ prefix.

This is the Go port of backend/api_gateway/config.py. It uses os.Getenv with typed defaults — no external config library needed. Sensitive values (secrets, encryption keys, client secrets) are never logged.

Index

Constants

View Source
const (
	CaptchaProviderTurnstile   = "turnstile"
	CaptchaProviderRecaptchaV3 = "recaptcha_v3"

	// DefaultCaptchaRecaptchaScoreThreshold is the reCAPTCHA v3 score below
	// which a response is rejected when no threshold is configured.
	DefaultCaptchaRecaptchaScoreThreshold = 0.5
)

CAPTCHA provider names accepted in GATEWAY_CAPTCHA_PROVIDER. They mirror the captcha.Provider* constants; config validates against these without importing pkg/captcha (config has no dependencies on the service tree).

View Source
const (
	SMSProviderTwilio = "twilio"
	SMSProviderSNS    = "sns"
	SMSProviderAzure  = "azure"
)

SMS provider names for GATEWAY_SMS_PROVIDER. Firebase/Google are intentionally out of scope — those are client-SDK flows, not server REST APIs.

View Source
const DefaultProjectIDFallback = "default"

DefaultProjectIDFallback is the project id used when none is configured. It is the env-loader default for GATEWAY_DEFAULT_PROJECT_ID and the value app.New normalizes an empty DefaultProjectID to, so a directly-constructed Config (tests, embedding callers) never reaches the repo boundary with an empty project shard id. The single source of truth for this literal.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Server
	GRPCPort    int
	ConnectPort int
	MetricsPort int

	// Persistence driver. Selects which Repository / DB
	// implementation the binary wires up — "entdb" (default), "memory"
	// for an in-process store useful for local dev, or "postgres"
	// once the Postgres driver lands. Driven by GATEWAY_REPO_DRIVER.
	RepoDriver string

	// EntDB
	EntDBAddress string

	// Tenant
	DefaultTenantID string

	// DefaultProjectID is the id of the control-plane Project the service
	// seeds on boot (postgres driver) and pins zero-config requests to. It
	// is a logical control-plane entity that MAPS ONTO the storage scope
	// DefaultTenantID — the two are distinct values and must not be
	// conflated. Driven by GATEWAY_DEFAULT_PROJECT_ID (default "default").
	// Only the postgres driver has a control plane; entdb/memory ignore it.
	DefaultProjectID string

	// AdminAPISecret is the shared secret that authenticates the
	// control-plane admin RPCs (AdminCreateProject and friends), which a
	// PLATFORM operator uses to provision projects/tenants out-of-band.
	// These RPCs are NOT user-authenticated: a caller proves it is the
	// operator by presenting this exact value in the
	// middleware.AdminAPISecretHeader header, compared in constant time.
	//
	// Empty (the default) DISABLES the admin RPCs entirely — they return
	// CodeUnimplemented — so a deployer who never sets it cannot have them
	// reached. Driven by GATEWAY_ADMIN_API_SECRET. Only the postgres driver
	// has a control plane; entdb/memory ignore it.
	//
	// TODO(redesign): the shared secret is the shipped mechanism. Future
	// work hardens this with mTLS client-certificate auth and an optional
	// internal-only listener port bound away from the public RPC surface.
	AdminAPISecret string

	// DefaultProjectAuthDomains is a comma-separated list of serving
	// hostnames seeded onto the default project at boot (postgres driver),
	// so the Host→project resolver maps these branded hostnames to the
	// default project. The FIRST entry is the primary auth-domain (used to
	// build branded links and cookie domains); the rest are additional
	// serving hosts. All are seeded VERIFIED — they are deployer-owned (a
	// customer-supplied custom domain goes through DNS verification
	// instead). Empty disables seeding. Driven by
	// GATEWAY_DEFAULT_PROJECT_AUTH_DOMAINS.
	DefaultProjectAuthDomains string

	// RequireVerifiedAuthDomain governs whether an UNVERIFIED custom
	// auth-domain marked is_primary may become a project's primary
	// auth-domain — the host that drives branded link URLs (magic links,
	// invitations) and cookie domains. When true (the safe default), the
	// primary-auth-domain selection requires verified_at_ms > 0, so only a
	// DNS-verified host can drive branded links, matching the verified-only
	// Host→project resolver and the proto contract on is_primary. identity
	// is a library/OSS server, so whether to trust an unverified is_primary
	// host is the deployer's policy: set this false to opt in. Driven by
	// GATEWAY_REQUIRE_VERIFIED_AUTH_DOMAIN, default true.
	RequireVerifiedAuthDomain bool

	// Email service (internal gRPC)
	EmailServiceHost string
	EmailServicePort int

	// JWT (RS256). Two backends ship in-tree:
	//
	//   file     (default) reads the keys file at GATEWAY_JWT_KEYS_FILE,
	//            reloads on SIGHUP. The default for any non-KMS
	//            deployment; works without external dependencies. If
	//            JWTKeysFile is empty, the binary auto-generates a
	//            throwaway dev key in a temp file at startup (suitable
	//            for local dev / CI only — emits a warning log).
	//   kms_aws  delegates Sign to AWS KMS. JWTKMSKeys is a CSV of
	//            "kid=keyARN" entries.
	//
	// Adding a new backend (GCP KMS, HashiCorp Vault, hardware HSM, …)
	// is a matter of implementing pkg/jwt.Signer in a sibling package.
	JWTSigner        string
	JWTKeysFile      string
	JWTKMSKeys       string
	JWTKMSAWSRegion  string
	JWTExpirySeconds int

	// JWT audience. When non-empty, minted access tokens carry this as
	// the "aud" claim and the verifier enforces a match. When
	// JWTRequireAudience is true, tokens with no "aud" claim are also
	// rejected; the false default exists so a deploy can roll out the
	// mint-side change first, wait for in-flight tokens to expire, then
	// flip to required.
	JWTAudience        string
	JWTRequireAudience bool

	// Refresh tokens
	RefreshExpirySeconds int

	// Revocation mode. Selects how the service propagates a
	// DeleteRefreshTokensForUser to in-flight access tokens.
	//
	//   "ttl"     (default) — refresh tokens are deleted; already-minted
	//             access tokens stay valid until natural JWT expiry. Zero
	//             hot-path cost. Hard startup assertion:
	//             `JWTExpirySeconds <= 900` so a deployer cannot raise the
	//             access-token lifetime without explicitly switching modes.
	//   "session" — opt-in. Access tokens carry an `sid` claim referencing
	//             a Session row; the verification middleware reads that
	//             row (via an in-process cache, configurable below) and
	//             rejects the request when `revoked_at_ms != 0`.
	//             DeleteRefreshTokensForUser additionally triggers
	//             RevokeSessionsForUser so the existing replay-detection
	//             code path also kills the access tokens.
	//
	// See docs/IDENTITY.md decision log §6 for the two-mode contract.
	RevocationMode RevocationMode

	// SessionCacheTTLSeconds bounds how long a session-state read from the
	// in-process cache may serve "active" before being re-read from the
	// repository. 0 = strict mode: every authenticated request reads the
	// row. Effective only when RevocationMode == RevocationModeSession.
	SessionCacheTTLSeconds int

	// ProjectResolutionCacheTTLSeconds bounds how long a per-request
	// project resolution (credential-key→project and Host→project) may be
	// served from the in-process cache before being re-read from the
	// control-plane store. Project resolution runs ahead of the rate
	// limiter and on every CORS preflight, so caching it removes 2-3
	// uncached DB queries from the hot path. Kept short so a suspended
	// project or revoked credential is never served stale beyond the TTL.
	// 0 = disabled: every request resolves against the store.
	ProjectResolutionCacheTTLSeconds int

	// ProjectResolutionCacheMaxEntries bounds the number of distinct
	// resolution keys (credential ids + hostnames) held in the cache,
	// evicting the least-recently-used entry past the bound so the cache
	// cannot grow unbounded under hostile or high-cardinality traffic.
	ProjectResolutionCacheMaxEntries int

	// OAuth providers. Identity does the code exchange for these
	// providers itself — see pkg/oauth. A provider is enabled only
	// when BOTH the ID and secret are non-empty.
	GoogleClientID        string
	GoogleClientSecret    string
	MicrosoftClientID     string
	MicrosoftClientSecret string
	MicrosoftTenantID     string
	GitHubClientID        string
	GitHubClientSecret    string

	// OAuthAllowedReturnURLs is the comma-separated allowlist of app URLs
	// the hosted OAuth flow may redirect back to (the `return_to` param of
	// GET /oauth/start/{provider}). Each entry is an exact origin or a URL
	// prefix; a return_to matches when it equals an entry or begins with
	// an entry. Validation is fail-closed: a return_to that matches no
	// entry is rejected with 400.
	//
	// Empty disables the hosted flow entirely — GET /oauth/start and GET
	// /oauth/callback return 404. The headless BeginOAuthLogin / OAuthLogin
	// RPCs are unaffected. Driven by GATEWAY_OAUTH_ALLOWED_RETURN_URLS.
	OAuthAllowedReturnURLs string

	// Identity Verification (document + selfie). The provider name
	// selects the implementation in pkg/idv. Empty disables IDV; the
	// RPCs return CodeUnimplemented to clients in that case.
	IDVProvider           string // "azure", "stub", or "" (disabled)
	IDVAzureEndpoint      string // e.g. https://my-face.cognitiveservices.azure.com
	IDVAzureKey           string // Cognitive Services key
	IDVAzureSessionTTLSec int    // session token lifetime; default 600
	// When true, PasswordLogin / OAuthLogin reject users without an
	// approved identity verification. The default is false (verification
	// is offered but not required) to match the existing email-verified
	// pattern. Tenants that need stricter onboarding flip this on.
	IDVRequired bool

	// CAPTCHA verification on unauthenticated endpoints. CaptchaEnabled is
	// the global on/off; when off the no-op verifier is wired and the
	// per-endpoint toggles are ignored. CaptchaProvider selects the
	// implementation in pkg/captcha ("turnstile" or "recaptcha_v3"); the
	// matching secret must be set. The per-endpoint toggles let a deployer
	// enforce CAPTCHA on a subset of the gated endpoints (all default true,
	// so enabling CAPTCHA gates every endpoint unless one is flipped off).
	CaptchaEnabled                 bool    // GATEWAY_CAPTCHA_ENABLED (default false)
	CaptchaProvider                string  // GATEWAY_CAPTCHA_PROVIDER ("turnstile" | "recaptcha_v3" | "")
	CaptchaTurnstileSecret         string  // GATEWAY_CAPTCHA_TURNSTILE_SECRET
	CaptchaRecaptchaSecret         string  // GATEWAY_CAPTCHA_RECAPTCHA_SECRET
	CaptchaRecaptchaScoreThreshold float64 // GATEWAY_CAPTCHA_RECAPTCHA_SCORE_THRESHOLD (default 0.5)
	CaptchaEnforcePasswordSignup   bool    // GATEWAY_CAPTCHA_ENFORCE_PASSWORD_SIGNUP (default true)
	CaptchaEnforcePasswordLogin    bool    // GATEWAY_CAPTCHA_ENFORCE_PASSWORD_LOGIN (default true)
	CaptchaEnforcePasswordReset    bool    // GATEWAY_CAPTCHA_ENFORCE_PASSWORD_RESET (default true)
	CaptchaEnforceEmailLoginCode   bool    // GATEWAY_CAPTCHA_ENFORCE_EMAIL_LOGIN_CODE (default true)
	CaptchaEnforceMagicLink        bool    // GATEWAY_CAPTCHA_ENFORCE_MAGIC_LINK (default true)

	// Password
	PasswordSignupEnabled      bool
	PasswordResetEnabled       bool
	PasswordResetExpirySeconds int

	// Passwordless email login (OTP code + magic link).
	//
	// PasswordlessSignupEnabled (default true) gates auto-create: when a
	// passwordless login verifies an email with no existing account and
	// this is true, the account is created on the spot; when false the
	// unknown email gets the same anti-enumeration decoy a request for a
	// known email would produce, so the endpoint never reveals which
	// addresses exist. Mirrors GATEWAY_PASSWORD_SIGNUP_ENABLED.
	PasswordlessSignupEnabled bool // GATEWAY_PASSWORDLESS_SIGNUP_ENABLED (default true)
	// OTP code lifetime, length is fixed at 6 digits.
	PasswordlessCodeTTLSeconds int // GATEWAY_PASSWORDLESS_CODE_TTL_SECONDS (default 300)
	// Max verify attempts per OTP before it is invalidated (brute-force cap).
	PasswordlessCodeMaxAttempts int // GATEWAY_PASSWORDLESS_CODE_MAX_ATTEMPTS (default 5)
	// Magic-link token lifetime.
	PasswordlessMagicLinkTTLSeconds int // GATEWAY_PASSWORDLESS_MAGIC_LINK_TTL_SECONDS (default 900)

	// Phone verification (SMS OTP). Standalone phone-ownership
	// verification for an already-authenticated user — not yet a login
	// factor. Disabled by default; when SMSEnabled is true a provider and
	// its credentials must be set (enforced by Validate).
	SMSEnabled  bool   // GATEWAY_SMS_ENABLED (default false)
	SMSProvider string // GATEWAY_SMS_PROVIDER: twilio | sns | azure

	// Twilio credentials (SMSProvider == twilio).
	SMSTwilioAccountSID string // GATEWAY_SMS_TWILIO_ACCOUNT_SID
	SMSTwilioAuthToken  string // GATEWAY_SMS_TWILIO_AUTH_TOKEN
	SMSTwilioFrom       string // GATEWAY_SMS_TWILIO_FROM

	// AWS SNS credentials (SMSProvider == sns).
	SMSAWSRegion          string // GATEWAY_SMS_AWS_REGION
	SMSAWSAccessKeyID     string // GATEWAY_SMS_AWS_ACCESS_KEY_ID
	SMSAWSSecretAccessKey string // GATEWAY_SMS_AWS_SECRET_ACCESS_KEY
	SMSAWSSenderID        string // GATEWAY_SMS_AWS_SENDER_ID (optional)

	// Azure Communication Services credentials (SMSProvider == azure).
	SMSAzureConnectionString string // GATEWAY_SMS_AZURE_CONNECTION_STRING
	SMSAzureFrom             string // GATEWAY_SMS_AZURE_FROM

	// Phone-verification OTP policy (mirrors the Passwordless* knobs).
	PhoneCodeTTLSeconds      int // GATEWAY_PHONE_CODE_TTL_SECONDS (default 300)
	PhoneCodeMaxAttempts     int // GATEWAY_PHONE_CODE_MAX_ATTEMPTS (default 5)
	PhoneCodeCooldownSeconds int // GATEWAY_PHONE_CODE_COOLDOWN_SECONDS (default 60)

	// TOTP (2FA)
	// 32-byte key, base64-encoded. Required in prod; dev falls back to
	// a deterministic throwaway key.
	TOTPEncryptionKey string
	TOTPIssuer        string

	// Pepper used as the HMAC-SHA-256 key for recovery-code hashing.
	// Base64-encoded; must decode to >= 32 bytes. Required whenever
	// TOTPEncryptionKey is set (i.e. any non-dev deployment). The
	// pepper turns a stolen DB into a brute-force-resistant artifact:
	// without it, an attacker cannot precompute or enumerate hashes.
	TOTPRecoveryPepper string

	// Login challenge (how long after password success user has to complete 2FA)
	LoginChallengeExpirySeconds int

	// WebAuthn / Passkeys
	PasskeyRPID                   string
	PasskeyRPName                 string
	PasskeyOrigin                 string
	PasskeyChallengeExpirySeconds int

	// QR Login (cross-device authorization)
	QRLoginBaseURL       string
	QRLoginExpirySeconds int

	// Login security (failed-login lockout)
	LoginMaxFailedAttempts int
	LoginLockoutSeconds    int

	// Default email domain
	DefaultEmailDomain string

	// PublicEmailDomains extends the built-in set of consumer/public email
	// providers (gmail, outlook, yahoo, …) used by IsPublicEmailDomain. A
	// verified email under a public domain does NOT imply company
	// affiliation, so a tenant is never auto-formed from one. Comma-
	// separated; entries are punycode-canonicalised. Driven by
	// GATEWAY_PUBLIC_EMAIL_DOMAINS (default empty — the built-in set
	// already covers the major global providers).
	PublicEmailDomains string

	// CORS
	AllowedOrigins string

	// Cookie settings
	CookieDomain   string
	CookieSecure   bool
	CookieSameSite string

	// Dev-only
	AuthAllowLocal bool

	// SMTP single-provider config (simple form). If SMTPProviders is set,
	// that takes precedence.
	SMTPHost string // GATEWAY_SMTP_HOST
	SMTPPort int    // GATEWAY_SMTP_PORT (default 587)
	SMTPUser string // GATEWAY_SMTP_USER
	SMTPPass string // GATEWAY_SMTP_PASS
	SMTPFrom string // GATEWAY_SMTP_FROM
	SMTPTLS  bool   // GATEWAY_SMTP_TLS (default true)

	// SMTP multi-provider JSON. If set, parsed as []email.SMTPConfig and
	// used as a chain in order. Overrides the single-provider env vars.
	SMTPProviders string // GATEWAY_SMTP_PROVIDERS

	// Public app URLs used in email links.
	AppBaseURL string // GATEWAY_APP_BASE_URL — e.g. "https://app.example.com"

	// How long an email-verification or password-reset token is valid for.
	EmailTokenExpirySeconds int // GATEWAY_EMAIL_TOKEN_EXPIRY_SECONDS (default 86400)

	// How long a tenant-membership invitation is valid for before it must be
	// reissued. Longer than an email token because joining a team is a less
	// time-sensitive action than a password reset.
	TenantInvitationExpirySeconds int // GATEWAY_TENANT_INVITATION_EXPIRY_SECONDS (default 604800 = 7 days)

	// Per-recipient cooldown between transactional email sends. Defeats
	// inbox-bombing via repeated unauthenticated RequestPasswordReset /
	// SendEmailVerification calls. In-memory per replica.
	EmailSendCooldownSeconds int // GATEWAY_EMAIL_SEND_COOLDOWN_SECONDS (default 60)

	// Per-email cooldown on PasswordSignup. Throttled signups return
	// the same anti-enumeration decoy as a duplicate-email signup so the
	// endpoint cannot be used to probe for which addresses are
	// rate-limited (which would itself reveal recent attempts).
	// Complements the per-IP rate limit at the middleware layer.
	SignupEmailCooldownSeconds int // GATEWAY_SIGNUP_EMAIL_COOLDOWN_SECONDS (default 60)

	// Audit log queue depth for the async flusher. Drops happen if the
	// auth hot path produces events faster than EntDB can absorb them.
	// Surface via audit.Logger.DroppedCount() on a metric.
	AuditQueueSize int // GATEWAY_AUDIT_QUEUE_SIZE (default 4096)

	// Maximum HTTP request body size in bytes, enforced via
	// http.MaxBytesHandler so a slow-POST / oversize-payload attacker
	// can't exhaust memory. Default 1 MiB — auth RPC bodies are tiny.
	HTTPMaxBodyBytes int64 // GATEWAY_HTTP_MAX_BODY_BYTES (default 1048576)

	// Trusted proxies: comma-separated list of CIDRs whose
	// X-Forwarded-For headers the service will honour. Anything outside
	// these ranges is treated as an untrusted client and its forwarded
	// headers are ignored — TCP peer IP is used instead.
	TrustedProxies string // GATEWAY_TRUSTED_PROXIES (default "10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.1/32,::1/128")

	// Rate-limit configuration. The in-memory token bucket is keyed by
	// client IP. quotas are requests-per-window per IP. Set to 0 to
	// disable the per-endpoint limiter.
	RateLimitWindowSeconds     int // GATEWAY_RATE_LIMIT_WINDOW_SECONDS (default 60)
	RateLimitSignupPerIP       int // GATEWAY_RATE_LIMIT_SIGNUP_PER_IP (default 10/min)
	RateLimitLoginPerIP        int // GATEWAY_RATE_LIMIT_LOGIN_PER_IP (default 30/min)
	RateLimitResetPerIP        int // GATEWAY_RATE_LIMIT_RESET_PER_IP (default 5/min)
	RateLimitVerifyPerIP       int // GATEWAY_RATE_LIMIT_VERIFY_PER_IP (default 20/min)
	RateLimitPasswordlessPerIP int // GATEWAY_RATE_LIMIT_PASSWORDLESS_PER_IP (default 5/min) — RequestEmailLoginCode + RequestMagicLink
	RateLimitPhonePerIP        int // GATEWAY_RATE_LIMIT_PHONE_PER_IP (default 5/min) — RequestPhoneVerification
	RateLimitBootstrapPerIP    int // GATEWAY_RATE_LIMIT_BOOTSTRAP_PER_IP (default 5/min) — CreateFirstPlatformAdmin

	// Postgres (alternate persistence driver). When PostgresDSN is set
	// the application bootstrapper may prefer the Postgres-backed
	// repository over EntDB; the actual driver selection lives in the
	// internal/repo package.
	//
	//   GATEWAY_POSTGRES_DSN          e.g. "postgres://user:pass@host:5432/identity?sslmode=disable"
	//   GATEWAY_POSTGRES_MAX_CONNS    pool size, default 25
	//   GATEWAY_POSTGRES_AUTO_MIGRATE run pending migrations on connect, default false
	//                                 (production: run migrations out-of-band as a
	//                                  separate Job; setting this true on a rolling
	//                                  deploy can race multiple replicas).
	PostgresDSN         string
	PostgresMaxConns    int
	PostgresAutoMigrate bool

	// OTel exports OpenTelemetry traces to a deployer-supplied OTLP
	// collector. Default off so a deployer who has no collector pays
	// zero cost — when disabled the no-op tracer is installed and the
	// otelconnect interceptor is omitted from the handler chain.
	//
	//   GATEWAY_OTEL_ENABLED            true|false (default false)
	//   GATEWAY_OTEL_EXPORTER_ENDPOINT  host:port — required when enabled
	//   GATEWAY_OTEL_EXPORTER_PROTOCOL  grpc|http (default grpc)
	//   GATEWAY_OTEL_SAMPLE_RATIO       0.0–1.0 (default 0.1)
	//   GATEWAY_OTEL_DEPLOYMENT_ENV     deployment.environment.name (default "")
	//   GATEWAY_OTEL_SERVICE_VERSION    overrides build version baked into the binary
	OTelEnabled          bool
	OTelExporterEndpoint string
	OTelExporterProtocol string
	OTelSampleRatio      float64
	OTelDeploymentEnv    string
	OTelServiceVersion   string

	// Sweeper (#94). A background goroutine periodically deletes
	// expired-but-uncollected rows from five ephemeral tables
	// (WebAuthn challenges, email-verification / password-reset /
	// email-change tokens, login challenges). Without GC these
	// tables grow unboundedly with the abandoned-flow rate.
	//
	//   GATEWAY_SWEEPER_INTERVAL_SECONDS  tick interval; 0 disables sweeping
	//                                     entirely (useful for tests and for
	//                                     deployers who run their own GC).
	//   GATEWAY_SWEEPER_BATCH_SIZE        per-table per-tick deletion cap.
	//   GATEWAY_SWEEPER_GRACE_SECONDS     additional grace past expires_at
	//                                     before a row is eligible to delete;
	//                                     covers in-flight flows that just
	//                                     consumed the token.
	SweeperIntervalSeconds int
	SweeperBatchSize       int
	SweeperGraceSeconds    int
}

Config holds all identity service configuration.

func Load

func Load() *Config

Load reads configuration from environment variables with GATEWAY_ prefix, falling back to sensible defaults for local development.

func (*Config) DefaultPrimaryAuthDomain added in v0.17.0

func (c *Config) DefaultPrimaryAuthDomain() string

DefaultPrimaryAuthDomain returns the default project's primary serving hostname — the first entry of DefaultProjectAuthDomainList — or "" when none is configured.

func (*Config) DefaultProjectAuthDomainList added in v0.17.0

func (c *Config) DefaultProjectAuthDomainList() []string

DefaultProjectAuthDomainList returns the configured default-project auth domains, lower-cased and de-duplicated, in order — the first entry is the primary. Blank entries are dropped; an empty config yields nil.

func (*Config) EmailServiceAddress

func (c *Config) EmailServiceAddress() string

EmailServiceAddress returns the host:port for the email service.

func (*Config) IsPublicEmailDomain added in v0.17.0

func (c *Config) IsPublicEmailDomain(emailOrDomain string) bool

IsPublicEmailDomain reports whether emailOrDomain belongs to a public / consumer email provider — a domain a Tenant must never be auto-formed from. The input may be a full address (the part after the last '@' is used) or a bare domain; it is lower-cased, trimmed, stripped of a trailing FQDN dot, and punycode-canonicalised before the built-in set and GATEWAY_PUBLIC_EMAIL_DOMAINS are consulted, so an IDN homograph cannot slip past the check.

func (*Config) JWTExpiry

func (c *Config) JWTExpiry() time.Duration

JWTExpiry returns the JWT expiry as a time.Duration.

func (*Config) PasswordResetExpiry

func (c *Config) PasswordResetExpiry() time.Duration

PasswordResetExpiry returns the password reset expiry as a time.Duration.

func (*Config) ProjectResolutionCacheTTL added in v1.2.0

func (c *Config) ProjectResolutionCacheTTL() time.Duration

ProjectResolutionCacheTTL returns the configured project-resolution cache TTL as a time.Duration. 0 means disabled (resolve on every request).

func (*Config) RefreshExpiry

func (c *Config) RefreshExpiry() time.Duration

RefreshExpiry returns the refresh token expiry as a time.Duration.

func (*Config) SessionCacheTTL added in v0.8.0

func (c *Config) SessionCacheTTL() time.Duration

SessionCacheTTL returns the configured cache TTL as a time.Duration. 0 means strict mode (read on every request).

func (*Config) Validate added in v0.8.0

func (c *Config) Validate() error

Validate enforces invariants that are too complex to express as per-field defaults: most importantly the `mode=ttl` access-token TTL ceiling. The binary calls this at startup; tests pin their configs through the same path so misuse surfaces immediately rather than as a silent revocation-window gap.

Why a method rather than running inside Load(): tests build *Config values directly (without going through Load) and a silent failure mode there would re-introduce the bug this function prevents. Callers that synthesise a Config must invoke Validate before handing it to app.New.

type RevocationMode added in v0.8.0

type RevocationMode string

RevocationMode names the two refresh-token revocation models the service supports. See the Config.RevocationMode comment for the semantics; the two-mode contract is in docs/IDENTITY.md decision log §6.

const (
	// RevocationModeTTL keeps the existing zero-cost hot path.
	// DeleteRefreshTokensForUser deletes refresh tokens; in-flight
	// access tokens stay valid until natural JWT expiry. The default.
	RevocationModeTTL RevocationMode = "ttl"

	// RevocationModeSession mints access tokens with an `sid` claim
	// referencing a Session row. The verification middleware reads
	// that row (via an in-process cache) and rejects the request when
	// the session is revoked.
	RevocationModeSession RevocationMode = "session"

	// RevocationModeTTLAccessTokenCap is the maximum access-token TTL
	// (seconds) compatible with the `ttl` revocation model. A deployer
	// who needs a longer-lived access token must switch to
	// `RevocationModeSession`, where cache TTL bounds the revocation
	// latency.
	RevocationModeTTLAccessTokenCap = 900
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL