iam

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Aug 19, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DeviceTokenBytes is the number of random bytes for device tokens (256 bits)
	DeviceTokenBytes = 32

	// DeviceTokenPrefix identifies device trust tokens for secret scanning
	DeviceTokenPrefix = "hmdl_device_"

	// DeviceTrustDays is the default trust duration
	DeviceTrustDays = 30
)

Variables

AllScopes is the canonical list of every scope Heimdall defines. The seed migration must insert exactly these names; a test asserts the two agree.

View Source
var ErrAccountAlreadyVerified = errors.New("account has already been verified")
View Source
var ErrAccountIsInactive = errors.New("user account is not active")
View Source
var ErrAccountLocked = errors.New("account is temporarily locked due to too many failed login attempts")
View Source
var ErrAutoProvisioningDisabled = errors.New("automatic user provisioning is not enabled for this domain")
View Source
var ErrBackupCodeAlreadyUsed = errors.New("backup code has already been used")
View Source
var ErrDuplicateEmail = errors.New("email address is already registered")
View Source
var ErrEmailConflict = errors.New("email address conflicts with existing account")
View Source
var ErrEmailNotVerified = errors.New("email address not verified")
View Source
var ErrInvalidBackupCode = errors.New("invalid backup code")
View Source
var ErrInvalidChallengeToken = errors.New("invalid or expired challenge token")
View Source
var ErrInvalidCredentials = errors.New("invalid credentials")

Authentication errors

View Source
var ErrInvalidMFACode = errors.New("invalid MFA code")
View Source
var ErrInvalidOIDCState = errors.New("invalid oidc state parameter")
View Source
var ErrInvalidSetupToken = errors.New("invalid or expired setup token")
View Source
var ErrMFAAlreadyEnabled = errors.New("MFA is already enabled for this user")
View Source
var ErrMFACodeAlreadyUsed = errors.New("MFA code has already been used")
View Source
var ErrMFANotEnabled = errors.New("MFA is not enabled for this user")

MFA errors

View Source
var ErrMismatchedHash = argon2.ErrMismatchedHash
View Source
var ErrOIDCDiscoveryFailed = errors.New("failed to discover OIDC provider")

OIDC discovery and registration errors

View Source
var ErrOIDCIssuerMismatch = errors.New("OIDC issuer mismatch")
View Source
var ErrOIDCLinkAlreadyExists = errors.New("user already has this provider linked")
View Source
var ErrOIDCLinkNotFound = errors.New("oidc link not found")

OIDC flow errors

View Source
var ErrOIDCProviderAccountAlreadyLinked = errors.New("this provider account is already linked to another user")
View Source
var ErrOIDCProviderNotConfigured = errors.New("OAuth provider is not configured")
View Source
var ErrOIDCProviderNotFound = errors.New("oidc provider not found")
View Source
var ErrOIDCRegistrationFailed = errors.New("dynamic client registration failed")
View Source
var ErrOIDCSessionNotFound = errors.New("oidc session not found or expired")
View Source
var ErrPasswordResetTokenNotFound = errors.New("password reset token not found or expired")
View Source
var ErrPermissionNotFound = errors.New("permission not found")
View Source
var ErrProviderEmailNotVerified = errors.New("email not verified by OAuth provider")
View Source
var ErrRoleNotFound = errors.New("role not found")

RBAC errors

View Source
var ErrSSONotConfigured = errors.New("SSO is not configured for this domain")

Corporate SSO errors

View Source
var ErrSSORequired = errors.New("this email domain requires SSO login")
View Source
var ErrSessionNotFound = errors.New("session not found or expired")

Session management errors

View Source
var ErrSessionRevoked = errors.New("session has been revoked")
View Source
var ErrTokenReused = errors.New("refresh token reuse detected")
View Source
var ErrTrustedDeviceNotFound = errors.New("trusted device not found or expired")

Trusted device errors

View Source
var ErrUserNotFound = errors.New("user not found")
View Source
var ErrVerificationTokenNotFound = errors.New("verification token not found or expired")
View Source
var ErrWeakPassword = errors.New("password is too weak")

Functions

func OAuthCallbackURL

func OAuthCallbackURL(publicURL string) string

OAuthCallbackURL constructs the OAuth callback URL from frontend base URL

