auth

package
v0.16.0 Latest Latest
Warning

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

Go to latest
Published: Jul 4, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package auth provides authentication handler types and utilities for scafctl plugins, including the canonical HandlerMetadata schema shared by core and all plugin auth handlers.

Index

Constants

View Source
const DefaultMinValidFor = 60 * time.Second

DefaultMinValidFor is the default minimum validity duration for tokens.

Variables

This section is empty.

Functions

func HasCapability

func HasCapability(capabilities []Capability, capability Capability) bool

HasCapability checks if a set of capabilities includes the specified capability.

func ProfileFromContext added in v0.6.0

func ProfileFromContext(ctx context.Context) string

ProfileFromContext retrieves the profile name from the context. Returns an empty string if no profile is set (default profile).

func WithProfile added in v0.6.0

func WithProfile(ctx context.Context, profile string) context.Context

WithProfile returns a new context with the given profile name attached. An empty string represents the default (unnamed) profile.

Types

type CachedTokenInfo

type CachedTokenInfo struct {
	Handler string `json:"handler" yaml:"handler"`
	// Hostname identifies the instance (cluster/server) the session belongs to.
	// Handlers that advertise auth.CapInstanceHostname populate it so a host can
	// enumerate one entry per live instance and render cluster-aware status; it
	// is empty ("") for non-instance handlers. The zero value preserves the
	// prior behavior, so this field is backward compatible.
	Hostname    string    `json:"hostname,omitempty" yaml:"hostname,omitempty"`
	TokenKind   string    `json:"tokenKind" yaml:"tokenKind"`
	Scope       string    `json:"scope,omitempty" yaml:"scope,omitempty"`
	TokenType   string    `json:"tokenType,omitempty" yaml:"tokenType,omitempty"`
	Flow        Flow      `json:"flow,omitempty" yaml:"flow,omitempty"`
	Fingerprint string    `json:"fingerprint,omitempty" yaml:"fingerprint,omitempty"`
	ExpiresAt   time.Time `json:"expiresAt,omitempty" yaml:"expiresAt,omitempty"`
	CachedAt    time.Time `json:"cachedAt,omitempty" yaml:"cachedAt,omitempty"`
	IsExpired   bool      `json:"isExpired" yaml:"isExpired"`
	SessionID   string    `json:"sessionId,omitempty" yaml:"sessionId,omitempty"`
}

CachedTokenInfo holds display metadata for a cached token.

func (*CachedTokenInfo) TimeUntilExpiry

func (c *CachedTokenInfo) TimeUntilExpiry() time.Duration

TimeUntilExpiry returns the duration until this cached token expires.

type CallerType added in v0.13.0

type CallerType string

CallerType identifies who is requesting the token.

const (
	// CallerServer means the plugin authenticates as itself.
	CallerServer CallerType = "server"
	// CallerUser means delegated on behalf of a user (OBO).
	CallerUser CallerType = "user"
	// CallerMachine means delegated on behalf of another service.
	CallerMachine CallerType = "machine"
)

type Capability

type Capability string

Capability represents a feature or behavior that an auth handler supports. Capabilities allow CLI commands to dynamically adapt their flags and validation based on what each handler supports, enabling plugin-loaded handlers to work without hardcoded knowledge of their features.

const (
	// CapScopesOnLogin indicates the handler supports specifying OAuth scopes at login time.
	// Both GitHub (device code) and Entra (device code/SP/WI) support this.
	CapScopesOnLogin Capability = "scopes_on_login"

	// CapScopesOnTokenRequest indicates the handler supports specifying per-request scopes
	// when acquiring tokens. Entra supports this (different resource scopes per request),
	// but GitHub does not (scopes are fixed at login time).
	CapScopesOnTokenRequest Capability = "scopes_on_token_request"

	// CapTenantID indicates the handler supports a tenant ID parameter.
	// Entra uses this for Azure AD tenant selection.
	CapTenantID Capability = "tenant_id"

	// CapHostname indicates the handler supports a hostname parameter.
	// GitHub uses this for GitHub Enterprise Server (GHES) support.
	CapHostname Capability = "hostname"

	// CapTokenHostname indicates the handler honors a hostname selector on the
	// token-request path (GetToken), not just at login. Hosts must only populate
	// the token hostname for handlers that advertise this capability. It is
	// distinct from CapHostname so that older handlers built against a prior SDK,
	// which advertise CapHostname for login only, are not sent a token hostname
	// they would silently ignore (proto3 drops unknown fields), which would fall
	// back to the default/most-recent token instead of the requested instance.
	CapTokenHostname Capability = "token_hostname"

	// CapInstanceHostname indicates the handler honors a hostname selector on the
	// status and logout paths (GetStatus/Logout), letting a caller report or
	// clear a single instance's credential from a per-instance cache. Hosts must
	// only populate the status/logout hostname for handlers that advertise this
	// capability; older handlers that ignore it preserve their current behavior
	// (status reports the default instance; logout clears all instances).
	CapInstanceHostname Capability = "instance_hostname"

	// CapFederatedToken indicates the handler supports federated token input.
	// Entra uses this for workload identity (Kubernetes) authentication.
	CapFederatedToken Capability = "federated_token"

	// CapCallbackPort indicates the handler supports binding the OAuth callback
	// server to a specific port via --callback-port. Handlers that use the
	// authorization code + PKCE flow (Entra, GCP) advertise this capability.
	CapCallbackPort Capability = "callback_port"

	// CapFlowOverride indicates the handler supports runtime flow selection via --flow.
	CapFlowOverride Capability = "flow_override"
)

