Documentation
¶
Overview ¶
Package oauth implements the client-side primitives for the OAuth dance the runtime drives at binding-setup time per ADR-0006.
The package is intentionally narrow: it exposes the small set of utilities the CLI needs to drive the server-side init/finish flow against an interactive user — generate a PKCE verifier+challenge pair, open the user's browser to the provider's authorize URL, and await the OAuth callback on a loopback HTTP listener.
Token exchange and refresh do not live here; they live in the runtime side (server handler + credential resolver) so the same machinery serves a future hosted Web UI without re-architecting.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type CallbackResult ¶
CallbackResult is the data extracted from the provider's redirect to the loopback listener. State is returned verbatim so the caller can compare it against the value sent at the authorize step (the listener does not know what value to expect).
type Listener ¶
type Listener struct {
// contains filtered or unexported fields
}
Listener captures the OAuth callback on a loopback HTTP server. One instance handles exactly one callback then shuts down.
func NewListener ¶
NewListener binds an `http.Server` on `127.0.0.1:port` (use port 0 to let the OS pick a free port — read the port back from Listener.Port). The server serves a single endpoint at `/callback` that captures `code` + `state` query params and renders a "you can close this tab" HTML page.
Lifecycle:
- Listener.Port returns the bound port (useful when the caller passed 0).
- Listener.Await blocks until the first callback arrives or ctx is cancelled.
- Listener.Close shuts down the server. Idempotent; safe to defer.
func (*Listener) Await ¶
func (l *Listener) Await(ctx context.Context) (CallbackResult, error)
Await blocks until the OAuth callback arrives or ctx is cancelled. Returns the captured `code` + `state`. The listener consumes exactly one callback then continues running until Listener.Close is called.
func (*Listener) Close ¶
Close shuts down the loopback HTTP server. Safe to call multiple times; subsequent calls are no-ops. Use a deferred Close to guarantee the listener is torn down even on error paths.
func (*Listener) Port ¶
Port returns the bound TCP port — useful when the caller passed 0 to NewListener and let the OS choose. Suitable for substituting into a redirect_uri before opening the user's browser.
func (*Listener) RedirectURI ¶
RedirectURI returns the canonical loopback redirect URI for the listener's port: `http://127.0.0.1:<port>/callback`. Suitable for the `redirect_uri` parameter in the authorize URL and the token exchange request.
type Opener ¶
Opener opens a URL in the user's default browser. The default implementation SystemBrowser dispatches to the platform-native command (`open` on macOS, `xdg-open` on Linux, `start` via cmd.exe on Windows). Tests substitute their own Opener.
type PKCEPair ¶
type PKCEPair struct {
// Verifier is the URL-safe-base64-encoded random secret. 43–128
// chars per RFC 7636 §4.1; this implementation always produces
// 43 chars (32 random bytes → 43 base64url-no-pad chars).
Verifier string
// Challenge is base64url(sha256(verifier)) — 43 chars without
// padding, suitable for inclusion in the authorize URL.
Challenge string
// Method is the challenge method name. Always "S256" in v1.
Method string
}
PKCEPair is the verifier + challenge pair produced by NewPKCE per RFC 7636. The verifier is the secret the client retains and sends at token exchange; the challenge is the base64url(sha256(verifier)) the client sends at the authorize step. The runtime uses S256 only in v1; the `plain` method is rejected.
type SystemBrowser ¶
type SystemBrowser struct{}
SystemBrowser is the default Opener. The zero value is ready to use.
func (SystemBrowser) Open ¶
func (SystemBrowser) Open(url string) error
Open dispatches to the platform's native "open URL" command. Returns an error if the platform is unsupported or the spawned process fails.