Types

type AuthService

type AuthService struct {
	PasswordService       passwordService
	PasswordChangeService passwordChangeService
	OIDCService           oidcAuthService
	UserService           userService
	MFAService            mfaVerificationService
	RBACService           rbacService
	JWTService            jwtService
	SessionService        sessionStorageService
	TrustedDeviceService  trustedDeviceService
	Logger                *slog.Logger
}

AuthService orchestrates authentication flows

func (*AuthService) AuthenticateWithMFA

func (s *AuthService) AuthenticateWithMFA(ctx context.Context, challengeToken, code string, trustDevice bool) (*SessionTokens, error)

AuthenticateWithMFA completes MFA challenge and issues final tokens

func (*AuthService) AuthenticateWithOIDC

func (s *AuthService) AuthenticateWithOIDC(ctx context.Context, state, code string) (*SessionTokens, error)

AuthenticateWithOIDC handles OAuth/OIDC callback

func (*AuthService) AuthenticateWithPassword

func (s *AuthService) AuthenticateWithPassword(ctx context.Context, email, password, deviceToken string) (*SessionTokens, error)

AuthenticateWithPassword handles password-based authentication

func (*AuthService) ChangePassword

func (s *AuthService) ChangePassword(ctx context.Context, userID uuid.UUID, oldPassword, newPassword string) error

ChangePassword orchestrates password change with security side effects. Revokes all trusted devices after password change.

func (*AuthService) CompleteRegistration

func (s *AuthService) CompleteRegistration(ctx context.Context, token, password string) (*SessionTokens, error)

CompleteRegistration handles email verification and auto-login

func (*AuthService) EnableRequiredMFA

func (s *AuthService) EnableRequiredMFA(ctx context.Context, setupToken, code string) (*SessionTokens, error)

EnableRequiredMFA validates the setup token, enables MFA, and returns a challenge token

func (*AuthService) HandleTokenReuse

func (s *AuthService) HandleTokenReuse(ctx context.Context, userID uuid.UUID)

HandleTokenReuse handles a detected token reuse attempt (potential theft). Revokes all trusted devices for the user as a security measure.

func (*AuthService) Logout

func (s *AuthService) Logout(ctx context.Context, refreshToken string) error

Logout revokes the session associated with the given refresh token

func (*AuthService) RefreshSession

func (s *AuthService) RefreshSession(ctx context.Context, refreshToken string) (*SessionTokens, error)

RefreshSession validates a refresh token, rotates it, and generates new session tokens. Token rotation: old token is revoked, new token is issued with same family_id. If a revoked token is reused, it's detected as theft and entire family is revoked.

func (*AuthService) SetupRequiredMFA

func (s *AuthService) SetupRequiredMFA(ctx context.Context, setupToken string) (*MFAEnrollment, error)

SetupRequiredMFA validates the setup token and initiates MFA enrollment

func (*AuthService) SignOutEverywhere

func (s *AuthService) SignOutEverywhere(ctx context.Context, userID uuid.UUID) error

SignOutEverywhere revokes all sessions and trusted devices for a user

type DirectPermission

type DirectPermission struct {
	PermissionID uuid.UUID
	Effect       sdk.PermissionEffect
}

DirectPermission represents input for setting direct user permissions

type EffectivePermission

type EffectivePermission struct {
	Permission *Permission
	Effect     sdk.PermissionEffect
}

EffectivePermission represents a user permission assignment

type JWTClaims

type JWTClaims = jwt.Claims

JWTClaims is an alias for jwt.Claims

type LoginAttemptsService

type LoginAttemptsService struct {
	DB     loginAttemptsDB
	Logger *slog.Logger
}

LoginAttemptsService handles login attempt tracking and account lockout logic

func (*LoginAttemptsService) IsAccountLocked

func (s *LoginAttemptsService) IsAccountLocked(ctx context.Context, email string) (bool, time.Time, error)

IsAccountLocked checks if an email is currently locked out and when the lock expires

func (*LoginAttemptsService) RecordFailedLogin

func (s *LoginAttemptsService) RecordFailedLogin(ctx context.Context, email string, userID *uuid.UUID, lastLoginAt *time.Time) error

RecordFailedLogin records a failed login attempt and calculates the appropriate lockout expiry

