auth

package
v0.4.0 Latest Latest
Warning

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

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

Documentation

Overview

Package auth provides authentication handler interfaces and utilities for scafctl. Auth handlers manage identity verification, credential storage, and token acquisition. They are separate from providers - providers are stateless execution primitives, while auth handlers manage state (cached tokens, refresh tokens) across invocations.

Index

Constants

View Source
const DefaultMinValidFor = 60 * time.Second

DefaultMinValidFor is the default minimum validity duration for tokens.

Variables

View Source
var (
	ErrNotAuthenticated     = errors.New("not authenticated: please run 'scafctl auth login entra'")
	ErrAuthenticationFailed = errors.New("authentication failed")
	ErrTokenExpired         = errors.New("credentials expired: please run 'scafctl auth login entra'")
	ErrConsentRequired      = errors.New("consent required: please login with the required scope, e.g. 'scafctl auth login entra --scope <scope>'")
	ErrInvalidScope         = errors.New("invalid scope: scope cannot be empty")
	ErrHandlerNotFound      = errors.New("auth handler not found")
	ErrFlowNotSupported     = errors.New("authentication flow not supported")
	ErrUserCancelled        = errors.New("authentication cancelled by user")
	ErrTimeout              = errors.New("authentication timed out")
	ErrAlreadyAuthenticated = errors.New("already authenticated")
	ErrGrantInvalid         = errors.New("invalid grant: the refresh token is invalid or has been revoked, please re-authenticate with 'scafctl auth login entra'")
)

Sentinel errors for the auth package.

Functions

func HasHandler

func HasHandler(ctx context.Context, name string) bool

HasHandler checks if an auth handler exists in the context's registry.

func IsConsentRequired added in v0.4.0

func IsConsentRequired(err error) bool

IsConsentRequired returns true if the error indicates consent is required for the requested scope.

func IsHandlerNotFound

func IsHandlerNotFound(err error) bool

IsHandlerNotFound returns true if the error indicates the handler was not found.

func IsNotAuthenticated

func IsNotAuthenticated(err error) bool

IsNotAuthenticated returns true if the error indicates the user is not authenticated.

func IsTimeout

func IsTimeout(err error) bool

IsTimeout returns true if the error indicates a timeout occurred.

func IsTokenExpired

func IsTokenExpired(err error) bool

IsTokenExpired returns true if the error indicates the token has expired.

func IsUserCancelled

func IsUserCancelled(err error) bool

IsUserCancelled returns true if the error indicates the user cancelled.

func ListHandlers

func ListHandlers(ctx context.Context) []string

ListHandlers lists all auth handlers in the context's registry.

func WithRegistry

func WithRegistry(ctx context.Context, registry *Registry) context.Context

WithRegistry returns a new context with the auth registry attached.

Types

type Claims

type Claims struct {
	Issuer    string
	Subject   string
	TenantID  string
	ObjectID  string
	ClientID  string
	Email     string
	Name      string
	Username  string
	IssuedAt  time.Time
	ExpiresAt time.Time
}

Claims represents normalized identity claims from any auth handler.

func (*Claims) DisplayIdentity

func (c *Claims) DisplayIdentity() string

DisplayIdentity returns the best available identity string for display.

func (*Claims) IsEmpty

func (c *Claims) IsEmpty() bool

IsEmpty returns true if the claims have no meaningful data.

type Error

type Error struct {
	Handler   string
	Operation string
	Cause     error
}

Error wraps authentication errors with additional context.

func NewError

func NewError(handler, operation string, cause error) *Error

NewError creates a new Error.

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface.

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap returns the underlying cause.

type Flow

type Flow string

Flow represents an authentication flow type.

