docs(specs): login migration — password-for-existing + nag-to-link-github#117
Merged
Conversation
Doc-only plan capturing a strategic shift in the cutover auth story: keep password login working for existing users (with auto-rehash from laddr's unsalted SHA1 to argon2id on every successful login), restrict new signups to GitHub, and surface GitHub-linking via a non-blocking banner on /account. Sunset deferred. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…thub
A directional change to the cutover auth strategy. Today's spec treats
GitHub OAuth as the only auth path and gates existing laddr users with
a one-shot claim flow at first sign-in. The new design:
- Existing users keep password sign-in indefinitely. Every successful
login auto-rehashes the unsalted-SHA1 credential (confirmed against
JarvusInnovations/emergence-skeleton User.class.php:33) to argon2id
so the corpus drifts toward modern hashing without forcing resets.
- New accounts are still GitHub-only — preserves the spam argument
that drove the original GitHub-only decision (which was specifically
about new-account sign-up, not existing users).
- Linking GitHub becomes a per-user opt-in surfaced via a persistent
yellow banner on /account. No deadline pressure; users link when
ready. The banner is the only nag mechanism.
- Sunset of password sign-in is deferred — no fixed deprecation date
or coverage threshold. Tracked separately when usage data justifies.
Doc-only change. The implementation work (POST /api/auth/login route,
rehash logic, link flow, banner, password-reset routes) lands in a
follow-up plan after these specs are reviewed.
Spec changes:
specs/deferred.md — flips "email/password auth"
from "deleted entirely" to "sign-up GitHub-only, existing users
keep password indefinitely."
specs/behaviors/account-migration.md — rewritten around the three
sign-in paths (GitHub-new, GitHub-matched, legacy-password) and
the link-when-ready banner. Cutover-window deadline policy
removed; users aren't time-pressured.
specs/behaviors/password-hash-rotation.md (new) — SHA-1/bcrypt/argon2
format detection, constant-time compare, rehash-on-login,
anti-enumeration timing (dummy argon2 verify on missing user/cred
paths), argon2id parameter source-of-truth.
specs/api/auth.md — adds POST /api/auth/login,
POST /api/auth/password-reset/{request,confirm}, POST /api/auth/
link-github. /api/auth/me grows hasGitHubLink + lastLoginMethod.
Notes section updated to reflect the password-for-migrated-users
posture.
specs/screens/login.md — adds a collapsed secondary
"Or sign in with your Code for Philly password" disclosure with
the password form + "Forgot your password?" affordance.
specs/screens/account.md — Card 1 (Identity) gains
State A (linked) / State B (not yet linked, shows banner). Link
action wired to POST /api/auth/link-github.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A directional change to the cutover auth strategy. Today's spec treats GitHub OAuth as the only auth path and gates existing laddr users with a one-shot claim flow at first sign-in. The new design:
Verified facts driving the design
Confirmed against `JarvusInnovations/emergence-skeleton/php-classes/User.class.php:33`:
```php
public static $passwordHasher = 'SHA1';
```
And the verifier:
```php
public function verifyPassword($password)
{
return $this->Password && call_user_func(static::$passwordHasher, $password) == $this->Password;
}
```
Unsalted SHA-1, with loose `==` comparison (timing-leaky). The new `password-hash-rotation.md` spec mandates constant-time compare + rehash-on-login so this corpus drifts to argon2id naturally.
Files changed
What's NOT in this PR
This is doc-only. Implementation (route handlers, argon2id dep, rehash logic, password-reset routes, link-github route, SPA banner + secondary login form) lives in a follow-up plan after these specs are reviewed.
Test plan
🤖 Generated with Claude Code