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 ¶
- Variables
- type Config
- type IDTokenPrincipal
- type PrincipalProvider
- type Provider
- func (p *Provider) AuthCodeURL(state, nonce string) (string, string)
- func (p *Provider) ExchangeAndVerify(ctx context.Context, code, nonce, codeVerifier string) (*IDTokenPrincipal, error)
- func (p *Provider) Refresh(ctx context.Context, refreshToken string) (idToken, newRefreshToken string, err error)
Constants ¶
This section is empty.
Variables ¶
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 ¶
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 ¶
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.