func (*LoginAttemptsService) RecordSuccessfulLogin

func (s *LoginAttemptsService) RecordSuccessfulLogin(ctx context.Context, userID uuid.UUID) error

RecordSuccessfulLogin clears failed login attempts for the user

type MFABackupCode

type MFABackupCode struct {
	ID       uuid.UUID
	UserID   uuid.UUID
	CodeHash string
	Used     bool
	UsedAt   *time.Time
}

MFABackupCode represents a one-time recovery code

type MFAEnrollment

type MFAEnrollment struct {
	Secret      string   // Base32 encoded secret
	QRCode      string   // data:image/png;base64,...
	BackupCodes []string // Plain text (shown once)
}

MFAEnrollment contains TOTP enrollment data

type MFAService

type MFAService struct {
	MFASettingsDB mfaSettingsDB
	BackupCodesDB mfaBackupCodesDB
	UsersDB       userDB
	Verifier      mfaVerifier
	Hasher        hasher
	Logger        *slog.Logger
}

MFAService manages multi-factor authentication

func (*MFAService) DisableMFA

func (s *MFAService) DisableMFA(ctx context.Context, userID uuid.UUID, password, code string) error

DisableMFA disables MFA for a user (requires password and TOTP/backup code)

func (*MFAService) EnableMFA

func (s *MFAService) EnableMFA(ctx context.Context, userID uuid.UUID, code string) error

EnableMFA validates MFA setup code and enables MFA

func (*MFAService) GetStatus

func (s *MFAService) GetStatus(ctx context.Context, userID uuid.UUID) (*MFAStatus, error)

GetStatus returns MFA status for a user (for UI display)

func (*MFAService) IsMFAEnabled

func (s *MFAService) IsMFAEnabled(ctx context.Context, userID uuid.UUID) (bool, error)

IsMFAEnabled returns whether MFA is enabled for a user

func (*MFAService) RegenerateBackupCodes

func (s *MFAService) RegenerateBackupCodes(ctx context.Context, userID uuid.UUID, password string) ([]string, error)

RegenerateBackupCodes generates new backup codes (requires password)

func (*MFAService) SetupMFA

func (s *MFAService) SetupMFA(ctx context.Context, userID uuid.UUID) (*MFAEnrollment, error)

SetupMFA initiates MFA setup by generating secret, QR code, and backup codes

func (*MFAService) VerifyCode

func (s *MFAService) VerifyCode(ctx context.Context, userID uuid.UUID, code string) error

VerifyCode verifies an MFA code (TOTP or backup code) for a user

type MFASettings

type MFASettings struct {
	UserID         uuid.UUID
	TOTPSecret     string
	LastUsedWindow *int64
	VerifiedAt     *time.Time
	LastUsedAt     *time.Time
}

MFASettings represents user's MFA configuration

type MFAStatus

type MFAStatus struct {
	VerifiedAt           *time.Time
	BackupCodesRemaining int
}

MFAStatus represents current MFA state for a user

type OIDCAuthService

type OIDCAuthService struct {
	OIDCProviderService oidcProviderLookup
	OIDCLinkDB          oidcLinkDB
	OIDCSessionDB       oidcSessionDB
	UserDB              userDB
	TenantsDB           tenantsDB
	SystemProviders     map[sdk.OIDCProviderType]OIDCProvider
	ProviderFactory     oidcProviderFactory
	PublicURL           string
	Logger              *slog.Logger
}

OIDCAuthService handles OAuth/SSO authentication flows

func (*OIDCAuthService) ProcessCallback

func (s *OIDCAuthService) ProcessCallback(ctx context.Context, state, code string) (*User, error)

ProcessCallback processes the OAuth callback and authenticates the user

func (*OIDCAuthService) StartOIDCLogin

func (s *OIDCAuthService) StartOIDCLogin(ctx context.Context, providerType sdk.OIDCProviderType) (string, error)

StartOIDCLogin initiates an OIDC login flow for individual OAuth registration

func (*OIDCAuthService) StartSSOLogin

func (s *OIDCAuthService) StartSSOLogin(ctx context.Context, email string) (string, error)

StartSSOLogin initiates an OIDC login flow for corporate SSO (domain-based discovery)

type OIDCClaims

