Documentation
¶
Overview ¶
Package oidc is an OpenID Connect provider for the federated sign-in seam: authorization code flow with PKCE, discovery, and an id_token verified against the provider's published keys.
Why this lives in the framework module and not in providers/ ¶
The sibling modules (providers/ldap, drivers/*, exporters/*) exist for one measured reason: so an application that does not use a backend does not compile its third-party dependencies (ADR-030/031). This provider has NONE — discovery is net/http and encoding/json, PKCE is crypto/sha256, and the id_token is verified with the JWT library the framework already links. A Go package nobody imports costs nothing in anybody's binary, so extracting it would add a module, a tag, a manifest entry and a release train phase to solve a problem that does not exist here.
What it does and does not decide ¶
The framework owns the anti-forgery state (see pkg/auth/federated): this provider never sees it and cannot forget it. What it owns is the protocol — where to send the browser, how to exchange a code, and what a valid answer from the identity provider looks like.
Index ¶
Constants ¶
const ProviderName = "oidc"
ProviderName is the name this provider registers under. An operator configures an INSTANCE of it: `auth_federated: [{name: corp, type: oidc}]`.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Config ¶
type Config struct {
// Issuer is the provider's base URL, e.g.
// "https://accounts.example.com". Discovery hangs off it.
Issuer string `koanf:"issuer"`
// ClientID and ClientSecret identify this application.
ClientID string `koanf:"client_id"`
ClientSecret string `koanf:"client_secret"`
// Scopes defaults to "openid email profile". "openid" is added when
// missing: without it the provider returns an OAuth token and no
// identity, which fails later and confusingly.
Scopes []string `koanf:"scopes"`
// RoleClaim is the claim carrying group or role membership, e.g.
// "groups" or "roles". Empty means the identity arrives with no
// roles rather than with a guess.
RoleClaim string `koanf:"role_claim"`
// UsernameClaim defaults to "preferred_username", then "email".
UsernameClaim string `koanf:"username_claim"`
// SkipIssuerVerification exists for a provider whose discovery
// document disagrees with its own issuer URL. It is a footgun with a
// name, so an audit can find it.
SkipIssuerVerification bool `koanf:"skip_issuer_verification"`
// Timeout for discovery and token exchange. Default 10s.
Timeout time.Duration `koanf:"timeout"`
}
Config is the `auth.<instance>.*` subtree an operator fills in.
type Provider ¶
type Provider struct {
// contains filtered or unexported fields
}
Provider implements federated.Provider.
func (*Provider) Begin ¶
func (p *Provider) Begin(ctx context.Context, req federated.BeginRequest) (federated.Redirect, error)
Begin implements federated.Provider: it returns where to send the browser and the per-flow state the framework keeps for it.
PKCE is not optional here. The code verifier makes a stolen authorization code useless to anyone who did not start the flow, and there is no deployment where leaving it out is the right trade — so it is generated whether or not the provider advertises support.