Documentation
¶
Overview ¶
Package auth contains the SafeDep CLI's authentication flows. It owns the OAuth2 device-code login, the static API-key login, and the helpers that read and write credentials via dry/cloud's keychain.
Commands under internal/cmd/auth invoke these flows. Nothing else in the CLI talks to the keychain directly.
Index ¶
- Constants
- Variables
- func APIKeyName(hostname string, now time.Time) string
- func AccessTokenExpiry(token string) (time.Time, error)
- func Audience() string
- func ClientID() string
- func DeviceCodeURL() string
- func IsExpired(token string, now time.Time) bool
- func SaveAPIKey(_ context.Context, store cloud.CredentialStore, in APIKeyInput) error
- func TokenURL() string
- func VerifyAPIKey(ctx context.Context, in APIKeyInput) error
- type APIKeyInput
- type BootstrapInput
- type BootstrapResult
- type ControlPlaneConnFunc
- type DeviceFlowResult
- type DeviceFlowSink
- type Status
- type TenantPicker
Constants ¶
const ( // DefaultAPIKeyExpiryDays is the lifetime of API keys created by the // device-code login flow. Override with --api-key-expiry-days. DefaultAPIKeyExpiryDays = 90 // gRPCAppName identifies our connections to SafeDep Cloud in logs. GRPCAppName = "safedep-cli" )
Variables ¶
var CLIScopes = []string{"offline_access", "openid", "profile", "email"}
CLIScopes are the OAuth scopes we request. offline_access is required to receive a refresh token.
Functions ¶
func APIKeyName ¶
APIKeyName returns the human-readable name used when creating API keys from the device login flow. Stable enough for users to identify keys in the cloud UI. Unique enough to avoid collisions on repeated logins.
func AccessTokenExpiry ¶
AccessTokenExpiry decodes the unverified `exp` claim of a JWT and returns it as a UTC time. Verification is the identity provider's job. We only need the expiry to drive UI hints and the "session expired" error path.
func Audience ¶
func Audience() string
Audience returns the OAuth audience, honouring the env override.
func ClientID ¶
func ClientID() string
ClientID returns the OAuth client ID, honouring the env override.
func DeviceCodeURL ¶
func DeviceCodeURL() string
DeviceCodeURL returns the device-code endpoint, honouring the env override.
func IsExpired ¶
IsExpired reports whether the token's exp claim is in the past. Tokens without a parseable exp claim are treated as expired so callers fall through to a re-login path.
func SaveAPIKey ¶
func SaveAPIKey(_ context.Context, store cloud.CredentialStore, in APIKeyInput) error
SaveAPIKey persists the API key + tenant to the provided keychain store. The store is expected to be already scoped to the active profile by the caller.
func TokenURL ¶
func TokenURL() string
TokenURL returns the token endpoint, honouring the env override.
func VerifyAPIKey ¶
func VerifyAPIKey(ctx context.Context, in APIKeyInput) error
VerifyAPIKey checks that the supplied API key + tenant authenticate against the SafeDep data plane. We connect and issue a low-cost RPC. A successful round trip means the key is valid for that tenant.
Types ¶
type APIKeyInput ¶
APIKeyInput is the data needed to persist an API-key credential.
type BootstrapInput ¶
type BootstrapInput struct {
AccessToken string
PreferredTenant string
CreateAPIKey bool
APIKeyExpiryDays int
APIKeyName string
Picker TenantPicker
// ConnFor is the control-plane connection builder. Optional. When
// nil, the package-local default is used. Tests inject a fake.
ConnFor ControlPlaneConnFunc
}
BootstrapInput captures everything PostOAuthBootstrap needs to provision a tenant and (optionally) an API key on top of a fresh access token.
type BootstrapResult ¶
BootstrapResult reports what the bootstrap step accomplished.
func PostOAuthBootstrap ¶
func PostOAuthBootstrap(ctx context.Context, in BootstrapInput) (*BootstrapResult, error)
PostOAuthBootstrap completes the work that follows a successful device flow: discover accessible tenants, pick one, optionally create an API key. It does not write to the keychain. The caller does that, since the keychain store is owned by App.
type ControlPlaneConnFunc ¶
type ControlPlaneConnFunc func(token, tenant string) (*grpc.ClientConn, error)
ControlPlaneConnFunc opens a control-plane gRPC connection for the supplied (token, tenant). tenant may be empty for the bootstrap call to GetUserInfo. Tests inject a fake here. Production callers leave it nil and the package-local default is used.
type DeviceFlowResult ¶
DeviceFlowResult is the outcome of a successful OAuth2 device-code authorisation: the access + refresh token pair returned by the IdP.
func RunDeviceFlow ¶
func RunDeviceFlow(ctx context.Context, sink DeviceFlowSink) (*DeviceFlowResult, error)
RunDeviceFlow performs a complete OAuth2 device-code authorisation against the configured SafeDep identity provider. It blocks until the user completes the flow in their browser or the IdP returns an error.
type DeviceFlowSink ¶
type DeviceFlowSink func(verificationURL, userCode string)
DeviceFlowSink reports the verification URL and user code to the user. Implementations decide how to present them (TUI banner, opening a browser, etc.). The sink runs once before polling begins.
type Status ¶
Status describes what credentials a profile currently holds.
func BuildStatus ¶
BuildStatus inspects the keychain via two resolvers (one per credential type) and returns what the active profile holds. Missing-credentials errors are treated as "not configured" rather than failures.
type TenantPicker ¶
TenantPicker resolves the tenant when the user has access to multiple. Invoked only when len(tenants) > 1 and no preferred tenant matches.