const (
	// FlowDeviceCode is the OAuth 2.0 device authorization flow.
	FlowDeviceCode Flow = "device_code"

	// FlowInteractive is an interactive browser-based flow.
	FlowInteractive Flow = "interactive"

	// FlowServicePrincipal is authentication using service principal credentials.
	FlowServicePrincipal Flow = "service_principal"

	// FlowWorkloadIdentity is authentication using Azure Workload Identity (Kubernetes).
	FlowWorkloadIdentity Flow = "workload_identity"
)

type Handler

type Handler interface {
	// Name returns the unique identifier for this auth handler.
	Name() string

	// DisplayName returns a human-readable name for display purposes.
	DisplayName() string

	// Login initiates the authentication flow.
	// For interactive flows (like device code), this blocks until completion or timeout.
	// Returns the authenticated identity claims on success.
	Login(ctx context.Context, opts LoginOptions) (*Result, error)

	// Logout clears stored credentials for this handler.
	Logout(ctx context.Context) error

	// Status returns the current authentication status.
	// Returns a status with Authenticated=false if not logged in.
	Status(ctx context.Context) (*Status, error)

	// GetToken returns a valid access token for the specified options.
	// Uses cached tokens when available and valid for the requested duration,
	// otherwise refreshes from the identity provider.
	// Returns ErrNotAuthenticated if user is not logged in.
	// Returns ErrTokenExpired if refresh token has expired (re-login required).
	GetToken(ctx context.Context, opts TokenOptions) (*Token, error)

	// InjectAuth adds authentication to an HTTP request.
	// This is the primary method used by providers (like HTTP) to authenticate requests.
	// Automatically handles token acquisition/refresh as needed.
	InjectAuth(ctx context.Context, req *http.Request, opts TokenOptions) error

	// SupportedFlows returns the authentication flows this handler supports.
	SupportedFlows() []Flow
}

Handler defines the interface for authentication handlers. Auth handlers manage identity verification, credential storage, and token acquisition.

func GetHandler

func GetHandler(ctx context.Context, name string) (Handler, error)

GetHandler gets an auth handler from the context's registry.

type IdentityType

type IdentityType string

IdentityType represents the type of authenticated identity.

const (
	// IdentityTypeUser represents a user identity (e.g., device code flow).
	IdentityTypeUser IdentityType = "user"
	// IdentityTypeServicePrincipal represents a service principal identity.
	IdentityTypeServicePrincipal IdentityType = "service-principal"
	// IdentityTypeWorkloadIdentity represents a workload identity (Kubernetes federated).
	IdentityTypeWorkloadIdentity IdentityType = "workload-identity"
)

type LoginOptions

type LoginOptions struct {
	TenantID           string
	Scopes             []string
	Flow               Flow
	Timeout            time.Duration
	DeviceCodeCallback func(userCode, verificationURI, message string)
}

LoginOptions configures the login process.

type MockHandler

type MockHandler struct {
	NameValue        string
	DisplayNameValue string
	FlowsValue       []Flow

	LoginResult    *Result
	LoginErr       error
	LogoutErr      error
	StatusResult   *Status
	StatusErr      error
	GetTokenResult *Token
	GetTokenErr    error
	InjectAuthErr  error

	LoginCalls      []LoginOptions
	LogoutCalls     int
	StatusCalls     int
	GetTokenCalls   []TokenOptions
	InjectAuthCalls []TokenOptions
	// contains filtered or unexported fields
}

MockHandler implements Handler for testing.

func NewMockHandler

func NewMockHandler(name string) *MockHandler

NewMockHandler creates a new mock auth handler with default values.

func (*MockHandler) DisplayName

func (m *MockHandler) DisplayName() string

func (*MockHandler) GetToken

func (m *MockHandler) GetToken(_ context.Context, opts TokenOptions) (*Token, error)

func (*MockHandler) InjectAuth

func (m *MockHandler) InjectAuth(_ context.Context, req *http.Request, opts TokenOptions) error

func (*MockHandler) Login

func (m *MockHandler) Login(_ context.Context, opts LoginOptions) (*Result, error)

