Documentation
¶
Overview ¶
Package auth defines the SPI for authentication providers.
An AuthProvider bridges the control plane to an external identity provider — Google OAuth, Okta OIDC, a generic SAML 2.0 IdP, etc. When a user initiates login, the control plane selects the appropriate provider and delegates the authentication flow.
Each provider implementation handles one external identity system. The SPI is intentionally narrow: providers generate an authorization URL and exchange a callback for an identity. Session management and JWT issuance happen in the control plane after the provider returns.
The Enforcer interface checks enterprise-level SSO policies — whether a provider is allowed, whether SSO is required, and whether an email domain is permitted. These checks run after the provider returns an identity but before the user is granted a session.
Index ¶
- func ContextWithClaims(ctx context.Context, claims *Claims) context.Context
- func ContextWithKEK(ctx context.Context, kek []byte) context.Context
- func GenerateRefreshToken() (raw string, hash string, err error)
- func HashToken(token string) string
- func KEKFromContext(ctx context.Context) []byte
- func Middleware(issuer *TokenIssuer, skipPaths map[string]bool) func(http.Handler) http.Handler
- func MiddlewareWithConfig(issuer *TokenIssuer, cfg MiddlewareConfig) func(http.Handler) http.Handler
- type AuthProvider
- type AuthorizationResult
- type CallbackRequest
- type Claims
- type Enforcer
- type Handler
- type HandlerConfig
- type Identity
- type KEKSessionCache
- func (c *KEKSessionCache) Clear(sessionID string)
- func (c *KEKSessionCache) EvictExpired()
- func (c *KEKSessionCache) ExpiresAt(sessionID string) *time.Time
- func (c *KEKSessionCache) Get(sessionID string) []byte
- func (c *KEKSessionCache) Len() int
- func (c *KEKSessionCache) Set(sessionID string, kek []byte)
- func (c *KEKSessionCache) TTL() time.Duration
- type LogMailer
- type Mailer
- type MiddlewareConfig
- type Registry
- type ResendMailer
- type ResendMailerConfig
- type StoreEnforcer
- func (e *StoreEnforcer) IsEmailDomainAllowed(ctx context.Context, enterpriseID string, email string) (bool, error)
- func (e *StoreEnforcer) IsProviderAllowed(ctx context.Context, enterpriseID string, provider string) (bool, error)
- func (e *StoreEnforcer) IsSSORequired(ctx context.Context, enterpriseID string) (bool, error)
- type TokenIssuer
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ContextWithClaims ¶
ContextWithClaims returns a context with the given claims attached.
func ContextWithKEK ¶
ContextWithKEK returns a new context with the KEK attached.
func GenerateRefreshToken ¶
GenerateRefreshToken creates a cryptographically random refresh token and returns both the raw token (to send to the client) and its SHA-256 hash (to store in the database).
func KEKFromContext ¶
KEKFromContext returns the KEK stored in the context by the KEK session middleware, or nil if no KEK session is active.
func Middleware ¶
Middleware returns HTTP middleware that validates Bearer JWTs and injects claims into the request context. Requests to paths in skipPaths bypass authentication (e.g. health checks, auth callbacks).
func MiddlewareWithConfig ¶
func MiddlewareWithConfig(issuer *TokenIssuer, cfg MiddlewareConfig) func(http.Handler) http.Handler
MiddlewareWithConfig returns HTTP middleware using the full MiddlewareConfig.
Types ¶
type AuthProvider ¶
type AuthProvider interface {
// Provider returns the provider identifier (e.g. "google", "github").
Provider() string
// AuthorizationURL returns the authorization result containing the URL to
// redirect the user to for login. The state parameter is an opaque CSRF
// token that must be echoed back in the callback. redirectURL is the
// callback URL the provider should redirect to after authentication.
//
// Providers that require PKCE can return an ExtraState in the result (e.g.
// the code_verifier); the handler will persist it across the redirect and
// supply it back in CallbackRequest.ExtraState.
AuthorizationURL(ctx context.Context, state, redirectURL string) (*AuthorizationResult, error)
// HandleCallback exchanges the authorization code from the IdP callback
// for a resolved user identity.
HandleCallback(ctx context.Context, req CallbackRequest) (*Identity, error)
}
AuthProvider authenticates users via an external identity provider.
type AuthorizationResult ¶
type AuthorizationResult struct {
// URL is the provider's authorization endpoint URL to redirect to.
URL string
// ExtraState is opaque provider data that the handler persists across the
// OAuth redirect (e.g. a PKCE code_verifier). It is returned to the
// provider via CallbackRequest.ExtraState. Empty means nothing to store.
ExtraState string
}
AuthorizationResult is returned by AuthProvider.AuthorizationURL.
type CallbackRequest ¶
type CallbackRequest struct {
Code string
State string
RedirectURL string // must match the redirectURL used in AuthorizationURL
ExtraState string // opaque data from AuthorizationResult, if any
}
CallbackRequest contains the data from the OAuth/OIDC callback.
type Claims ¶
type Claims struct {
jwt.RegisteredClaims
EnterpriseID string `json:"ent_id"`
Email string `json:"email"`
Role string `json:"role"`
}
Claims are the JWT claims issued by Aileron after authentication.
func ClaimsFromContext ¶
ClaimsFromContext returns the authenticated claims from the request context, or nil if the request is not authenticated.
type Enforcer ¶
type Enforcer interface {
// IsProviderAllowed reports whether the given auth provider is permitted
// for the enterprise. Returns true if the enterprise has no provider
// restrictions configured.
IsProviderAllowed(ctx context.Context, enterpriseID string, provider string) (bool, error)
// IsSSORequired reports whether the enterprise requires all users to
// authenticate via a configured SSO provider.
IsSSORequired(ctx context.Context, enterpriseID string) (bool, error)
// IsEmailDomainAllowed reports whether the user's email domain is
// permitted for the enterprise. Returns true if the enterprise has no
// domain restrictions configured.
IsEmailDomainAllowed(ctx context.Context, enterpriseID string, email string) (bool, error)
}
Enforcer checks enterprise-level SSO policies.
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler serves the authentication HTTP routes.
func (*Handler) RegisterRoutes ¶
RegisterRoutes registers auth routes on the given mux.
type HandlerConfig ¶
type HandlerConfig struct {
Log *slog.Logger
Registry *Registry
Enforcer Enforcer
Issuer *TokenIssuer
Users store.UserStore
UserAuthProviders store.UserAuthProviderStore
Enterprises store.EnterpriseStore
Sessions store.SessionStore
VerificationCodes store.VerificationCodeStore
Mailer Mailer
NewID func() string
UIBaseURL string // UI origin, e.g. "http://localhost:5173" or "/"
AutoVerifyEmail bool // skip email verification (dev/CI only)
RefreshTTL time.Duration // e.g. 7 * 24 * time.Hour
VerificationTTL time.Duration // e.g. 15 * time.Minute
BcryptCost int // bcrypt cost (default 12; use bcrypt.MinCost in tests)
}
HandlerConfig configures the auth handler.
type Identity ¶
type Identity struct {
// Subject is the provider-specific unique user identifier.
Subject string
Email string
DisplayName string
AvatarURL string
Provider string
// RawClaims carries the full set of claims from the IdP for extensibility.
RawClaims map[string]any
}
Identity is the authenticated user identity returned by a provider.
type KEKSessionCache ¶
type KEKSessionCache struct {
// contains filtered or unexported fields
}
KEKSessionCache holds per-session KEKs in memory with a TTL. When a user verifies their passphrase, the derived KEK is stored here so that subsequent requests in the same session can decrypt vault secrets without re-prompting for the passphrase.
The cache zeros KEK bytes on eviction to minimize the window during which plaintext key material exists in process memory.
func NewKEKSessionCache ¶
func NewKEKSessionCache(ttl time.Duration) *KEKSessionCache
NewKEKSessionCache creates a new cache with the given default TTL.
func (*KEKSessionCache) Clear ¶
func (c *KEKSessionCache) Clear(sessionID string)
Clear removes and zeros the KEK for the given session.
func (*KEKSessionCache) EvictExpired ¶
func (c *KEKSessionCache) EvictExpired()
EvictExpired removes all expired entries, zeroing their KEK bytes. Call this periodically from a background goroutine.
func (*KEKSessionCache) ExpiresAt ¶
func (c *KEKSessionCache) ExpiresAt(sessionID string) *time.Time
ExpiresAt returns the expiry time for the given session, or nil if the session is not found or has expired. Unlike Get, it does not return the KEK bytes — safe for status checks.
func (*KEKSessionCache) Get ¶
func (c *KEKSessionCache) Get(sessionID string) []byte
Get returns a copy of the KEK for the given session, or nil if not found or expired. Expired entries are evicted on access.
func (*KEKSessionCache) Len ¶
func (c *KEKSessionCache) Len() int
Len returns the number of entries in the cache (for testing).
func (*KEKSessionCache) Set ¶
func (c *KEKSessionCache) Set(sessionID string, kek []byte)
Set stores a KEK for the given session ID. The KEK bytes are copied so the caller can safely zero their copy.
func (*KEKSessionCache) TTL ¶
func (c *KEKSessionCache) TTL() time.Duration
TTL returns the configured session TTL.
type LogMailer ¶
type LogMailer struct {
// contains filtered or unexported fields
}
LogMailer is a development Mailer that logs emails instead of sending them.
func NewLogMailer ¶
NewLogMailer returns a mailer that writes to the log.
type Mailer ¶
type Mailer interface {
// SendVerificationCode sends an email with the verification code.
SendVerificationCode(ctx context.Context, to string, code string) error
}
Mailer sends transactional emails. Implementations may delegate to Resend, AWS SES, SendGrid, SMTP, etc. The built-in LogMailer prints to the server log for development.
type MiddlewareConfig ¶
type MiddlewareConfig struct {
// SkipPaths are paths that bypass authentication entirely.
SkipPaths map[string]bool
// OptionalAuthPrefixes are path prefixes where authentication is attempted
// but not required. If credentials are present and valid, claims are
// injected into the context. If credentials are absent, the request
// proceeds without claims. This allows handlers to support both
// authenticated and unauthenticated flows on the same endpoint.
OptionalAuthPrefixes []string
}
MiddlewareConfig holds the configuration for the auth middleware.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry holds registered auth providers and resolves the correct one for a given provider name. It is safe for concurrent use.
func NewRegistry ¶
func NewRegistry() *Registry
NewRegistry returns an empty auth provider registry.
func (*Registry) Get ¶
func (r *Registry) Get(name string) (AuthProvider, bool)
Get returns the provider for the given name, or nil if not registered.
func (*Registry) Register ¶
func (r *Registry) Register(p AuthProvider)
Register adds an auth provider to the registry.
type ResendMailer ¶
type ResendMailer struct {
// contains filtered or unexported fields
}
ResendMailer sends transactional emails via the Resend REST API.
func NewResendMailer ¶
func NewResendMailer(cfg ResendMailerConfig) *ResendMailer
NewResendMailer returns a Mailer that sends emails via Resend.
func (*ResendMailer) SendVerificationCode ¶
SendVerificationCode sends a verification code email via the Resend API.
type ResendMailerConfig ¶
type ResendMailerConfig struct {
// APIKey is the Resend API key. Required.
// Env: RESEND_API_KEY
APIKey string
// From is the sender email address shown to recipients.
// Env: MAIL_FROM (default: "noreply@withaileron.ai")
From string
// HTTPClient is an optional custom HTTP client. Defaults to http.DefaultClient.
HTTPClient *http.Client
}
ResendMailerConfig holds configuration for constructing a ResendMailer.
type StoreEnforcer ¶
type StoreEnforcer struct {
// contains filtered or unexported fields
}
StoreEnforcer implements the Enforcer interface using the enterprise store.
func NewStoreEnforcer ¶
func NewStoreEnforcer(enterprises store.EnterpriseStore) *StoreEnforcer
NewStoreEnforcer creates an enforcer backed by the enterprise store.
func (*StoreEnforcer) IsEmailDomainAllowed ¶
func (*StoreEnforcer) IsProviderAllowed ¶
func (*StoreEnforcer) IsSSORequired ¶
type TokenIssuer ¶
type TokenIssuer struct {
// contains filtered or unexported fields
}
TokenIssuer creates and validates JWTs.
func NewTokenIssuer ¶
func NewTokenIssuer(signingKey []byte, issuer string, accessTTL time.Duration) *TokenIssuer
NewTokenIssuer creates a token issuer with the given HMAC signing key.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package github implements the AuthProvider SPI for GitHub OAuth 2.0.
|
Package github implements the AuthProvider SPI for GitHub OAuth 2.0. |
|
Package google implements the AuthProvider SPI for Google OAuth 2.0.
|
Package google implements the AuthProvider SPI for Google OAuth 2.0. |