Documentation
¶
Overview ¶
Package oidc provides a thin adapter over coreos/go-oidc v3 and golang.org/x/oauth2 for OpenID Connect authentication.
This package intentionally does NOT re-define SDK types. It exposes go-oidc's Provider, IDToken, and oauth2's Token directly. The adapter adds GoCell-specific concerns: Config, errcode wrapping, and HTTP client lifecycle.
ref: github.com/coreos/go-oidc/v3/oidc ref: golang.org/x/oauth2
Index ¶
- Constants
- type Adapter
- func (a *Adapter) Close(ctx context.Context) error
- func (a *Adapter) OAuth2Config(ctx context.Context) (*oauth2.Config, error)
- func (a *Adapter) Probes() []healthz.Probe
- func (a *Adapter) Provider(_ context.Context) (*gooidc.Provider, error)
- func (a *Adapter) Refresh(ctx context.Context) (*gooidc.Provider, error)
- func (a *Adapter) Verifier(ctx context.Context) (*gooidc.IDTokenVerifier, error)
- func (a *Adapter) Worker() worker.Worker
- type Config
- type NoopRefreshCollector
- type RefreshCollector
Constants ¶
const ( ErrAdapterOIDCConfig errcode.Code = "ERR_ADAPTER_OIDC_CONFIG" ErrAdapterOIDCDiscovery errcode.Code = "ERR_ADAPTER_OIDC_DISCOVERY" ErrAdapterOIDCVerify errcode.Code = "ERR_ADAPTER_OIDC_VERIFY" ErrAdapterOIDCExchange errcode.Code = "ERR_ADAPTER_OIDC_TOKEN" ErrAdapterOIDCUserInfo errcode.Code = "ERR_ADAPTER_OIDC_USERINFO" )
OIDC adapter error codes.
ErrAdapterOIDCExchange is named "Exchange" but its wire literal stays "ERR_ADAPTER_OIDC_TOKEN" — the constant was renamed to dodge a gosec G101 false positive on "Token" while keeping the existing wire value stable for downstream consumers (logs, error fingerprints, dashboards).
const ProbeReady healthz.ProbeName = "oidc_ready"
ProbeReady is the ops-contract name for the OIDC readiness probe. healthz.ProbeName-typed, funneled by PROBENAME-SEALED-FUNNEL-01.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Adapter ¶
type Adapter struct {
// contains filtered or unexported fields
}
Adapter is a thin wrapper over go-oidc and oauth2. It manages provider discovery and exposes the underlying go-oidc types directly.
func New ¶
New creates an OIDC Adapter and synchronously performs OIDC discovery. An unreachable or misconfigured issuer causes construction to fail immediately (fail-fast at boot, not at first request).
clk is required: New panics via clock.MustHaveClock when clk is nil. Use clock.Real() at the composition root; inject clockmock.New() in tests.
ref: coreos/go-oidc — Provider.NewProvider semantics (sync HTTP round-trip). ref: adapters/s3.New — same clock.MustHaveClock + state-machine field pattern.
func (*Adapter) Close ¶
Close implements lifecycle.ManagedResource. It signals the worker to stop and waits for the goroutine to drain, bounded by ctx. Idempotent — safe to call from both Worker.Stop and ManagedResource.Close teardown paths.
Fast path: if the worker goroutine was never started (e.g. bootstrap aborted before Worker.Start was called), workerDone will never be closed. In that case we skip the select so we do not burn the shutdown budget on a non-existent drain.
ref: adapters/s3.Client.Close — same idempotent + ctx-bounded pattern.
func (*Adapter) OAuth2Config ¶
OAuth2Config returns an oauth2.Config using the provider's endpoints.
func (*Adapter) Probes ¶
Probes returns the typed readyz probe for the OIDC provider. The probe verifies that the cached provider is populated without re-discovering.
ref: kubernetes/kubernetes pkg/util/healthz — named health checkers.
func (*Adapter) Provider ¶
Provider returns the cached go-oidc Provider. Discovery runs synchronously in New (fail-fast at boot), so a successfully constructed Adapter always has a populated provider. This read is lock-free (atomic.Pointer.Load); the refresh worker swaps the pointer atomically and never blocks readers, even across a slow or hung re-discovery (post-init fail-open availability).
IMPORTANT: The cached provider never expires automatically. The refresh worker (Worker(), auto-wired by bootstrap.WithManagedResource) re-discovers every refreshInterval to pick up OIDC metadata rotation.
func (*Adapter) Refresh ¶
Refresh re-discovers the OIDC provider metadata and atomically swaps the cached provider. The refresh worker calls this on each tick; it is also safe to call manually.
type Config ¶
type Config struct {
IssuerURL string
ClientID string
ClientSecret string
RedirectURL string
Scopes []string // default: [openid, profile, email]
HTTPTimeout time.Duration // default: 10s
// RefreshInterval controls how often the worker re-discovers OIDC provider
// metadata. Zero means defaultOIDCRefreshInterval (24h).
RefreshInterval time.Duration
// RefreshCollector receives success/failure signals from the refresh worker.
// Optional: nil is replaced with NoopRefreshCollector{} in New().
RefreshCollector RefreshCollector
}
Config holds the OIDC provider configuration.
type NoopRefreshCollector ¶
type NoopRefreshCollector struct{}
NoopRefreshCollector is the default collector used when no observability is wired. Method body intentionally empty — registration cost is zero and metric absence is documented behavior, not a fault.
func (NoopRefreshCollector) RecordRefresh ¶
func (NoopRefreshCollector) RecordRefresh(_ context.Context, _ bool)
RecordRefresh is a no-op.
type RefreshCollector ¶
type RefreshCollector interface {
// RecordRefresh increments the refresh counter.
// success=true means discovery succeeded and a.provider was updated;
// success=false means discovery failed (fail-open: old provider kept).
RecordRefresh(ctx context.Context, success bool)
}
RefreshCollector observes OIDC JWKS refresh attempts so alerting rules can detect stale discovery metadata without parsing log strings.
Implementations must be safe for concurrent use.
ref: adapters/rabbitmq.PublisherCollector — same inject-at-construction pattern.
func NewProviderRefreshCollector ¶
func NewProviderRefreshCollector(p metrics.Provider, cellID string) (RefreshCollector, error)
NewProviderRefreshCollector registers the oidc_jwks_refresh_total counter on p and returns a RefreshCollector backed by it. Returns error when cellID is empty or when the Provider reports registration failure (typically duplicate metric names).