auth

package
v0.0.0-...-ff81b08 Latest Latest
Warning

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

Go to latest
Published: May 12, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

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

Constants

This section is empty.

Variables

This section is empty.

Functions

func ContextWithClaims

func ContextWithClaims(ctx context.Context, claims *Claims) context.Context

ContextWithClaims returns a context with the given claims attached.

func ContextWithKEK

func ContextWithKEK(ctx context.Context, kek []byte) context.Context

ContextWithKEK returns a new context with the KEK attached.

func GenerateRefreshToken

func GenerateRefreshToken() (raw string, hash string, err error)

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 HashToken

func HashToken(token string) string

HashToken returns the hex-encoded SHA-256 hash of a token string.

func KEKFromContext

func KEKFromContext(ctx context.Context) []byte

KEKFromContext returns the KEK stored in the context by the KEK session middleware, or nil if no KEK session is active.

func Middleware

func Middleware(issuer *TokenIssuer, skipPaths map[string]bool) func(http.Handler) http.Handler

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

func ClaimsFromContext(ctx context.Context) *Claims

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 NewHandler

func NewHandler(cfg HandlerConfig) *Handler

NewHandler creates an auth handler.

func (*Handler) RegisterRoutes

func (h *Handler) RegisterRoutes(mux *http.ServeMux)

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

func NewLogMailer(log *slog.Logger) *LogMailer

NewLogMailer returns a mailer that writes to the log.

func (*LogMailer) SendVerificationCode

func (m *LogMailer) SendVerificationCode(_ context.Context, to string, code string) error

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

func (m *ResendMailer) SendVerificationCode(ctx context.Context, to string, code string) error

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 (e *StoreEnforcer) IsEmailDomainAllowed(ctx context.Context, enterpriseID string, email string) (bool, error)

func (*StoreEnforcer) IsProviderAllowed

func (e *StoreEnforcer) IsProviderAllowed(ctx context.Context, enterpriseID string, provider string) (bool, error)

func (*StoreEnforcer) IsSSORequired

func (e *StoreEnforcer) IsSSORequired(ctx context.Context, enterpriseID string) (bool, error)

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.

func (*TokenIssuer) Issue

func (ti *TokenIssuer) Issue(userID, enterpriseID, email, role string) (string, error)

Issue creates a signed JWT for the given user.

func (*TokenIssuer) Validate

func (ti *TokenIssuer) Validate(tokenString string) (*Claims, error)

Validate parses and validates a JWT, returning the claims.

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.

Jump to

Keyboard shortcuts

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