type OIDCClaims struct {
	Sub           string
	Email         string
	EmailVerified bool
	Name          string
	Picture       string
	Issuer        string
	Audience      string
	ExpiresAt     time.Time
	IssuedAt      time.Time
}

OIDCClaims represents the claims from an ID token

type OIDCDiscoveryMetadata

type OIDCDiscoveryMetadata struct {
	Issuer                string   `json:"issuer"`
	AuthorizationEndpoint string   `json:"authorization_endpoint"`
	TokenEndpoint         string   `json:"token_endpoint"`
	UserInfoEndpoint      string   `json:"userinfo_endpoint"`
	JWKSUri               string   `json:"jwks_uri"`
	RegistrationEndpoint  string   `json:"registration_endpoint"` // RFC 7591 dynamic registration
	ScopesSupported       []string `json:"scopes_supported,omitempty"`
}

OIDCDiscoveryMetadata from provider's .well-known/openid-configuration endpoint

type OIDCLink struct {
	ID               uuid.UUID
	UserID           uuid.UUID
	OIDCProviderID   uuid.UUID
	ProviderUserID   string         // Provider's immutable 'sub' claim (allows email reassignment)
	ProviderEmail    string         // Email at time of link (may change at provider)
	ProviderMetadata map[string]any // Additional claims (name, picture, etc.)
	LinkedAt         time.Time
	LastUsedAt       *time.Time
}

OIDCLink tracks SSO users by provider's immutable sub claim (not email)

type OIDCProvider

type OIDCProvider interface {
	// GetAuthorizationURL generates the OAuth authorization URL with PKCE
	GetAuthorizationURL(state, codeVerifier, redirectURI string) (string, error)

	// ExchangeCode exchanges an authorization code for tokens
	ExchangeCode(ctx context.Context, code, codeVerifier, redirectURI string) (*OIDCTokenResponse, error)

	// GetUserInfo retrieves user information from the provider
	GetUserInfo(ctx context.Context, accessToken string) (*OIDCUserInfo, error)

	// ValidateIDToken validates and parses an ID token
	ValidateIDToken(ctx context.Context, idToken string) (*OIDCClaims, error)
}

OIDCProvider defines the interface for OIDC provider implementations

type OIDCProviderConfig

type OIDCProviderConfig struct {
	ID       uuid.UUID
	TenantID uuid.UUID

	ProviderName string // User-defined display name (e.g., "Azure AD - Production")
	IssuerURL    string // OIDC discovery URL (e.g., https://login.microsoftonline.com/tenant-id)

	ClientID     string
	ClientSecret string

	Scopes  []string
	Enabled bool

	// Domain-based SSO routing
	AllowedDomains           []string // Email domains that trigger this provider (e.g., ['acmecorp.com'])
	AutoCreateUsers          bool     // Auto-provision users on first SSO login
	RequireEmailVerification bool     // Require provider to verify email

	// RFC 7591 dynamic registration metadata (empty for manual registration)
	RegistrationAccessToken string
	RegistrationClientURI   string
	ClientIDIssuedAt        *time.Time
	ClientSecretExpiresAt   *time.Time

	RegistrationMethod sdk.OIDCRegistrationMethod
}

OIDCProviderConfig represents tenant-specific OIDC provider for corporate SSO

type OIDCProviderService

type OIDCProviderService struct {
	OIDCProviderDB     oidcProviderDB
	RegistrationClient oidcRegistrationClient
	ProviderFactory    oidcProviderFactory
	PublicURL          string
	Logger             *slog.Logger
}

OIDCProviderService handles OIDC provider CRUD operations and domain checks

func (*OIDCProviderService) CreateOIDCProvider

func (s *OIDCProviderService) CreateOIDCProvider(ctx context.Context, provider *OIDCProviderConfig, accessToken string) (*OIDCProviderConfig, error)

CreateOIDCProvider creates a new OIDC provider configuration manually or dynamically

func (*OIDCProviderService) DeleteOIDCProvider

func (s *OIDCProviderService) DeleteOIDCProvider(ctx context.Context, providerID uuid.UUID) error

DeleteOIDCProvider deletes an OIDC provider (admin operation) For dynamically registered providers, also attempts to unregister the OAuth client

func (*OIDCProviderService) GetOIDCProvider