type Claims

type Claims struct {
	Issuer    string    `` /* 130-byte string literal not displayed */
	Subject   string    `json:"subject,omitempty" yaml:"subject,omitempty" doc:"Subject identifier" example:"user@example.com" maxLength:"512"`
	TenantID  string    `` /* 139-byte string literal not displayed */
	ObjectID  string    `` /* 147-byte string literal not displayed */
	ClientID  string    `` /* 142-byte string literal not displayed */
	Email     string    `json:"email,omitempty" yaml:"email,omitempty" doc:"Email address of the identity" example:"user@example.com" maxLength:"320"`
	Name      string    `json:"name,omitempty" yaml:"name,omitempty" doc:"Display name of the identity" example:"Jane Doe" maxLength:"256"`
	Username  string    `json:"username,omitempty" yaml:"username,omitempty" doc:"Username or login name" example:"janedoe" maxLength:"256"`
	IssuedAt  time.Time `json:"issuedAt,omitempty" yaml:"issuedAt,omitempty" doc:"Time the token was issued"`
	ExpiresAt time.Time `json:"expiresAt,omitempty" yaml:"expiresAt,omitempty" doc:"Time the token expires"`
}

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 Flow

type Flow string

Flow represents an authentication flow type.

const (
	FlowDeviceCode        Flow = "device_code"
	FlowInteractive       Flow = "interactive"
	FlowServicePrincipal  Flow = "service_principal"
	FlowWorkloadIdentity  Flow = "workload_identity"
	FlowPAT               Flow = "pat"
	FlowMetadata          Flow = "metadata"
	FlowGcloudADC         Flow = "gcloud_adc"
	FlowGitHubApp         Flow = "github_app"
	FlowClientCredentials Flow = "client_credentials"
	FlowOnBehalfOf        Flow = "obo"
)

func ParseFlow

func ParseFlow(flowStr, handlerName string) (Flow, error)

ParseFlow converts a flow string to a Flow constant. If flowStr is empty, an empty Flow is returned (caller should auto-detect). handlerName is used to produce handler-specific error messages for unrecognised values.

type HandlerMetadata added in v0.11.0

type HandlerMetadata struct {
	Claims        *Claims        `json:"claims,omitempty" yaml:"claims,omitempty" doc:"Normalized identity claims for the session"`
	ExpiresAt     time.Time      `json:"expiresAt,omitempty" yaml:"expiresAt,omitempty" doc:"Time the session or refresh credential expires"`
	Scopes        []string       `json:"scopes,omitempty" yaml:"scopes,omitempty" doc:"Scopes granted to the session"`
	LastLoginFlow Flow           `json:"lastLoginFlow,omitempty" yaml:"lastLoginFlow,omitempty" doc:"Auth flow that produced the session"`
	SessionID     string         `json:"sessionId,omitempty" yaml:"sessionId,omitempty" doc:"Opaque session identifier"`
	LastRefresh   time.Time      `json:"lastRefresh,omitempty" yaml:"lastRefresh,omitempty" doc:"Time the session was last refreshed"`
	ClientID      string         `json:"clientId,omitempty" yaml:"clientId,omitempty" doc:"Application/client ID used for the session"`
	Metadata      map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty" doc:"Handler-specific fields keyed by exported plugin constants"`
}

HandlerMetadata is the canonical persisted metadata for an auth session, shared by core and all plugin auth handlers.

The typed fields cover everything common across handlers. Handler-specific values (for example the entra tenant ID or the gcp project) go in the open Metadata map, keyed by exported constants defined in each plugin to avoid key drift.

func (HandlerMetadata) MetaString added in v0.11.0

func (m HandlerMetadata) MetaString(key string) string

MetaString returns the string value for key, or "" if the key is absent or its value is not a string. It uses a value receiver so it can be called on non-addressable values.

func (*HandlerMetadata) SetMeta added in v0.11.0

func (m *HandlerMetadata) SetMeta(key string, value any)

SetMeta sets a handler-specific key, allocating the Metadata map on first use.

type IdentityType

type IdentityType string

IdentityType represents the type of authenticated identity.

const (
	IdentityTypeUser             IdentityType = "user"
	IdentityTypeServicePrincipal IdentityType = "service-principal"
	IdentityTypeWorkloadIdentity IdentityType = "workload-identity"
)

