Authentication
Wahoo provides password, opaque-token, session, and CSRF primitives. Generated account routes return 501 Not Implemented until the application supplies storage, mail, cookies, authorization, and rate limits.
Work in progress: Do not use Wahoo in production yet.
Provided API
| API | Use it to |
|---|---|
auth.HashPassword |
Create a bcrypt hash after a 12-character minimum check. |
auth.VerifyLogin |
Verify credentials with a dummy bcrypt check for absent users. Storage failures are returned. |
auth.NewToken |
Create a URL-safe opaque token. |
auth.TokenHash |
Hash an opaque token before storage. |
auth.AuthenticateSession |
Validate token hash, expiry, and revocation through an application SessionStore. |
auth.NewCSRFToken |
Create a token for an application-owned CSRF design. |
auth.VerifyCSRFToken |
Compare CSRF tokens in constant time. |
Do not store raw passwords, session tokens, reset tokens, or CSRF tokens.
Session Store
Implement only the lookup needed by the framework primitive:
type SessionStore interface {
FindSessionByTokenHash(context.Context, string) (*auth.Session, error)
}
rawToken, err := auth.NewToken(32)
if err != nil {
return err
}
hash, err := auth.TokenHash(rawToken)
// Store hash, user ID, expiry, and revocation time.
session, err := auth.AuthenticateSession(r.Context(), sessions, rawToken, time.Now())
The application must create, rotate, revoke, and persist sessions. It must set a secure, HttpOnly, SameSite cookie. Use Secure: false only for local HTTP development.
Login And Reset
A login handler must normalize email, rate limit attempts, return the same credential failure for absent and incorrect users, create a new session, write an audit event, and set a secure cookie.
A password-reset flow must always return the same public response, store only a single-use token hash, use a short expiry, revoke sessions after a successful reset, and write an audit event.
CSRF
Use a server-side synchronizer token or signed double-submit token for browser mutations. Also validate Origin or Referer. CORS does not prevent CSRF.
OAuth And MFA
Keep OAuth and MFA behind application provider interfaces. OAuth requires state, nonce, and PKCE. Use WebAuthn or TOTP for MFA, hash recovery codes, and require short-lived step-up state for sensitive actions.