func (s *OIDCProviderService) GetOIDCProvider(ctx context.Context, providerID uuid.UUID) (*OIDCProviderConfig, error)

GetOIDCProvider retrieves an OIDC provider by ID

func (*OIDCProviderService) GetOIDCProvidersByDomain

func (s *OIDCProviderService) GetOIDCProvidersByDomain(ctx context.Context, domain string) ([]*OIDCProviderConfig, error)

GetOIDCProvidersByDomain retrieves OIDC providers by domain

func (*OIDCProviderService) IsSSORequired

func (s *OIDCProviderService) IsSSORequired(ctx context.Context, email string) (bool, error)

IsSSORequired verifies if SSO login is required for the email domain

func (*OIDCProviderService) ListOIDCProviders

func (s *OIDCProviderService) ListOIDCProviders(ctx context.Context) ([]*OIDCProviderConfig, error)

ListOIDCProviders lists all OIDC providers for a tenant

func (*OIDCProviderService) UpdateOIDCProvider

func (s *OIDCProviderService) UpdateOIDCProvider(ctx context.Context, params *UpdateOIDCProviderParams) (*OIDCProviderConfig, error)

UpdateOIDCProvider updates an OIDC provider configuration

type OIDCRegistration

type OIDCRegistration struct {
	ClientID                string   `json:"client_id"`
	ClientSecret            string   `json:"client_secret,omitempty"`
	ClientIDIssuedAt        *int64   `json:"client_id_issued_at,omitempty"`
	ClientSecretExpiresAt   *int64   `json:"client_secret_expires_at,omitempty"`  // 0 = never expires
	RegistrationAccessToken string   `json:"registration_access_token,omitempty"` // For RFC 7592 management
	RegistrationClientURI   string   `json:"registration_client_uri,omitempty"`   // Update/delete endpoint
	TokenEndpointAuthMethod string   `json:"token_endpoint_auth_method,omitempty"`
	GrantTypes              []string `json:"grant_types,omitempty"`
	ResponseTypes           []string `json:"response_types,omitempty"`
	RedirectURIs            []string `json:"redirect_uris,omitempty"`
}

OIDCRegistration represents RFC 7591 dynamic client registration response

type OIDCSession

type OIDCSession struct {
	ID             uuid.UUID
	State          string                // Random state for CSRF protection
	CodeVerifier   string                // PKCE code verifier (hashed in authorization URL)
	OIDCProviderID *uuid.UUID            // Tenant-specific provider for SSO
	ProviderType   *sdk.OIDCProviderType // System-wide provider for individual OAuth
	RedirectURI    string
	TenantID       *uuid.UUID
	ExpiresAt      time.Time
}

OIDCSession tracks OAuth flow state for CSRF protection and PKCE

type OIDCTokenResponse

type OIDCTokenResponse struct {
	AccessToken  string
	IDToken      string
	RefreshToken string
	ExpiresIn    int
}

OIDCTokenResponse represents tokens from an OAuth token exchange

type OIDCUserInfo

type OIDCUserInfo struct {
	Sub           string // Provider's unique user ID (immutable)
	Email         string
	EmailVerified bool
	Name          string
	Picture       string
	Metadata      map[string]any // Provider-specific claims
}

OIDCUserInfo from provider's userinfo endpoint (standard + custom claims)

func (*OIDCUserInfo) Validate

func (u *OIDCUserInfo) Validate() error

Validate checks that required claims are present

type PasswordService

type PasswordService struct {
	UserDB               userDB
	PasswordValidator    passwordValidator
	Hasher               hasher
	PasswordResetTokenDB tokenDB
	EmailClient          emailClient
	LoginAttemptsService loginAttemptsService
	SessionRevoker       sessionRevoker
	Logger               *slog.Logger
}

func (*PasswordService) ChangePassword

func (s *PasswordService) ChangePassword(ctx context.Context, userID uuid.UUID, oldPassword, newPassword string) error

ChangePassword updates a user's password after validating their current password

func (*PasswordService) InitiatePasswordReset

func (s *PasswordService) InitiatePasswordReset(ctx context.Context, email string) error

InitiatePasswordReset generates a password reset token and sends a reset email

func (*PasswordService) ResetPassword

