deviceauth

package module
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Sep 1, 2026 License: MIT Imports: 14 Imported by: 0

README

deviceauth

deviceauth provides reusable OAuth 2.0 Device Authorization Grant UX and credential storage for Go command-line applications.

It deliberately stays below product and command-framework concerns:

  • RFC 8628 protocol behavior is delegated to golang.org/x/oauth2.
  • browser launch is best-effort and always has a visible manual fallback;
  • credentials use the operating system credential store by default;
  • plaintext JSON storage is available only when a caller explicitly selects it;
  • callers own product names, OAuth endpoints, client IDs, scopes, and commands.
result, err := deviceauth.Login(ctx, deviceauth.LoginOptions{
	OAuthConfig: oauth2.Config{
		ClientID: "example-cli",
		Scopes:   []string{"account:read"},
		Endpoint: oauth2.Endpoint{
			DeviceAuthURL: "https://cloud.example.com/oauth/device/code",
			TokenURL:      "https://cloud.example.com/oauth/token",
		},
	},
	DeviceInfo: deviceauth.DeviceInfo{
		Name: "Alex's MacBook Pro", OS: "darwin", Arch: "arm64", ClientVersion: "1.2.3",
	},
	OpenBrowser: deviceauth.OpenBrowser,
	Output:      os.Stdout,
	ErrorOutput: os.Stderr,
})

DeviceInfo is sent as optional device-authorization request parameters so a server can identify the requesting device during consent. It is informational, untrusted metadata; authorization state and timestamps remain server-owned.

The module is MIT licensed.

Documentation

Overview

Package deviceauth provides reusable OAuth 2.0 device-login UX and credential storage for command-line applications.

Index

Constants

This section is empty.

Variables

View Source
var ErrCredentialNotFound = errors.New("deviceauth: credential not found")

ErrCredentialNotFound reports that no credential exists for a configured service/account pair.

Functions

func OpenBrowser

func OpenBrowser(rawURL string) error

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.

Types

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"`
	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

type DeviceInfo struct {
	Name          string
	OS            string
	Arch          string
	ClientVersion string
}

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 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

func NewFileStore(path string) (*FileStore, error)

NewFileStore returns a plaintext store at path.

func (*FileStore) Delete

func (s *FileStore) Delete() error

Delete removes the plaintext credential file. Absence succeeds.

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 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 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.

Jump to

Keyboard shortcuts

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