oidc

package
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package oidc provides a small, testable wrapper around the OpenID Connect authorization-code flow on top of coreos/go-oidc and golang.org/x/oauth2.

agent-orca uses it to offer browser "login via OIDC" for the UI API and an interactive login on the External/ACP APIs. A successful login yields an IDTokenPrincipal carrying the IdP's claims; the caller (the apiserver) then mints a short-lived agent-orca-issued JWT (see apiserver.MintSessionJWT) that the existing requireAuth / ExternalAuth middleware already understands, so no parallel auth path is introduced.

OIDC is the industry standard for authenticating into web UIs; this package is the auth-login half of that story. Authorization (RBAC) is deliberately out of scope here — the principal only *carries* the user's groups so a future role mapper can consume them without re-architecting authentication.

Index

Constants

This section is empty.

Variables

View Source
var DefaultScopes = []string{"openid", "email", "profile"}

DefaultScopes returned when Config.Scopes is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	IssuerURL    string
	ClientID     string
	ClientSecret string
	RedirectURI  string
	Scopes       []string // defaults to {"openid","email","profile"}
	// AccessType, when non-empty, is sent as the `access_type` auth-code request
	// parameter. Set to "offline" so Google issues a refresh token (the
	// "offline_access" scope alone is insufficient for Google). Other providers
	// ignore the parameter, so requesting it is safe and makes refresh capture
	// work across IdPs.
	AccessType    string
	PKCE          bool // default true
	ClaimMappings struct {
		UserID string // default "sub"
		Groups string // default "groups"
		Email  string // default "email"
	}
}

Config configures an OIDC login client against an external identity provider.

IssuerURL/ClientID/ClientSecret/RedirectURI are the OAuth2 client credentials registered with the IdP. ClaimMappings selects which IdP claims map onto the resolved principal (used later by RBAC, for now only carried through). PKCE is enabled by default and strongly recommended for browser/public clients.

type IDTokenPrincipal

type IDTokenPrincipal struct {
	Subject    string         // sub
	Issuer     string         // iss — used to resolve the federated tenant
	UserID     string         // mapped from ClaimMappings.UserID
	Email      string         // mapped from ClaimMappings.Email
	Groups     []string       // mapped from ClaimMappings.Groups
	Claims     map[string]any // raw verified claims
	RawIDToken string         // the raw id_token (logging/auditing only)
	// RefreshToken is the refresh_token returned alongside the id_token (if any).
	// It lets the caller (e.g. the aoctl CLI) refresh the session without
	// re-prompting for IdP credentials. The server-side browser flow does not
	// need it and ignores it; it is purely a CLI convenience.
	RefreshToken string
}

IDTokenPrincipal is the resolved identity derived from a verified OIDC ID token. Groups are intentionally not used for authorization yet — they're carried so a future RBAC layer can consume them.

type PrincipalProvider

type PrincipalProvider interface {
	// AuthCodeURL returns the IdP login URL and the PKCE code_verifier (empty when
	// PKCE is disabled). nonce is the OIDC nonce bound to the ID token.
	AuthCodeURL(state, nonce string) (authURL, codeVerifier string)
	// ExchangeAndVerify exchanges the auth code for tokens, verifies the ID token
	// (signature via JWKS, iss, aud, exp/nbf, nonce) and returns the resolved
	// principal.
	ExchangeAndVerify(ctx context.Context, code, nonce, codeVerifier string) (*IDTokenPrincipal, error)
}

PrincipalProvider is the surface handlers depend on; *Provider satisfies it and tests can substitute a fake.

type Provider

type Provider struct {
	// contains filtered or unexported fields
}

Provider is the default PrincipalProvider.

func NewProvider

func NewProvider(ctx context.Context, cfg Config) (*Provider, error)

NewProvider discovers the IdP via its well-known configuration and returns a configured Provider. PKCE defaults to disabled unless cfg.PKCE is true.

func (*Provider) AuthCodeURL

func (p *Provider) AuthCodeURL(state, nonce string) (string, string)

AuthCodeURL implements PrincipalProvider.

func (*Provider) ExchangeAndVerify

func (p *Provider) ExchangeAndVerify(ctx context.Context, code, nonce, codeVerifier string) (*IDTokenPrincipal, error)

ExchangeAndVerify implements PrincipalProvider.

func (*Provider) Refresh

func (p *Provider) Refresh(ctx context.Context, refreshToken string) (idToken, newRefreshToken string, err error)

Refresh exchanges a refresh_token for a fresh id_token at the IdP, verifies it (signature via JWKS, iss, aud — nonce is not bound across a refresh) and returns the new id_token plus any rotated refresh token. It is the path the aoctl CLI uses to keep a federated session alive beyond the id_token's short lifetime without re-prompting for credentials.

Returns an error if the IdP did not return a new id_token (some providers omit it on refresh); in that case the caller should re-authenticate.

Jump to

Keyboard shortcuts

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