func (*MockHandler) Logout

func (m *MockHandler) Logout(_ context.Context) error

func (*MockHandler) Name

func (m *MockHandler) Name() string

func (*MockHandler) Reset

func (m *MockHandler) Reset()

func (*MockHandler) SetAuthenticated

func (m *MockHandler) SetAuthenticated(claims *Claims)

func (*MockHandler) SetNotAuthenticated

func (m *MockHandler) SetNotAuthenticated()

func (*MockHandler) SetToken

func (m *MockHandler) SetToken(token *Token)

func (*MockHandler) SetTokenError

func (m *MockHandler) SetTokenError(err error)

func (*MockHandler) Status

func (m *MockHandler) Status(_ context.Context) (*Status, error)

func (*MockHandler) SupportedFlows

func (m *MockHandler) SupportedFlows() []Flow

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry manages registered auth handlers.

func MustRegistryFromContext

func MustRegistryFromContext(ctx context.Context) *Registry

MustRegistryFromContext retrieves the auth registry from the context. Panics if no registry is attached.

func NewRegistry

func NewRegistry() *Registry

NewRegistry creates a new auth handler registry.

func RegistryFromContext

func RegistryFromContext(ctx context.Context) *Registry

RegistryFromContext retrieves the auth registry from the context.

func (*Registry) All

func (r *Registry) All() map[string]Handler

All returns all registered handlers as a map.

func (*Registry) Count

func (r *Registry) Count() int

Count returns the number of registered handlers.

func (*Registry) Get

func (r *Registry) Get(name string) (Handler, error)

Get retrieves an auth handler by name.

func (*Registry) Has

func (r *Registry) Has(name string) bool

Has returns true if a handler with the given name is registered.

func (*Registry) List

func (r *Registry) List() []string

List returns the names of all registered handlers in sorted order.

func (*Registry) Register

func (r *Registry) Register(handler Handler) error

Register adds an auth handler to the registry.

func (*Registry) Unregister

func (r *Registry) Unregister(name string) error

Unregister removes an auth handler from the registry.

type Result

type Result struct {
	Claims    *Claims
	ExpiresAt time.Time
}

Result contains the result of a successful authentication.

type Status

type Status struct {
	Authenticated bool
	Claims        *Claims
	ExpiresAt     time.Time
	LastRefresh   time.Time
	TenantID      string
	IdentityType  IdentityType // Type of identity: "user", "service-principal", or "workload-identity"
	ClientID      string       // For service principal/workload identity: the application ID
	TokenFile     string       // For workload identity: path to the federated token file
	Scopes        []string     // Scopes granted during login
}

Status represents the current authentication state.

type Token

type Token struct {
	AccessToken string //nolint:gosec // G117: not a hardcoded credential, stores runtime token data
	TokenType   string
	ExpiresAt   time.Time
	Scope       string
}

Token represents a short-lived access token.

func (*Token) IsExpired

func (t *Token) IsExpired() bool

IsExpired returns true if the token has expired.

func (*Token) IsValidFor

func (t *Token) IsValidFor(duration time.Duration) bool

IsValidFor returns true if the token will be valid for at least the specified duration.

func (*Token) TimeUntilExpiry

func (t *Token) TimeUntilExpiry() time.Duration

TimeUntilExpiry returns the duration until the token expires. Returns 0 if the token is already expired or invalid.

type TokenOptions

type TokenOptions struct {
	Scope        string
	MinValidFor  time.Duration
	ForceRefresh bool
}

TokenOptions configures token acquisition.

Directories

Path Synopsis
Package entra provides Microsoft Entra ID (formerly Azure AD) authentication for scafctl using the OAuth 2.0 device authorization flow.
Package entra provides Microsoft Entra ID (formerly Azure AD) authentication for scafctl using the OAuth 2.0 device authorization flow.

Jump to

Keyboard shortcuts

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