Documentation
¶
Overview ¶
Package auth implements OAuth 2.0 PKCE flow scaffolding for bee.
Generic by design: no provider is hard-coded. Users add OAuth client_id + endpoints under [providers.<name>.oauth] in ~/.bee/config.toml, then run /login <name> to drive the flow and persist tokens under ~/.bee/auth/.
Index ¶
- func BuildAuthorizeURL(authorizeEndpoint, clientID, redirectURI, codeChallenge, state, scope string) string
- func BuildAuthorizeURLWithExtras(authorizeEndpoint, clientID, redirectURI, codeChallenge, state, scope string, ...) string
- func Challenge(verifier string) string
- func DefaultDir() (string, error)
- func DeleteAPIKey(dir, provider string) error
- func DeleteToken(dir, provider string) error
- func ExtractClaim(jwt, path string) string
- func GenerateVerifier() (string, error)
- func HasAPIKey(dir, provider string) bool
- func LoadAPIKey(dir, provider string) (string, error)
- func SaveAPIKey(dir, provider, key string) error
- func SaveToken(dir, provider string, tok *Token) error
- type CallbackResult
- type LoginConfig
- type LoopbackServer
- type Token
- func ExchangeCode(ctx context.Context, tokenURL, clientID, code, verifier, redirectURI string) (*Token, error)
- func LoadToken(dir, provider string) (*Token, error)
- func Login(ctx context.Context, cfg LoginConfig) (*Token, error)
- func RefreshToken(ctx context.Context, tokenURL, clientID, refreshToken string) (*Token, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildAuthorizeURL ¶
func BuildAuthorizeURL(authorizeEndpoint, clientID, redirectURI, codeChallenge, state, scope string) string
BuildAuthorizeURL composes the full authorize URL with PKCE params.
func BuildAuthorizeURLWithExtras ¶
func BuildAuthorizeURLWithExtras(authorizeEndpoint, clientID, redirectURI, codeChallenge, state, scope string, extras map[string]string) string
BuildAuthorizeURLWithExtras is like BuildAuthorizeURL but appends extra vendor-specific params (audience, prompt, id_token_hint). Extras override standard params if they collide — caller's responsibility.
func DefaultDir ¶
DefaultDir returns ~/.bee/auth, creating it 0700 if missing.
func DeleteAPIKey ¶
DeleteAPIKey removes the saved key file. No-op when missing.
func DeleteToken ¶
DeleteToken removes the token file. No-op if missing.
func ExtractClaim ¶
ExtractClaim decodes the unverified payload of a JWT and returns the value of the named claim, or "" if absent/non-string.
path supports two forms:
- "foo" → top-level "foo"
- "https://example.com/x.bar" → nested: first segment is the FULL claim name (URI claims allowed), subsequent dot-separated segments traverse into the nested object.
No signature verification. Caller must ensure the JWT came from a trusted source (e.g. just-completed TLS-secured OAuth exchange).
func GenerateVerifier ¶
GenerateVerifier returns a 43-128 char URL-safe code_verifier per RFC 7636. Uses 64 random bytes -> 86 chars after base64url-no-pad. Cryptographically strong.
func HasAPIKey ¶
HasAPIKey reports whether a key file exists for provider (best-effort — errors are treated as "no key" so callers don't have to fan out error handling for a probe).
func LoadAPIKey ¶
LoadAPIKey reads a previously saved api key. Returns ("", nil) if the file is absent — callers fall back to env / treat as unauthenticated.
func SaveAPIKey ¶
SaveAPIKey writes a plain-text api key to <dir>/<provider>.key with 0600 perms. Used for providers that authenticate via static api keys (no oauth flow) when the user enters one through /login. Empty keys are rejected.
Types ¶
type CallbackResult ¶
CallbackResult holds the auth code from the OAuth redirect.
type LoginConfig ¶
type LoginConfig struct {
ClientID string
AuthorizeEndpoint string
TokenEndpoint string
Scope string
RedirectPath string
Stdout io.Writer
// RedirectPort pins the loopback port (0 = random). Some providers
// require an exact registered redirect_uri.
RedirectPort int
// ExtraAuthorizeParams are merged into the authorize URL query string
// (e.g. {"audience": "..."}).
ExtraAuthorizeParams map[string]string
// AccountIDClaim, when set, instructs Login to decode id_token and
// extract this claim path into Token.AccountID. Dotted path; first
// segment may be a fully-qualified URI claim (e.g.
// "https://api.openai.com/auth.chatgpt_account_id").
AccountIDClaim string
}
LoginConfig captures everything Login needs to drive the PKCE flow.
type LoopbackServer ¶
type LoopbackServer struct {
URL string
Result <-chan CallbackResult
// contains filtered or unexported fields
}
LoopbackServer runs a one-shot HTTP server on a random localhost port. The caller registers s.URL as the redirect_uri, opens the authorize URL in a browser, and reads exactly one value from Result.
func StartLoopback ¶
func StartLoopback(ctx context.Context, path string) (*LoopbackServer, error)
StartLoopback binds 127.0.0.1:<random> and serves a single handler at path (defaults to /callback). Context cancellation triggers shutdown.
func StartLoopbackOn ¶
StartLoopbackOn is like StartLoopback but binds to a fixed port. Pass 0 for random. Used when the provider requires an exact redirect_uri match.
func (*LoopbackServer) Close ¶
func (s *LoopbackServer) Close() error
Close stops the loopback server. Safe to call multiple times.
type Token ¶
type Token struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token,omitempty"`
ExpiresIn int `json:"expires_in"`
TokenType string `json:"token_type"`
IssuedAt time.Time `json:"issued_at"`
// IDToken is the OIDC id_token, when the provider returns one. Carries
// per-account claims like ChatGPT's chatgpt_account_id.
IDToken string `json:"id_token,omitempty"`
// AccountID is extracted from IDToken at login time and cached so the
// provider adapter doesn't re-decode the JWT on every request.
AccountID string `json:"account_id,omitempty"`
}
Token mirrors the standard OAuth 2.0 token endpoint response.
func ExchangeCode ¶
func ExchangeCode(ctx context.Context, tokenURL, clientID, code, verifier, redirectURI string) (*Token, error)
ExchangeCode swaps an authorization code for a token via the token endpoint.
func Login ¶
func Login(ctx context.Context, cfg LoginConfig) (*Token, error)
Login runs the full PKCE flow: starts a loopback server, opens the browser, waits for the callback, validates state, exchanges the code, and returns the resulting Token. Caller persists via SaveToken.
func RefreshToken ¶
RefreshToken swaps a refresh token for a new access token.