Documentation
¶
Overview ¶
Package auth implements GitHub OAuth device code flow authentication and Copilot API token management with automatic caching and refresh.
Index ¶
- Variables
- func IsInteractiveLoginRequired(err error) bool
- type AccessTokenResponse
- type AuthPreferences
- type AuthSource
- type AuthStatus
- type Authenticator
- func (a *Authenticator) GetToken(ctx context.Context) (string, error)
- func (a *Authenticator) GetTokenNonInteractive(ctx context.Context) (string, error)
- func (a *Authenticator) GitHubCLIAutoSignInEnabled() bool
- func (a *Authenticator) IsSignedIn() bool
- func (a *Authenticator) PollForAuthorization(ctx context.Context, dcResp *DeviceCodeResponse) error
- func (a *Authenticator) RefreshTokenNonInteractive(ctx context.Context) (string, error)
- func (a *Authenticator) RequestDeviceCode(ctx context.Context) (*DeviceCodeResponse, error)
- func (a *Authenticator) SignInWithGitHubCLI(ctx context.Context) error
- func (a *Authenticator) SignOut() error
- func (a *Authenticator) Status() AuthStatus
- type CopilotTokenResponse
- type CopilotUserResponse
- type DeviceCodeResponse
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNotAuthenticated indicates that no reusable GitHub access token was // available for a token refresh attempt. ErrNotAuthenticated = errors.New("not authenticated") // ErrInvalidAccessToken indicates that a stored GitHub access token exists // but can no longer be exchanged for a Copilot token. ErrInvalidAccessToken = errors.New("invalid access token") )
Functions ¶
func IsInteractiveLoginRequired ¶ added in v0.9.0
IsInteractiveLoginRequired reports whether resolving the error should fall back to an interactive device-code login flow.
Types ¶
type AccessTokenResponse ¶
type AccessTokenResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
Scope string `json:"scope"`
Error string `json:"error,omitempty"`
ErrorDescription string `json:"error_description,omitempty"`
}
AccessTokenResponse is the response from GitHub's OAuth access token endpoint.
type AuthPreferences ¶ added in v0.10.0
type AuthPreferences struct {
GitHubCLIAutoSignIn bool `json:"github_cli_auto_sign_in,omitempty"`
}
AuthPreferences stores explicit authentication preferences shared by the CLI and menubar app.
type AuthSource ¶ added in v0.10.0
type AuthSource string
AuthSource identifies the source of the currently usable authentication state.
const ( AuthSourceNone AuthSource = "none" AuthSourceEnv AuthSource = "env" AuthSourceVekil AuthSource = "vekil" AuthSourceGitHubCLI AuthSource = "github-cli" )
type AuthStatus ¶ added in v0.10.0
type AuthStatus struct {
SignedIn bool
Source AuthSource
GitHubCLIAutoSignIn bool
SignedOut bool
HasValidCopilotCache bool
HasVekilAccessToken bool
}
AuthStatus is a fast snapshot of local authentication state. It never shells out to external tools such as gh.
type Authenticator ¶
type Authenticator struct {
// DisableAutoDeviceFlow prevents refreshToken from falling through to the
// interactive device-code flow. When true, callers (e.g. the menubar app)
// are expected to drive the flow themselves via RequestDeviceCode /
// PollForAuthorization.
DisableAutoDeviceFlow bool
// contains filtered or unexported fields
}
Authenticator manages GitHub OAuth and Copilot API tokens. It handles the device code flow, token caching to disk, and automatic refresh using a read-write mutex for concurrent access.
func NewAuthenticator ¶
func NewAuthenticator(tokenDir string) (*Authenticator, error)
NewAuthenticator creates an Authenticator that stores tokens in tokenDir. If tokenDir is empty, it defaults to ~/.config/vekil.
func NewTestAuthenticator ¶
func NewTestAuthenticator(token string) *Authenticator
NewTestAuthenticator creates an Authenticator pre-loaded with a token for testing.
func (*Authenticator) GetToken ¶
func (a *Authenticator) GetToken(ctx context.Context) (string, error)
GetToken returns a valid Copilot API token, refreshing it if necessary. It is safe for concurrent use.
func (*Authenticator) GetTokenNonInteractive ¶
func (a *Authenticator) GetTokenNonInteractive(ctx context.Context) (string, error)
GetTokenNonInteractive returns a valid Copilot API token without falling back to the interactive device-code flow.
func (*Authenticator) GitHubCLIAutoSignInEnabled ¶ added in v0.10.0
func (a *Authenticator) GitHubCLIAutoSignInEnabled() bool
GitHubCLIAutoSignInEnabled reports whether the user has explicitly opted in to automatic GitHub CLI sign-in. Malformed preferences are treated as false.
func (*Authenticator) IsSignedIn ¶
func (a *Authenticator) IsSignedIn() bool
IsSignedIn reports whether the authenticator has a usable or explicitly configured local authentication source.
func (*Authenticator) PollForAuthorization ¶
func (a *Authenticator) PollForAuthorization(ctx context.Context, dcResp *DeviceCodeResponse) error
PollForAuthorization polls GitHub until the user authorizes the device code, then saves the access token and exchanges it for a Copilot API token. It acquires the write lock internally.
func (*Authenticator) RefreshTokenNonInteractive ¶ added in v0.9.0
func (a *Authenticator) RefreshTokenNonInteractive(ctx context.Context) (string, error)
RefreshTokenNonInteractive refreshes the Copilot API token using existing GitHub authentication without falling back to the interactive device-code flow. Unlike GetTokenNonInteractive, it bypasses any cached Copilot token so callers can verify that the underlying GitHub auth is still refreshable.
func (*Authenticator) RequestDeviceCode ¶
func (a *Authenticator) RequestDeviceCode(ctx context.Context) (*DeviceCodeResponse, error)
RequestDeviceCode initiates the GitHub device-code flow by requesting a device code and user code from GitHub. The caller should present the UserCode and VerificationURI to the user, then call PollForAuthorization. No lock is required — only immutable fields (client) are accessed.
func (*Authenticator) SignInWithGitHubCLI ¶ added in v0.10.0
func (a *Authenticator) SignInWithGitHubCLI(ctx context.Context) error
SignInWithGitHubCLI explicitly signs in using the currently authenticated GitHub CLI account. The GitHub CLI token is kept only in memory as a short-lived Copilot bearer token and is never persisted by Vekil.
func (*Authenticator) SignOut ¶
func (a *Authenticator) SignOut() error
SignOut clears all authentication state from memory and removes persisted token files from disk. It is safe for concurrent use.
func (*Authenticator) Status ¶ added in v0.10.0
func (a *Authenticator) Status() AuthStatus
Status returns a fast snapshot of local authentication state without making network requests or invoking external commands.
type CopilotTokenResponse ¶
type CopilotTokenResponse struct {
Token string `json:"token"`
ExpiresAt int64 `json:"expires_at"`
ErrorDetails string `json:"error_details,omitempty"`
}
CopilotTokenResponse is the response from the Copilot token exchange endpoint.
type CopilotUserResponse ¶ added in v0.10.0
type CopilotUserResponse struct {
Login string `json:"login,omitempty"`
ChatEnabled *bool `json:"chat_enabled,omitempty"`
}
CopilotUserResponse is the response from the Copilot user endpoint used to validate GitHub CLI tokens. Only the fields needed for validation are modeled.
type DeviceCodeResponse ¶
type DeviceCodeResponse struct {
DeviceCode string `json:"device_code"`
UserCode string `json:"user_code"`
VerificationURI string `json:"verification_uri"`
ExpiresIn int `json:"expires_in"`
Interval int `json:"interval"`
}
DeviceCodeResponse is the response from GitHub's device code endpoint.