Documentation
¶
Overview ¶
Package deviceauth provides reusable OAuth 2.0 device-login UX and credential storage for command-line applications.
Index ¶
- Variables
- func OpenBrowser(rawURL string) error
- func ValidateRequiredScopes(granted, required []string) error
- type Authentication
- type Client
- func (c *Client) DeviceLogin(ctx context.Context, options DeviceLoginOptions) (LoginResult, error)
- func (c *Client) DeviceLoginAndStore(ctx context.Context, options DeviceLoginOptions, store Store) (Authentication, error)
- func (c *Client) Issuer() string
- func (c *Client) Logout(ctx context.Context, store Store) error
- func (c *Client) NewKeyringStore() (Store, error)
- func (c *Client) OAuthConfig() oauth2.Config
- func (c *Client) Revoke(ctx context.Context, token string) error
- func (c *Client) ScopedStore(store Store) Store
- func (c *Client) UserInfo(ctx context.Context, token *oauth2.Token) (Identity, error)
- type ClientConfig
- type Credential
- type DeviceInfo
- type DeviceLoginOptions
- type FileStore
- type Identity
- type KeyringStore
- type LoginOptions
- type LoginResult
- type ReplacementRevocationWarning
- type ResponseError
- type Store
- type TokenTransformer
Constants ¶
This section is empty.
Variables ¶
var ErrCredentialNotFound = errors.New("deviceauth: credential not found")
ErrCredentialNotFound reports that no credential exists for a configured service/account pair.
var ErrCredentialScopeMismatch = errors.New("deviceauth: credential issuer or client ID does not match")
ErrCredentialScopeMismatch reports a credential that was saved for a different issuer or OAuth client. Callers must not use it as a session for the current Client.
Functions ¶
func OpenBrowser ¶
OpenBrowser opens rawURL in the user's default browser. Callers should treat errors as a reason to show a manual URL, not as a failed authorization.
func ValidateRequiredScopes ¶ added in v0.1.0
ValidateRequiredScopes verifies that every explicitly required scope was granted by the issuer. With no requirements it succeeds; an absent or reduced granted scope claim never becomes a synthetic requested grant.
Types ¶
type Authentication ¶ added in v0.1.0
type Authentication struct {
Login LoginResult
SessionToken *oauth2.Token
Identity Identity
Credential Credential
// Warnings report completed logins that need operator attention but are
// safe to use. In particular, a new local credential remains valid when a
// replaced server token could not be revoked.
Warnings []error
}
Authentication is the complete, validated result of DeviceLoginAndStore.
type Client ¶ added in v0.1.0
type Client struct {
// contains filtered or unexported fields
}
Client provides the neutral client-side half of a device authorization service. It knows the standard endpoint layout below its issuer, but does not depend on a particular identity provider or product.
func NewClient ¶ added in v0.1.0
func NewClient(config ClientConfig) (*Client, error)
NewClient validates config and returns a client for an OAuth service.
func (*Client) DeviceLogin ¶ added in v0.1.0
func (c *Client) DeviceLogin(ctx context.Context, options DeviceLoginOptions) (LoginResult, error)
DeviceLogin starts and completes the RFC 8628 flow using this client's configured service. It preserves the package Login function for existing consumers such as OVDB.
func (*Client) DeviceLoginAndStore ¶ added in v0.1.0
func (c *Client) DeviceLoginAndStore(ctx context.Context, options DeviceLoginOptions, store Store) (Authentication, error)
DeviceLoginAndStore completes device authorization, validates userinfo, and saves a credential bound to this issuer and client. The supplied store is scoped automatically; this prevents accidental reuse of the same file or keyring account by another issuer/client pair.
func (*Client) Issuer ¶ added in v0.1.0
Issuer returns the canonical base URL configured for this client.
func (*Client) Logout ¶ added in v0.1.0
Logout revokes the stored access token at the issuer before removing the local credential. A failed revoke leaves the local credential in place so a caller can retry rather than falsely reporting a successful logout.
func (*Client) NewKeyringStore ¶ added in v0.1.0
NewKeyringStore returns an issuer/client-isolated keyring store. It requires the product-specific KeyringService and KeyringAccount from ClientConfig.
func (*Client) OAuthConfig ¶ added in v0.1.0
OAuthConfig returns the configuration needed by the existing Login API.
func (*Client) ScopedStore ¶ added in v0.1.0
ScopedStore wraps store so every saved credential is bound to this issuer and client. Load rejects a credential saved for a different pair.
type ClientConfig ¶ added in v0.1.0
type ClientConfig struct {
Issuer string
ClientID string
Scopes []string
// RequiredScopes is the subset of requested Scopes a caller requires for a
// usable session. It is checked against the issuer's authoritative
// userinfo scope claim; an omitted scope claim is never treated as a grant.
RequiredScopes []string
KeyringService string
KeyringAccount string
}
ClientConfig configures a reusable device-authorization client for one OAuth issuer and public CLI client. Issuer is the base URL, for example "https://auth.sneat.co". KeyringService and KeyringAccount are product chosen names used only when NewKeyringStore is called.
type Credential ¶
type Credential struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type,omitempty"`
RefreshToken string `json:"refresh_token,omitempty"`
Expiry time.Time `json:"expiry,omitempty"`
// Issuer and ClientID bind a persisted credential to the authorization
// service and public OAuth client that issued it. They are set by a
// Client's ScopedStore; the fields remain optional for backwards
// compatibility with credentials saved by older callers.
Issuer string `json:"issuer,omitempty"`
ClientID string `json:"client_id,omitempty"`
AccountID string `json:"account_id,omitempty"`
AccountName string `json:"account_name,omitempty"`
Scopes []string `json:"scopes,omitempty"`
}
Credential is the persisted result of a device authorization.
type DeviceInfo ¶ added in v0.0.2
DeviceInfo describes the command-line device requesting authorization. Authorization servers may display these optional, untrusted values during consent and retain them with the resulting grant.
type DeviceLoginOptions ¶ added in v0.1.0
type DeviceLoginOptions struct {
DeviceInfo DeviceInfo
OpenBrowser func(string) error
Output io.Writer
ErrorOutput io.Writer
TokenTransformer TokenTransformer
}
DeviceLoginOptions are the presentation and device details used during a device authorization. The issuer, client ID, scopes, and endpoints always come from Client.
type FileStore ¶
type FileStore struct {
// contains filtered or unexported fields
}
FileStore is an explicitly insecure 0600 JSON credential store. It is provided for headless environments only; callers should require a user flag before selecting it.
func NewFileStore ¶
NewFileStore returns a plaintext store at path.
func (*FileStore) Load ¶
func (s *FileStore) Load() (Credential, error)
Load reads and validates the plaintext credential file.
func (*FileStore) Save ¶
func (s *FileStore) Save(credential Credential) error
Save atomically writes a credential with directory mode 0700 and file mode 0600. The token remains plaintext and must be treated as sensitive.
type Identity ¶ added in v0.1.0
Identity is a validated response from the issuer's userinfo endpoint. Audience is always non-empty and contains ClientID after UserInfo returns.
type KeyringStore ¶
type KeyringStore struct {
// contains filtered or unexported fields
}
KeyringStore keeps a credential in the operating system credential store.
func NewKeyringStore ¶
func NewKeyringStore(service, account string) (*KeyringStore, error)
NewKeyringStore returns a secure credential store. service should identify the CLI and account should normally identify the authorization host.
func (*KeyringStore) Delete ¶
func (s *KeyringStore) Delete() error
Delete removes the credential. Deleting an absent credential succeeds.
func (*KeyringStore) Load ¶
func (s *KeyringStore) Load() (Credential, error)
Load reads and validates the credential in the operating system keyring.
func (*KeyringStore) Save ¶
func (s *KeyringStore) Save(credential Credential) error
Save stores credential as one JSON value in the operating system keyring.
type LoginOptions ¶
type LoginOptions struct {
OAuthConfig oauth2.Config
DeviceInfo DeviceInfo
OpenBrowser func(string) error
Output io.Writer
ErrorOutput io.Writer
}
LoginOptions configures one browser-approved OAuth 2.0 device login. Product-specific commands own the OAuth endpoints, client ID, and scopes.
type LoginResult ¶
type LoginResult struct {
Token *oauth2.Token
Authorization *oauth2.DeviceAuthResponse
BrowserOpened bool
}
LoginResult contains the issued token and the authorization prompt that led to it. BrowserOpened reports only whether the launcher succeeded; a failed launcher is intentionally non-fatal because the visible URL remains usable.
func Login ¶
func Login(ctx context.Context, options LoginOptions) (LoginResult, error)
Login starts an RFC 8628 device authorization, shows the user code and URL, attempts to open the verification page, and polls until approval, denial, expiry, or context cancellation.
type ReplacementRevocationWarning ¶ added in v0.1.0
type ReplacementRevocationWarning struct {
Cause error
}
ReplacementRevocationWarning reports that a new credential was saved but the previous credential could not be revoked. The authentication succeeded; callers may surface this warning and retry revocation later.
func (*ReplacementRevocationWarning) Error ¶ added in v0.1.0
func (e *ReplacementRevocationWarning) Error() string
func (*ReplacementRevocationWarning) Unwrap ¶ added in v0.1.0
func (e *ReplacementRevocationWarning) Unwrap() error
type ResponseError ¶ added in v0.1.0
ResponseError is a redacted non-success response from the authorization service. It deliberately excludes arbitrary response text, which may carry secrets or HTML from a proxy. OAuthError is populated only for a safe OAuth error code.
func (*ResponseError) Error ¶ added in v0.1.0
func (e *ResponseError) Error() string
type Store ¶
type Store interface {
Save(Credential) error
Load() (Credential, error)
Delete() error
}
Store persists and removes one credential selected by the concrete store's service/account configuration.
type TokenTransformer ¶ added in v0.1.0
TokenTransformer converts the token returned by the device token endpoint into the session token accepted by userinfo and the product API. It is deliberately identity-provider-neutral: a consumer may exchange a one-use bootstrap token for its own session without this package importing that provider's SDK.
The input is always the unmodified token returned by DeviceLogin. The transformer must return a non-nil token with a non-empty access token.