Documentation
¶
Overview ¶
Package oauth implements the client side of the CircleCI OAuth 2.0 Authorization Code + PKCE flow (RFC 6749 + RFC 7636 + RFC 8252) with Pushed Authorization Requests (RFC 9126).
The flow:
- Start a localhost listener on 127.0.0.1:0.
- Assemble the authorization request — PKCE code challenge, state, and the loopback redirect_uri — and POST it to the server's PAR endpoint (/oauth/par), which returns a request_uri.
- Build a short authorize URL carrying only client_id and request_uri.
- The caller opens that URL in the user's browser.
- Wait for the OAuth provider to redirect to the loopback server with ?code=...&state=... and validate the state.
- Exchange the captured code (with the PKCE verifier) for a token via POST /oauth/token.
Pushing the request keeps sensitive parameters off the browser URL and makes the URL short enough to log and click.
Two entry points share the same underlying flow:
- Start lands the user on the OAuth login page.
- StartSignup appends signup=true so unauthenticated users land on the signup page instead. Everything past the authorize step is identical.
Index ¶
Constants ¶
const ClientID = "circleci-cli"
ClientID is the CircleCI-registered OAuth client identifier for the CLI.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Flow ¶
type Flow struct {
// AuthorizeURL is the URL the user's browser must visit to start the flow.
AuthorizeURL string
// contains filtered or unexported fields
}
Flow is an in-progress authorization-code+PKCE exchange.
Typical usage:
flow, err := oauth.Start(ctx, host)
if err != nil { ... }
defer flow.Close()
// open flow.AuthorizeURL in the user's browser
res, err := flow.Wait(ctx)
func Start ¶
Start binds a loopback listener, generates PKCE + state, and returns a Flow whose AuthorizeURL the caller should open in the user's browser. The returned Flow owns the listener and HTTP server until Close is called.
host is the CircleCI base URL (e.g. https://circleci.com). The OAuth endpoints are derived as host + /oauth/authorize and host + /oauth/token. deviceID and osInfo are appended as query parameters on the authorize URL so the server can correlate requests by CLI installation and platform.
func StartSignup ¶
StartSignup is like Start, but appends signup=true to the authorize URL so the OAuth provider routes unauthenticated users to the signup page rather than the login page. The PKCE handshake, loopback callback, and token exchange are otherwise identical.
type Result ¶
Result is the outcome of a successful authorization. The Verifier must be presented when exchanging Code for an access token.
type TokenResponse ¶
type TokenResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type,omitempty"`
ExpiresIn int64 `json:"expires_in,omitempty"`
RefreshToken string `json:"refresh_token,omitempty"`
}
TokenResponse is the parsed response from POST /oauth/token. It mirrors the OAuth 2.0 wire format; we expose this rather than oauth2.Token directly so the JSON output is deterministic (oauth2.Token.Expiry is computed from time.Now() at parse time, which makes it non-reproducible across runs).