oauth

package
v0.0.0-...-bd7e1f2 Latest Latest
Warning

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

Go to latest
Published: May 18, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

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

func NewState

func NewState() (string, error)

NewState returns a random URL-safe state token suitable for use as the OAuth `state` parameter. 32 bytes of entropy, base64url-encoded without padding. Callers compare the value verbatim across the authorize → callback hop.

Types

type CallbackResult

type CallbackResult struct {
	Code  string
	State string
}

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

func NewListener(port int) (*Listener, error)

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

func (l *Listener) Close() error

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

func (l *Listener) Port() int

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

func (l *Listener) RedirectURI() string

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

type Opener interface {
	Open(url string) error
}

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.

func NewPKCE

func NewPKCE() (PKCEPair, error)

NewPKCE returns a fresh PKCE verifier + challenge pair using S256. The verifier is 32 bytes of crypto-random entropy, base64url- encoded without padding (43 characters); the challenge is the base64url-encoded SHA-256 of the verifier per RFC 7636 §4.2.

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.

Jump to

Keyboard shortcuts

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