SPEC 001 Authentication Account - rafaelfqueiroz/allmywallet GitHub Wiki

SPEC-001 — Authentication & Account

Status Draft
PRD source F1 (FR-1.1–1.6), FR-8.23
Depends on SPEC-003 (tenant model), SPEC-002 (config)
Required by Every other spec, SPEC-020
Milestone M0

Description

Sign-in, session handling and account lifecycle for AllMyWallet. Google OAuth 2.0 is the only sign-in method: no password is ever created, transmitted or stored by this system.

That is a security decision before it is a convenience one — it removes credential storage, password reset flows, and credential-stuffing exposure from the product entirely. It is also the sole identity boundary behind which every tenant-scoped record in the system sits, so this spec is a prerequisite for all others.

First successful sign-in provisions the user's tenant and hands off to the onboarding flow in SPEC-020.

Business rules

ID Rule
BR-001-01 Google OAuth 2.0 is the only authentication method. No password field exists anywhere in the product.
BR-001-02 Only the openid, email and profile scopes are requested. No Google Drive, Calendar, Contacts or any other scope may be added without a documented privacy review.
BR-001-03 The stable Google subject ID (sub), not the email address, is the identity key. Users can change their Google email; the account must survive it.
BR-001-04 First successful sign-in creates exactly one User record and its tenant context, then routes to onboarding. Provisioning is idempotent — a retried callback must not create a second tenant.
BR-001-05 Personal data stored is limited to: Google subject ID, email, display name, profile picture URL. Nothing else.
BR-001-06 Sessions expire after a configurable period of inactivity (default 30 days).
BR-001-07 Sign-out invalidates the session server-side. Clearing a cookie client-side is not sufficient.
BR-001-08 Every request resolves its tenant from the authenticated session only. A user, org or tenant identifier accepted from a request parameter, header or body is a security defect.
BR-001-09 A user can permanently delete their account from settings; the deletion itself is specified in SPEC-004.
BR-001-10 OAuth state and PKCE parameters are validated on callback; a mismatched or replayed state is rejected.
BR-001-11 Authentication endpoints are rate-limited per IP and per subject.
BR-001-12 Account recovery when the Google account is lost is not offered. This is an accepted consequence of single-provider auth and must be stated in the sign-up screen, not buried in terms.

Acceptance Criteria

  • A new user signs in with Google and reaches an empty dashboard with no form fields to complete.
  • Sign-up to signed-in state completes in under 30 seconds on a normal connection.
  • Signing in a second time reuses the same tenant; no duplicate User row is created.
  • Changing the email address on the Google account still resolves to the same AllMyWallet account.
  • A replayed or tampered OAuth state parameter is rejected with no session created.
  • Signing out invalidates the session server-side: replaying the captured session cookie afterwards is refused.
  • A session idle beyond the configured window is refused, and the window is changeable via config without a deploy.
  • No password field, "forgot password" link, or credential input exists anywhere in the product.
  • A request carrying a user_id parameter for a different tenant is ignored — identity comes from the session (verified jointly with SPEC-003).
  • The sign-up screen states plainly that losing the Google account means losing access.
  • Repeated failed auth attempts are rate-limited.
  • Only openid, email, profile scopes appear in the consent screen.

Out of Scope

  • Email/password authentication, magic links, or any second identity provider.
  • Multi-factor authentication beyond what Google itself enforces.
  • Account recovery, account merging, or transferring data between accounts.
  • Organizations, teams, shared portfolios, or any multi-user-per-tenant concept.
  • Role-based access control — every user has exactly one role over exactly their own data.
  • Impersonation or support-side login-as.
  • The account deletion mechanics themselves (SPEC-004).
  • Storing or handling any B3, broker or bank credential — prohibited product-wide (SPEC-003).

Decision Logs

# Decision Alternatives considered Rationale
DL-001-01 Google OAuth is the only sign-in method. Email+password; magic link; multiple OAuth providers Removes credential storage and the entire password-breach class of risk. The target user already has a Google account. A second provider can be added later without redesign; adding passwords could not be undone as cheaply.
DL-001-02 Identity keyed on Google sub, not email. Key on email address Emails change and can be reassigned within Workspace domains. Keying on a mutable field would silently orphan or, worse, merge accounts.
DL-001-03 No account recovery. Support-mediated recovery via email proof Any recovery path is an authentication bypass by definition, and building one securely for a product holding financial data is disproportionate at v1. Accepted and disclosed rather than half-built. Revisit if a second provider is added.
DL-001-04 Session expiry is configurable, defaulting to 30 days. Fixed 30 days; short expiry with refresh tokens Long-horizon tracker checked weekly or monthly — a short session is pure friction for no threat-model gain. Configurable per SPEC-002 so it can tighten without a release.
DL-001-05 Minimum OAuth scopes, enforced by rule not convention. Request broader scopes for future features Scope creep in OAuth is invisible to users until the consent screen, and expanding scopes later forces re-consent anyway. Nothing is requested until a feature needs it.