idp

A multi-tenant OAuth 2.0 / OpenID Connect authorization server built to survive a standards reviewer.

GoPostgresOAuth 2.0OIDCArgon2id live demo

What it is

The flagship: a multi-tenant authorization server implementing the authorization-code + PKCE flow, refresh-token rotation with family reuse detection, device flow, client credentials, introspection, revocation, OIDC discovery, userinfo, and admin-gated dynamic client registration. Signing is delegated to keysmith; idp owns protocol correctness, not cryptography.

Standards coverage

RFC 6749 (OAuth 2.0 core, exact §5.2 error semantics), RFC 6750 (Bearer + WWW-Authenticate), RFC 7636 (PKCE, S256 only), RFC 7662 (introspection), RFC 7009 (revocation), RFC 8414 + OIDC Discovery, RFC 8628 (device flow), RFC 7591 (dynamic registration), OIDC Core, and RFC 9700 (OAuth Security BCP). The deprecated grants — implicit and ROPC — are deliberately absent; per ADR 0002, their absence is a security feature the discovery document advertises, not a gap.

Key design decisions

UPDATE refresh_tokens SET rotated_at=$3
 WHERE realm_name=$1 AND token_hash=$2
   AND rotated_at IS NULL AND revoked=false

A concurrent second redemption updates zero rows and is rejected — at most one winner, no second successor ever issued (internal/storage/postgres/stores.go).

Security highlights

From the threat model: no error reaches redirect_uri until both client_id and an exactly-matched redirect_uri are validated (open-redirect discipline); login failures are uniform in body and timing — unknown users are verified against a real decoy Argon2id hash; login always mints a fresh session ID (fixation defense); CSRF double-submit on every state-changing form; per-realm issuers in every token so cross-realm token use fails; device-flow user codes are high-entropy, one-shot, and poll-paced with slow_down.

Verified by

Code worth reading