Documentation
¶
Overview ¶
Package oidc wraps go-oidc + x/oauth2 into the small surface the server needs for SSO login: build an auth-code+PKCE URL, then exchange the code and verify the returned ID token. Provider discovery is cached because it is a network round trip.
Why a dependency here: ADR-001 D8 — JWT/JWKS validation is the part you must not hand-roll. go-oidc (+ go-jose) is the canonical, minimal-surface choice; x/oauth2 provides the auth-code + PKCE primitives. These are the first external deps of lattice-server, justified in adr-001 and iteration 001.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GenerateCodeVerifier ¶
func GenerateCodeVerifier() string
GenerateCodeVerifier returns a fresh PKCE code verifier (high-entropy, URL-safe). The server stores it in the auth state and replays it on exchange.
func SanitizeRedirect ¶
SanitizeRedirect returns a safe post-login landing path. To prevent open redirects it accepts only a single-slash-rooted relative path (no scheme, host, or protocol-relative "//"); anything else collapses to "/".
Types ¶
type IdentityResolution ¶
type IdentityResolution struct {
UserID string
Email string
BindSubject bool // create a new (issuer,sub) link for this user
}
IdentityResolution is the outcome of mapping verified OIDC claims to a local user.
func ResolveIdentity ¶
func ResolveIdentity(p model.OIDCProvider, claims Claims, existingLinkUserID string, userByEmail func(email string) (string, bool)) (IdentityResolution, error)
ResolveIdentity decides which local user an OIDC login maps to, per ADR-001 D9 (allowlist-gated, no auto-provisioning). The provider's domain policy is re-evaluated on EVERY login (not just the first), so tightening the allowlist or a user's email becoming unverified is retroactive for already-linked subjects:
- If the provider restricts domains, require a verified email in an allowed domain — for both returning (linked) and first-time logins.
- If a durable link already exists, use it (the stable-sub path).
- Otherwise first login: require a verified email and a pre-existing local user whose username equals the verified email; bind the sub. Else denied.
existingLinkUserID is "" when no link exists. userByEmail reports a local user whose username equals the given email (case-insensitive in the store).
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager performs OIDC flows and caches discovered providers by issuer.
func NewManager ¶
func NewManager() *Manager
NewManager returns a manager whose outbound IdP calls are timeout-bounded and guarded against SSRF/private-network targets.
func NewManagerWithClient ¶
NewManagerWithClient returns a manager using client for all IdP calls. It is primarily for hermetic tests that need to talk to a local httptest IdP; pass nil to use the production guarded client.
func (*Manager) AuthCodeURL ¶
func (m *Manager) AuthCodeURL(ctx context.Context, p model.OIDCProvider, redirectURL, state, nonce, codeVerifier string) (string, error)
AuthCodeURL builds the provider authorization URL for an auth-code + PKCE (S256) login carrying the given state and nonce.
func (*Manager) Exchange ¶
func (m *Manager) Exchange(ctx context.Context, p model.OIDCProvider, redirectURL, code, codeVerifier, nonce string) (Claims, error)
Exchange swaps the auth code for tokens (proving the PKCE verifier), then verifies the ID token's signature/issuer/audience/expiry and matches the nonce. It returns the verified claims.
func (*Manager) Probe ¶
func (m *Manager) Probe(ctx context.Context, issuer string) (authEndpoint, tokenEndpoint string, err error)
Probe runs OIDC discovery for the issuer and returns the advertised authorization and token endpoints. It is the read-only "test connection" counterpart to AuthCodeURL: the same discovery path, but no login is started. Latency is bounded by the passed-in ctx (and the manager's timeout-bounded client); a successful probe harmlessly warms the discovery cache.