Documentation
¶
Index ¶
- Constants
- Variables
- func AuthorizeIdentity(cfg OIDCConfig, id *Identity) error
- func ClearLoginStateCookie(w http.ResponseWriter, opts CookieOptions)
- func ClearSessionCookie(w http.ResponseWriter, opts CookieOptions)
- func GenerateSecureToken(length int) (rawToken string, tokenHash string, err error)
- func HashToken(rawToken string) string
- func IsAPIKey(value string) bool
- func LookupAPIKey(ctx context.Context, store APIKeyStore, raw string) (*db.APIKey, error)
- func NewAPIKey(name, createdBy string, expiresAt *time.Time) (raw string, key *db.APIKey, err error)
- func NewRandomToken() (string, error)
- func SetLoginStateCookie(w http.ResponseWriter, token string, opts CookieOptions)
- func SetSessionCookie(w http.ResponseWriter, token string, expires time.Time, opts CookieOptions)
- func WithAgent(ctx context.Context, c *AgentClaims) context.Context
- func WithPrincipal(ctx context.Context, p *Principal) context.Context
- type APIKeyStore
- type AdminAuth
- type AgentAuth
- type AgentClaims
- type AgentStateStore
- type AgentTokenClaims
- type AgentVerifier
- type BackupTicketClaims
- type CookieOptions
- type Identity
- type LoginStateClaims
- type OIDC
- type OIDCConfig
- type Principal
- type PrincipalKind
- type SessionClaims
- type TokenManager
- func (tm *TokenManager) CreateAgentToken(agentID uuid.UUID, taskQueue string, version int, ttl time.Duration) (string, time.Time, error)
- func (tm *TokenManager) CreateBackupTicket(claims BackupTicketClaims, ttl time.Duration) (string, error)
- func (tm *TokenManager) CreateLoginState(state, nonce, next string) (string, error)
- func (tm *TokenManager) CreateSession(id *Identity, ttl time.Duration) (string, time.Time, error)
- func (tm *TokenManager) CreateWorkerToken(agentID uuid.UUID, taskQueue string, version int, ttl time.Duration) (string, time.Time, error)
- func (tm *TokenManager) ValidateAgentToken(tokenString string) (*AgentTokenClaims, error)
- func (tm *TokenManager) ValidateBackupTicket(ticketString string) (*BackupTicketClaims, error)
- func (tm *TokenManager) ValidateLoginState(tokenString string) (*LoginStateClaims, error)
- func (tm *TokenManager) ValidateSession(tokenString string) (*SessionClaims, error)
Constants ¶
const ( CSRFHeader = "X-Requested-With" CSRFHeaderValue = "fallbck" )
CSRFHeader must be present on cookie-authenticated state-changing requests. Browsers cannot add custom headers cross-site, so its presence proves same-origin JS.
const ( // SessionCookieName carries the admin browser session JWT SessionCookieName = "fallbck_session" // LoginStateCookieName carries the OIDC state/nonce between login redirect and callback LoginStateCookieName = "fallbck_login" DefaultSessionTTL = 12 * time.Hour )
const ( AudienceBackupTicket = "fallbck-ticket" AudienceAgent = "fallbck-agent" AudienceSession = "fallbck-session" AudienceLoginState = "fallbck-login" )
Audiences separate the JWT types that share the server signing secret so that a token of one kind can never be presented as another.
const APIKeyPrefix = "fbk_"
APIKeyPrefix makes keys recognisable in logs and secret scanners
const DefaultAgentTokenTTL = 365 * 24 * time.Hour
DefaultAgentTokenTTL is the lifetime of an agent bearer token unless configured otherwise
const Issuer = "fallbck-server"
Issuer is the `iss` claim on every JWT minted by the server
Variables ¶
var ( ErrInvalidTicket = errors.New("invalid or expired backup ticket") ErrInvalidToken = errors.New("invalid or expired token") )
var ErrAgentRevoked = errors.New("agent has been revoked")
ErrAgentRevoked is returned when an agent has been deleted or revoked
var ErrInvalidAPIKey = errors.New("invalid, expired or revoked API key")
ErrInvalidAPIKey is returned for unknown, expired or revoked API keys
var ErrNotAuthorized = errors.New("identity is not authorized to access this server")
ErrNotAuthorized is returned when an authenticated identity is not permitted to administer
Functions ¶
func AuthorizeIdentity ¶
func AuthorizeIdentity(cfg OIDCConfig, id *Identity) error
AuthorizeIdentity applies the allow-lists of cfg to id
func ClearLoginStateCookie ¶
func ClearLoginStateCookie(w http.ResponseWriter, opts CookieOptions)
ClearLoginStateCookie removes the OIDC state cookie
func ClearSessionCookie ¶
func ClearSessionCookie(w http.ResponseWriter, opts CookieOptions)
ClearSessionCookie expires the session cookie
func GenerateSecureToken ¶
GenerateSecureToken creates a cryptographically secure random token string and its SHA256 hash
func LookupAPIKey ¶
LookupAPIKey resolves a raw key to its record, enforcing expiry and revocation
func NewAPIKey ¶
func NewAPIKey(name, createdBy string, expiresAt *time.Time) (raw string, key *db.APIKey, err error)
NewAPIKey generates a new raw key and its persisted record. The raw key is returned exactly once; only its hash is stored.
func NewRandomToken ¶
NewRandomToken returns a URL-safe random string for OIDC state and nonce values
func SetLoginStateCookie ¶
func SetLoginStateCookie(w http.ResponseWriter, token string, opts CookieOptions)
SetLoginStateCookie writes the short-lived OIDC state cookie
func SetSessionCookie ¶
func SetSessionCookie(w http.ResponseWriter, token string, expires time.Time, opts CookieOptions)
SetSessionCookie writes the session cookie
Types ¶
type APIKeyStore ¶
type APIKeyStore interface {
CreateAPIKey(ctx context.Context, key *db.APIKey) error
GetAPIKeyByHash(ctx context.Context, hash string) (*db.APIKey, error)
TouchAPIKey(ctx context.Context, id uuid.UUID) error
}
APIKeyStore provides API key persistence (implemented by *db.DB)
type AdminAuth ¶
type AdminAuth struct {
TM *TokenManager
Keys APIKeyStore
// Insecure disables authentication entirely (development only)
Insecure bool
// LoginPath is where unauthenticated browser requests are redirected
LoginPath string
}
AdminAuth authenticates admin requests via session cookie or API key
func NewAdminAuth ¶
func NewAdminAuth(tm *TokenManager, keys APIKeyStore, insecure bool) *AdminAuth
NewAdminAuth constructs the admin middleware
func (*AdminAuth) Authenticate ¶
Authenticate resolves the principal for a request without enforcing anything
type AgentAuth ¶
type AgentAuth struct {
Verifier *AgentVerifier
}
AgentAuth authenticates agent requests with the agent bearer token
type AgentClaims ¶
type AgentClaims struct {
AgentID uuid.UUID
TaskQueue string
Version int
Worker bool
ExpiresAt time.Time
}
AgentClaims is the authenticated identity of an agent, attached to request contexts
func AgentFrom ¶
func AgentFrom(ctx context.Context) *AgentClaims
AgentFrom returns the authenticated agent on the context, if any
type AgentStateStore ¶
type AgentStateStore interface {
GetAgentAuthState(ctx context.Context, id uuid.UUID) (*db.AgentAuthState, error)
}
AgentStateStore provides the persisted revocation state of agents (implemented by *db.DB)
type AgentTokenClaims ¶
type AgentTokenClaims struct {
TaskQueue string `json:"tq"`
Version int `json:"ver"`
// Worker marks the short-lived secondary token of a kubernetes run's worker pods;
// it cannot be rotated into a long-lived one
Worker bool `json:"wrk,omitempty"`
jwt.RegisteredClaims
}
AgentTokenClaims is the JWT payload of an agent bearer token. `sub` is the agent ID.
type AgentVerifier ¶
type AgentVerifier struct {
// contains filtered or unexported fields
}
AgentVerifier validates agent bearer tokens against both the signature and the database state (agent exists, not revoked, token version current). Database lookups are cached per agent for a short time so every RPC does not hit Postgres.
func NewAgentVerifier ¶
func NewAgentVerifier(tm *TokenManager, store AgentStateStore, cacheTTL time.Duration) *AgentVerifier
NewAgentVerifier creates a verifier. cacheTTL bounds how long a revocation takes to propagate.
func (*AgentVerifier) Invalidate ¶
func (v *AgentVerifier) Invalidate(agentID uuid.UUID)
Invalidate drops the cached state for an agent (call after revocation for immediate effect)
func (*AgentVerifier) Verify ¶
func (v *AgentVerifier) Verify(ctx context.Context, bearer string) (*AgentClaims, error)
Verify validates a bearer token value (with or without the "Bearer " prefix)
type BackupTicketClaims ¶
type BackupTicketClaims struct {
JobID uuid.UUID `json:"job_id"`
AgentID uuid.UUID `json:"agent_id"`
TargetID uuid.UUID `json:"target_id"`
Datastore string `json:"datastore"`
Namespace string `json:"namespace"`
BackupType string `json:"backup_type"` // e.g. "host"
BackupID string `json:"backup_id"` // e.g. "agent-123"
BackupTime int64 `json:"backup_time"` // unix timestamp
// Issued is when the run's first ticket was minted; refreshes and sub-tickets carry
// it over so a run cannot keep itself alive forever
Issued int64 `json:"issued,omitempty"`
jwt.RegisteredClaims
}
BackupTicketClaims defines the claims embedded in a short-lived backup session ticket
type CookieOptions ¶
type CookieOptions struct {
// Secure marks cookies as HTTPS-only; enable whenever PublicURL is https
Secure bool
}
CookieOptions controls the attributes of cookies set by the server
type Identity ¶
type Identity struct {
Subject string
Email string
Name string
Groups []string
// EmailUnverified is set when the IdP says email_verified=false; allowed_emails
// never matches such an identity (a missing claim is taken as verified)
EmailUnverified bool
}
Identity is an authenticated admin resolved from an OIDC ID token
type LoginStateClaims ¶
type LoginStateClaims struct {
State string `json:"state"`
Nonce string `json:"nonce"`
Next string `json:"next,omitempty"`
jwt.RegisteredClaims
}
LoginStateClaims protects the OIDC round trip: state must match the callback query, nonce must match the ID token, next is where to send the user afterwards.
type OIDC ¶
type OIDC struct {
// contains filtered or unexported fields
}
OIDC performs the authorization-code login flow against the configured provider
func NewOIDC ¶
NewOIDC discovers the provider and prepares the OAuth2 client. redirectURL must be PublicURL + "/auth/callback" and registered with the provider.
func (*OIDC) AuthCodeURL ¶
AuthCodeURL builds the provider login URL for a state/nonce pair
type OIDCConfig ¶
type OIDCConfig = config.OIDCConfig
OIDCConfig is the OpenID Connect configuration (defined in pkg/config)
type Principal ¶
type Principal struct {
Kind PrincipalKind
Subject string
Email string
Name string
}
Principal is the authenticated admin identity attached to the request context
func PrincipalFrom ¶
PrincipalFrom returns the admin principal on the context, if any
type PrincipalKind ¶
type PrincipalKind string
PrincipalKind distinguishes how an admin request was authenticated
const ( PrincipalSession PrincipalKind = "session" PrincipalAPIKey PrincipalKind = "apikey" PrincipalInsecure PrincipalKind = "insecure" )
type SessionClaims ¶
type SessionClaims struct {
Email string `json:"email,omitempty"`
Name string `json:"name,omitempty"`
Groups []string `json:"groups,omitempty"`
jwt.RegisteredClaims
}
SessionClaims is the payload of an admin browser session. `sub` is the OIDC subject.
type TokenManager ¶
type TokenManager struct {
// contains filtered or unexported fields
}
TokenManager signs and validates every JWT the server issues (backup tickets, agent tokens, admin sessions, login state) with a single HS256 secret, separated by audience.
func NewTokenManager ¶
func NewTokenManager(secret string) *TokenManager
NewTokenManager creates a new TokenManager with a shared signing secret
func (*TokenManager) CreateAgentToken ¶
func (tm *TokenManager) CreateAgentToken(agentID uuid.UUID, taskQueue string, version int, ttl time.Duration) (string, time.Time, error)
CreateAgentToken mints a long-lived bearer token for an enrolled agent
func (*TokenManager) CreateBackupTicket ¶
func (tm *TokenManager) CreateBackupTicket(claims BackupTicketClaims, ttl time.Duration) (string, error)
CreateBackupTicket generates a signed JWT ticket valid for the specified duration (e.g. 2 hours)
func (*TokenManager) CreateLoginState ¶
func (tm *TokenManager) CreateLoginState(state, nonce, next string) (string, error)
CreateLoginState signs the OIDC state cookie payload
func (*TokenManager) CreateSession ¶
CreateSession mints a session token for an authenticated admin identity
func (*TokenManager) CreateWorkerToken ¶ added in v0.14.12
func (tm *TokenManager) CreateWorkerToken(agentID uuid.UUID, taskQueue string, version int, ttl time.Duration) (string, time.Time, error)
CreateWorkerToken mints a short-lived worker token (same agent identity, not rotatable)
func (*TokenManager) ValidateAgentToken ¶
func (tm *TokenManager) ValidateAgentToken(tokenString string) (*AgentTokenClaims, error)
ValidateAgentToken verifies the signature and claims of an agent token. It does NOT consult revocation state; use AgentVerifier for that.
func (*TokenManager) ValidateBackupTicket ¶
func (tm *TokenManager) ValidateBackupTicket(ticketString string) (*BackupTicketClaims, error)
ValidateBackupTicket parses and verifies a short-lived backup ticket
func (*TokenManager) ValidateLoginState ¶
func (tm *TokenManager) ValidateLoginState(tokenString string) (*LoginStateClaims, error)
ValidateLoginState verifies the OIDC state cookie payload
func (*TokenManager) ValidateSession ¶
func (tm *TokenManager) ValidateSession(tokenString string) (*SessionClaims, error)
ValidateSession verifies a session token