func (s *PasswordService) ResetPassword(ctx context.Context, tokenStr, newPassword string) error

ResetPassword validates the reset token and updates the user's password

func (*PasswordService) VerifyCredentials

func (s *PasswordService) VerifyCredentials(ctx context.Context, email, password string) (*User, error)

VerifyCredentials verifies user credentials and returns the active user account

type Permission

type Permission struct {
	ID          uuid.UUID
	Name        string // e.g., "employee:create"
	Description string
}

Permission represents a system-wide permission

type RBACService

type RBACService struct {
	RolesDB           roleDB
	PermissionsDB     permissionDB
	RolePermissionsDB rolePermissionDB
	UserRolesDB       userRoleDB
	UserPermissionsDB userPermissionDB
	Logger            *slog.Logger
}

func (*RBACService) CreateRole

func (s *RBACService) CreateRole(ctx context.Context, role *Role) (*Role, error)

CreateRole creates a new role

func (*RBACService) DeleteRole

func (s *RBACService) DeleteRole(ctx context.Context, roleID uuid.UUID) error

DeleteRole deletes a role

func (*RBACService) GetDirectPermissions

func (s *RBACService) GetDirectPermissions(ctx context.Context, userID uuid.UUID) ([]*EffectivePermission, error)

GetDirectPermissions retrieves direct permissions assigned to a user

func (*RBACService) GetRole

func (s *RBACService) GetRole(ctx context.Context, roleID uuid.UUID) (*Role, error)

GetRole retrieves a role by ID

func (*RBACService) GetRolePermissions

func (s *RBACService) GetRolePermissions(ctx context.Context, roleID uuid.UUID) ([]*Permission, error)

GetRolePermissions retrieves all permissions for a role

func (*RBACService) GetUserRoles

func (s *RBACService) GetUserRoles(ctx context.Context, userID uuid.UUID) ([]*Role, error)

GetUserRoles retrieves all roles for a user

func (*RBACService) GetUserScopes

func (s *RBACService) GetUserScopes(ctx context.Context, userID uuid.UUID) ([]Scope, error)

GetUserScopes returns all effective permission scopes for a user

func (*RBACService) ListPermissions

func (s *RBACService) ListPermissions(ctx context.Context) ([]*Permission, error)

ListPermissions lists all available permissions (system-wide)

func (*RBACService) ListRoles

func (s *RBACService) ListRoles(ctx context.Context) ([]*Role, error)

ListRoles lists all roles for the current tenant

func (*RBACService) SetDirectPermissions

func (s *RBACService) SetDirectPermissions(ctx context.Context, userID uuid.UUID, permissions []DirectPermission) error

SetDirectPermissions sets all direct permissions for a user (replaces existing direct permissions)

func (*RBACService) SetRolePermissions

func (s *RBACService) SetRolePermissions(ctx context.Context, roleID uuid.UUID, permissionIDs []uuid.UUID) error

SetRolePermissions replaces all permissions for a role (bulk update)

func (*RBACService) SetUserRoles

func (s *RBACService) SetUserRoles(ctx context.Context, userID uuid.UUID, roleIDs []uuid.UUID) error

SetUserRoles sets all roles for a user (replaces existing roles)

func (*RBACService) UpdateRole

func (s *RBACService) UpdateRole(ctx context.Context, params UpdateRoleParams) (*Role, error)

UpdateRole updates a role

func (*RBACService) UserRolesRequireMFA

func (s *RBACService) UserRolesRequireMFA(ctx context.Context, userID uuid.UUID) (bool, error)

UserRolesRequireMFA checks if any of the user's assigned roles require MFA

type RefreshToken

type RefreshToken struct {
	ID         uuid.UUID
	UserID     uuid.UUID
	TokenHash  string
	FamilyID   uuid.UUID // Token family for rotation tracking
	UserAgent  string
	IPAddress  string
	CreatedAt  time.Time
	LastUsedAt time.Time
	ExpiresAt  time.Time
	RevokedAt  *time.Time
}

RefreshToken represents a stored session for session management

type Role

type Role struct {
	ID          uuid.UUID
	Name        string
	Description string
	MFARequired bool
}

Role represents a tenant-specific role

type Scope

type Scope = jwt.Scope

Scope is an alias for jwt.Scope

