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
- func HasCapability(capabilities []Capability, capability Capability) bool
- func ProfileFromContext(ctx context.Context) string
- func WithProfile(ctx context.Context, profile string) context.Context
- type CachedTokenInfo
- type CallerType
- type Capability
- type Claims
- type Flow
- type HandlerMetadata
- type IdentityType
- type LoginOptions
- type Result
- type ServerContext
- type Status
- type Token
- type TokenLister
- type TokenOptions
- type TokenPurger
Constants ¶
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
ProfileFromContext retrieves the profile name from the context. Returns an empty string if no profile is set (default 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 ¶
DisplayIdentity returns the best available identity string for display.
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" )
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) IsValidFor ¶
IsValidFor returns true if the token will be valid for at least the specified duration.
func (*Token) TimeUntilExpiry ¶
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.