type LoginOptions

type LoginOptions struct {
	TenantID string        `json:"tenantId,omitempty" yaml:"tenantId,omitempty"`
	Scopes   []string      `json:"scopes,omitempty" yaml:"scopes,omitempty"`
	Flow     Flow          `json:"flow,omitempty" yaml:"flow,omitempty"`
	Timeout  time.Duration `json:"timeout,omitempty" yaml:"timeout,omitempty"`
	// Hostname selects a specific instance (e.g. a cluster or server) for
	// handlers that advertise CapHostname.
	Hostname           string                                          `json:"hostname,omitempty" yaml:"hostname,omitempty"`
	CallbackPort       int                                             `json:"callbackPort,omitempty" yaml:"callbackPort,omitempty"`
	DeviceCodeCallback func(userCode, verificationURI, message string) `json:"-" yaml:"-"`
}

LoginOptions configures the login process.

type Result

type Result struct {
	Claims    *Claims   `json:"claims,omitempty" yaml:"claims,omitempty"`
	ExpiresAt time.Time `json:"expiresAt,omitempty" yaml:"expiresAt,omitempty"`
}

Result contains the result of a successful authentication.

type ServerContext added in v0.13.0

type ServerContext string

ServerContext identifies whether the request is for the server itself or delegated.

const (
	// ServerContextServer means the server is acquiring a token as itself.
	ServerContextServer ServerContext = "server"
	// ServerContextDelegated means the server is acquiring a token on behalf of another identity.
	ServerContextDelegated ServerContext = "delegated"
)

type Status

type Status struct {
	Authenticated bool         `json:"authenticated" yaml:"authenticated"`
	Reason        string       `json:"reason,omitempty" yaml:"reason,omitempty"`
	Claims        *Claims      `json:"claims,omitempty" yaml:"claims,omitempty"`
	ExpiresAt     time.Time    `json:"expiresAt,omitempty" yaml:"expiresAt,omitempty"`
	LastRefresh   time.Time    `json:"lastRefresh,omitempty" yaml:"lastRefresh,omitempty"`
	TenantID      string       `json:"tenantId,omitempty" yaml:"tenantId,omitempty"`
	IdentityType  IdentityType `json:"identityType,omitempty" yaml:"identityType,omitempty"`
	ClientID      string       `json:"clientId,omitempty" yaml:"clientId,omitempty"`
	TokenFile     string       `json:"tokenFile,omitempty" yaml:"tokenFile,omitempty"`
	Scopes        []string     `json:"scopes,omitempty" yaml:"scopes,omitempty"`
	Flow          Flow         `json:"flow,omitempty" yaml:"flow,omitempty"`
	// Hostname identifies the instance (cluster/server) this status reports on.
	// Handlers that advertise auth.CapInstanceHostname set it so a host can label
	// a per-cluster status row straight from GetStatus; it is empty ("") for
	// non-instance handlers. The zero value preserves the prior behavior, so this
	// field is backward compatible.
	Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"`
}

Status represents the current authentication state.

type Token

type Token struct {
	AccessToken string    `json:"accessToken" yaml:"accessToken"` //nolint:gosec
	TokenType   string    `json:"tokenType" yaml:"tokenType"`
	ExpiresAt   time.Time `json:"expiresAt" yaml:"expiresAt"`
	Scope       string    `json:"scope,omitempty" yaml:"scope,omitempty"`
	CachedAt    time.Time `json:"cachedAt,omitempty" yaml:"cachedAt,omitempty"`
	Flow        Flow      `json:"flow,omitempty" yaml:"flow,omitempty"`
	SessionID   string    `json:"sessionId,omitempty" yaml:"sessionId,omitempty"`
}

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.

type TokenLister

type TokenLister interface {
	ListCachedTokens(ctx context.Context) ([]*CachedTokenInfo, error)
}

TokenLister is an optional interface for auth handlers that can enumerate cached tokens.

type TokenOptions

type TokenOptions struct {
	Scope         string        `json:"scope,omitempty" yaml:"scope,omitempty"`
	MinValidFor   time.Duration `json:"minValidFor,omitempty" yaml:"minValidFor,omitempty"`
	ForceRefresh  bool          `json:"forceRefresh,omitempty" yaml:"forceRefresh,omitempty"`
	ServerContext ServerContext `json:"serverContext,omitempty" yaml:"serverContext,omitempty"`
	Assertion     string        `json:"assertion,omitempty" yaml:"assertion,omitempty"`
	Caller        CallerType    `json:"caller,omitempty" yaml:"caller,omitempty"`
	// Hostname selects a specific instance (e.g. a cluster or server) for
	// handlers that advertise CapTokenHostname.
	Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"`
}

TokenOptions configures token acquisition.

type TokenPurger

type TokenPurger interface {
	PurgeExpiredTokens(ctx context.Context) (int, error)
}

TokenPurger is an optional interface for auth handlers that can remove expired tokens.

Jump to

Keyboard shortcuts

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