const (
	// User management scopes
	ScopeUserCreate Scope = "heimdall:user:create" // Create new user accounts
	ScopeUserRead   Scope = "heimdall:user:read"   // View user information and their role/permission assignments
	ScopeUserUpdate Scope = "heimdall:user:update" // Update user profile (email, name, status)
	ScopeUserDelete Scope = "heimdall:user:delete" // Delete user accounts
	ScopeUserAssign Scope = "heimdall:user:assign" // Assign roles and permissions to users

	// Role management scopes
	ScopeRoleCreate Scope = "heimdall:role:create" // Create new roles
	ScopeRoleRead   Scope = "heimdall:role:read"   // View roles and their permissions
	ScopeRoleUpdate Scope = "heimdall:role:update" // Update roles and their permission assignments
	ScopeRoleDelete Scope = "heimdall:role:delete" // Delete roles

	// OIDC provider management scopes
	ScopeOIDCCreate Scope = "heimdall:oidc:create" // Create OIDC/SSO provider configurations
	ScopeOIDCRead   Scope = "heimdall:oidc:read"   // View OIDC/SSO provider configurations
	ScopeOIDCUpdate Scope = "heimdall:oidc:update" // Update OIDC/SSO provider settings
	ScopeOIDCDelete Scope = "heimdall:oidc:delete" // Delete OIDC/SSO provider configurations
)

System-wide scopes for Heimdall authentication and authorization service

type SessionService

type SessionService struct {
	RefreshTokenDB refreshTokenDB
	Logger         *slog.Logger
}

SessionService manages refresh token storage for session management

func (*SessionService) DeleteExpiredSessions

func (s *SessionService) DeleteExpiredSessions(ctx context.Context) error

DeleteExpiredSessions cleans up expired and old revoked tokens

func (*SessionService) ListSessions

func (s *SessionService) ListSessions(ctx context.Context, userID uuid.UUID) ([]*RefreshToken, error)

ListSessions returns all active sessions for a user

func (*SessionService) RevokeAllSessions

func (s *SessionService) RevokeAllSessions(ctx context.Context, userID uuid.UUID) error

RevokeAllSessions revokes all sessions for a user (sign out everywhere)

func (*SessionService) RevokeSession

func (s *SessionService) RevokeSession(ctx context.Context, sessionID uuid.UUID) error

RevokeSession revokes a specific session by ID

func (*SessionService) RevokeSessionByToken

func (s *SessionService) RevokeSessionByToken(ctx context.Context, refreshToken string) error

RevokeSessionByToken revokes a session by the raw refresh token (for logout)

func (*SessionService) RotateSession

func (s *SessionService) RotateSession(ctx context.Context, refreshToken string) (*RefreshToken, error)

RotateSession validates a refresh token and revokes it for rotation. Returns the old token's metadata (including FamilyID) for creating the new token.

func (*SessionService) StoreSession

func (s *SessionService) StoreSession(ctx context.Context, rt *RefreshToken) error

StoreSession stores a refresh token in the database

func (*SessionService) ValidateSession

func (s *SessionService) ValidateSession(ctx context.Context, refreshToken string) (*RefreshToken, error)

ValidateSession checks if a refresh token is valid (not revoked, not expired)

type SessionTokens

type SessionTokens struct {
	AccessToken            string
	RefreshToken           string
	MFAChallengeToken      string
	MFASetupToken          string
	DeviceToken            string // Trusted device token (set when user opts to trust device after MFA)
	AccessExpiration       time.Duration
	RefreshExpiration      time.Duration
	MFAChallengeExpiration time.Duration
	MFASetupExpiration     time.Duration
}

SessionTokens contains all tokens for an authenticated session

func (*SessionTokens) RequiresMFA

func (s *SessionTokens) RequiresMFA() bool

RequiresMFA returns true if MFA verification is needed to complete authentication

func (*SessionTokens) RequiresMFASetup

func (s *SessionTokens) RequiresMFASetup() bool

RequiresMFASetup returns true if user must set up MFA before getting full access

type Tenant

type Tenant struct {
	ID uuid.UUID
}

Tenant represents a tenant in the system

type TrustedDevice

