Skip to content

Proposal: Meteor Accounts Extension #3

@StorytellerCZ

Description

@StorytellerCZ

Summary

This proposal extends/modernizes Meteor Accounts in two practical steps:

  • Phase 1 (Warm-up): Official “Sign in with Apple” OAuth provider

    • Deliver first-party apple-oauth + accounts-apple packages consistent with existing official providers.
  • Phase 2 (Primary Goal): Hardware security keys for 2FA

    • Add WebAuthn-based hardware key authentication as a second factor (“touch your key” after password/OAuth), aligning with community interest in FIDO/WebAuthn for Accounts (e.g. Discussion #12555) and with existing Meteor 2FA direction (Discussion #11514).
  • Stretch Goals: Passwordless login via WebAuthn/Passkeys

    • After 2FA hardware keys are solid, expand to WebAuthn/passkeys as a primary login method, not just a second factor.

This sequencing intentionally reduces risk: Apple OAuth is a bounded OAuth-provider task with the existing community and provides initial experience in the Meteor Accounts system; hardware-key 2FA is higher-impact but can be built on a stable foundation.


Motivation / Context

  • Meteor already supports multiple login methods and OAuth providers, but:
    • Apple is a common requirement and currently relies on community packages.
    • Phishing-resistant 2FA (hardware keys) is increasingly expected, and WebAuthn is broadly supported across modern browsers and OSes.
  • Accounts discussions also highlight a crucial constraint: avoid lockouts and ensure backup paths exist (see discussion around passwordless + 2FA behavior).

Goals

G1. Official Apple OAuth Provider (Phase 1)

Create official packages that match the Meteor “accounts-*” ecosystem:

  • apple-oauth: OAuth flow implementation
  • accounts-apple: Accounts integration and Meteor.loginWithApple(...)
  • Configuration via service-configuration
  • Strong docs and troubleshooting guidance (Apple config is easy to get wrong)

G2. Hardware Security Keys for 2FA (Primary Goal / Phase 2)

Implement WebAuthn-backed security keys as an Accounts 2FA option:

  • Users enroll one or more hardware keys (and optionally platform authenticators).
  • On login, after primary auth succeeds (password, OAuth, etc.), require WebAuthn verification to complete login.

This is explicitly 2FA / step-up authentication, not passwordless login, for the MVP.

G3. Avoid lockouts and preserve fallback

  • Ensure there is a safe recovery story:
    • fallback to existing OTP 2FA (if configured), and/or
    • backup/recovery codes (recommended), and/or
    • admin/secure recovery flow guidance
  • The system should be configurable so apps can choose their enforcement level.

Non-Goals (MVP)

  • A full UI for key enrollment/login in core (Meteor provides APIs; apps implement UX).
  • Passkeys/passwordless login in the MVP (these are stretch goals).

Proposed Deliverables

Phase 1: Official Apple OAuth packages

D1. apple-oauth + accounts-apple

  • Accounts.oauth.registerService('apple') and Meteor.loginWithApple(...) consistent with existing providers.
  • Works with popup/redirect flows like other official OAuth providers.
  • Uses ServiceConfiguration collection (and supports Meteor.settings patterns).
  • Clear errors for misconfiguration (missing keys, redirect URI mismatch, etc.).
  • Documentation:
    • required Apple developer settings (Team ID / Service ID / Key ID / private key formatting)
    • HTTPS redirect URI constraints
    • example configuration snippet
  • Tests aligned with how other OAuth providers are tested in Meteor.

D2. Migration guide from community packages

  • Provide “If you used quave:accounts-apple, here’s how to migrate” notes.

Phase 2: Hardware keys for 2FA (WebAuthn-based)

D3. Extend Accounts 2FA to support webauthn factor type

Introduce a new 2FA method type, conceptually:

  • services.twoFactorAuthentication.type = 'webauthn' (or a parallel structure that accounts-2fa recognizes)
  • Store registered authenticators under something like:
    • services.twoFactorAuthentication.webauthn.credentials[]

D4. Server-side factor enrollment + verification APIs

Add server methods (names illustrative) to:

  • Begin enrollment: generate WebAuthn registration options + challenge
  • Finish enrollment: verify attestation and persist credential
  • Begin 2FA challenge during login: generate assertion options + challenge
  • Finish 2FA: verify assertion, mark 2FA step complete for that login attempt

D5. Multi-step login integration (“step-up”)

Meteor Accounts supports login handlers; for 2FA a typical pattern is:

  • Primary login handler validates password/OAuth and returns a “requires 2FA” result (or a structured error/flow indicator).
  • Client then submits 2FA proof (WebAuthn assertion) to complete login.

Deliverable includes defining (and documenting) the canonical way to represent:

  • “primary factor ok; needs 2FA”
  • “2FA satisfied; issue session token”

This should be designed to work cleanly with:

  • password login
  • OAuth login
  • passwordless email token login

D6. Challenge storage (replay-resistant)

Store WebAuthn challenges server-side with:

  • short TTL (minutes)
  • single-use enforcement
  • compatibility with multi-instance deployments (DB-backed TTL collection, not memory-only)

D7. Lockout prevention

Ship with at least one of the following:

  • Backup codes (recommended; aligns with original 2FA design notes)
  • Or a clearly documented fallback strategy that apps must enable (less ideal)

The goal is: losing a key should not permanently lock out a user.

D8. Docs + security guidance

Documentation should include:

  • threat model basics (phishing-resistant 2FA)
  • required origins/RP ID configuration
  • recommended enrollment UX (naming keys, multiple keys per account)
  • recovery guidance

Stretch Goals (after Phase 2)

S1. WebAuthn/Passkeys as a primary login method

Add passwordless-first flows:

  • “Sign in with passkey” (resident credentials)
  • Account bootstrap + linking flows (e.g., user adds passkey after signing in with password)

S2. Platform authenticator support + passkey UX polish

  • Encourage multi-device credentials (syncable passkeys)
  • Better device metadata handling and account management UX guidance

S3. Advanced policy hooks

  • Require hardware key 2FA for privileged actions (step-up for specific methods)
  • Org/admin enforcement patterns

S4. 2FA Challenge

  • Meteor supported method where 2FA is required to perform an action/method

Milestones & Estimates

Milestone 1 — Apple OAuth officialization (40–70h)

  • Implement packages, docs, tests, migration guidance.

Milestone 2 — Hardware key enrollment + verification primitives (60–90h)

  • WebAuthn library selection
  • challenge storage
  • enrollment + verification methods
  • credential persistence format

Milestone 3 — Integrate into Accounts 2FA flow (60–100h)

  • multi-step login wiring
  • ensure compatibility with password + OAuth
  • rate limiting and abuse controls
  • docs

Milestone 4 — Recovery / backup codes + hardening (30–60h)

  • backup codes implementation (or formal fallback plan + guardrails)
  • security review checklist
  • additional tests

Total estimate

  • ~190–320 hours depending on:
    • how deep recovery/backup codes go
    • how broad the supported client environments are (web vs Cordova specifics)
    • test automation approach for WebAuthn flows

Acceptance Criteria

Apple OAuth

  • A1: Meteor.loginWithApple(...) works in popup + redirect flows.
  • A2: ServiceConfiguration-based setup is documented and validated with helpful errors.
  • A3: Package quality matches existing official providers (tests, docs, consistent API).

Hardware key 2FA

  • B1: A user can enroll multiple security keys.
  • B2: After primary login succeeds, WebAuthn 2FA is required to complete login when enabled.
  • B3: Challenges are single-use, expire, and are not replayable.
  • B4: Default validation is strict (origin/RP ID), with explicit configuration for advanced deployments.
  • B5: There is a documented and implemented recovery path (preferably backup codes).

Thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions