Skip to content

v0.2.0 — 2FA, Apple + Facebook, richer SCIM, RFC-compliance hardening

Choose a tag to compare

@alex-savin alex-savin released this 01 Jul 03:56

go-auth-x v0.2.0

A big release: two-factor auth, two more social providers, a much richer SCIM server, and a full RFC-compliance hardening pass. All additive at the public-API level (no removals/renames); a few security-hardening behavior changes are noted below.

✨ Highlights

Two-factor auth (2FA) — no third-party dependency

  • TOTP (RFC 4226/6238) implemented in the standard library only (verified against the published RFC test vectors) — the frontend renders the QR from an otpauth:// URI.
  • Recovery codes — single-use, sha256-at-rest.
  • Login enforcement — when 2FA is on, the first factor sets a short-lived signed 2fa_pending cookie instead of the session; POST /auth/2fa/verify (a TOTP or recovery code) finishes it. Replay-guarded and rate-limited.
  • Passkey as a second factor — complete the second step with a registered passkey (/auth/2fa/webauthn/begin+/finish) instead of a code.
  • Step-up / re-authRequireStepUpHTTP(maxAge) gates sensitive routes; POST /auth/reauth (password or a 2FA code) sets a short-lived step-up cookie.
  • Wire the optional TwoFactorStore (gormstore + memory reference impls) with SetTwoFactorStore.

Social login: Apple + Facebook

  • Sign in with Apple — the library signs the ES256 client-secret JWT from your .p8 and handles Apple's form_post callback (SameSite=None flow cookie; HTTPS required).
  • Facebook — Graph API /me with an appsecret_proof.
  • Both follow the same verified-email account-linking rule as Google/GitHub.

SCIM 2.0 — much more conformant

  • Filters: eq/ne/co/sw/ew/gt/ge/lt/le/pr with and/or/not, parentheses, and valuePath (emails[type eq "work"]).
  • Sorting (sortBy/sortOrder), strong ETags (If-Match/If-None-Match), Location/meta.location (set SetBaseURL), uniqueness scimType, PATCH noTarget/op validation, and the /Bulk endpoint.

🔒 Security / compliance (RFC audit)

An audit against ~27 RFCs/specs found and this release fixes 11 MUST-level gaps — all in caller-owned wiring, not the delegated crypto:

  • JWT token-audience segregation — session / oauth-flow / 2fa-pending / webauthn tokens now carry a distinct validated aud, closing a path where a 2fa_pending token could be replayed as a session (2FA bypass). (RFC 7519)
  • WebAuthn UserVerification is now Required — a passwordless passkey is a real multi-factor credential, not a bare possession factor. (WebAuthn L2)
  • randToken fails closed on a crypto/rand error instead of emitting a guessable state/CSRF/API-key token. (RFC 6749)
  • TOTP past-leaning validation window + rate-limited verify. (RFC 4226/6238)
  • LDAP StartTLS sets ServerName and refuses a cleartext bind. (RFC 4513)
  • OIDC validates azp. (OIDC Core)
  • Bearer admin guard returns 401 + WWW-Authenticate / 403 insufficient_scope. (RFC 6750)
  • SCIM strong ETags for If-Match, Location/uniqueness/PATCH validation. (RFC 7644 / 9110)

Upgrade

go get github.com/alex-savin/go-auth-x@v0.2.0

Public API is source-compatible with v0.1.x. Behavior changes to be aware of: WebAuthn logins now require user verification (a UV-capable authenticator); the admin Bearer guard returns 401 (not 403) for an invalid/missing key; SCIM ETags are now strong (no W/ prefix).

Full changelog: https://github.com/alex-savin/go-auth-x/blob/main/CHANGELOG.md