type TrustedDevice struct {
	ID         uuid.UUID
	UserID     uuid.UUID
	TokenHash  string
	UserAgent  string
	IPAddress  string
	CreatedAt  time.Time
	LastUsedAt time.Time
	ExpiresAt  time.Time
	RevokedAt  *time.Time
}

TrustedDevice represents a device trusted to skip MFA

type TrustedDeviceService

type TrustedDeviceService struct {
	TrustedDeviceDB trustedDeviceDB
	Logger          *slog.Logger
}

TrustedDeviceService manages trusted device operations

func (*TrustedDeviceService) CreateTrustedDevice

func (s *TrustedDeviceService) CreateTrustedDevice(ctx context.Context, device *TrustedDevice) (string, error)

CreateTrustedDevice creates a new trusted device entry and returns the raw token.

func (*TrustedDeviceService) DeleteExpiredDevices

func (s *TrustedDeviceService) DeleteExpiredDevices(ctx context.Context) error

DeleteExpiredDevices cleans up expired and old revoked devices

func (*TrustedDeviceService) RevokeAllTrustedDevices

func (s *TrustedDeviceService) RevokeAllTrustedDevices(ctx context.Context, userID uuid.UUID) error

RevokeAllTrustedDevices revokes all trusted devices for a user

func (*TrustedDeviceService) ValidateTrustedDevice

func (s *TrustedDeviceService) ValidateTrustedDevice(ctx context.Context, deviceToken string, userID uuid.UUID, ipAddress string) (bool, error)

ValidateTrustedDevice checks if the device token is valid for the given user

type UpdateOIDCProviderParams

type UpdateOIDCProviderParams struct {
	ID                       uuid.UUID
	ProviderName             *string
	ClientSecret             *string
	Scopes                   []string
	Enabled                  *bool
	AllowedDomains           []string
	AutoCreateUsers          *bool
	RequireEmailVerification *bool
}

UpdateOIDCProviderParams supports partial updates using optional pointer fields

type UpdateRoleParams

type UpdateRoleParams struct {
	ID          uuid.UUID
	Name        *string
	Description *string
	MFARequired *bool
}

UpdateRoleParams supports partial updates using optional pointer fields

type UpdateUserParams

type UpdateUserParams struct {
	ID           uuid.UUID
	PasswordHash *string
	Status       *UserStatus
}

UpdateUserParams supports partial updates using optional pointer fields

type User

type User struct {
	ID           uuid.UUID
	TenantID     uuid.UUID
	Email        string
	PasswordHash string
	FirstName    string
	LastName     string
	Status       UserStatus
	LastLoginAt  *time.Time
}

User represents a user in the system

type UserService

type UserService struct {
	UserDB              userDB
	PasswordValidator   passwordValidator
	TenantsDB           tenantsDB
	Hasher              hasher
	EmailClient         emailClient
	VerificationTokenDB tokenDB
	OIDCService         oidcService
	RBACService         rbacService
	Logger              *slog.Logger
}

UserService handles user registration, email verification, and user management

func (*UserService) CreateUser

func (s *UserService) CreateUser(ctx context.Context, user *User, roleIDs []uuid.UUID) (*User, string, error)

CreateUser creates a new user and assigns specified roles

func (*UserService) GetUser

func (s *UserService) GetUser(ctx context.Context, userID uuid.UUID) (*User, error)

GetUser retrieves a user by ID

func (*UserService) Register

func (s *UserService) Register(ctx context.Context, email, firstName, lastName string) (*User, error)

Register creates new user with email verification, rejects SSO-enforced domains

func (*UserService) VerifyEmailAndSetPassword

func (s *UserService) VerifyEmailAndSetPassword(ctx context.Context, tokenStr string, password string) (*User, error)

VerifyEmailAndSetPassword verifies the email verification token, sets the password, and activates the account

type UserStatus

type UserStatus string

UserStatus represents the status of a user

const (
	UserStatusUnverified UserStatus = "unverified"
	UserStatusActive     UserStatus = "active"
	UserStatusSuspended  UserStatus = "suspended"
	UserStatusInactive   UserStatus = "inactive"
)

type UserToken

type UserToken struct {
	UserID    uuid.UUID
	Token     string
	ExpiresAt time.Time
}

UserToken represents a temporary token (verification, password reset, etc.)

Jump to

Keyboard shortcuts

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