Linked accounts page: list, link, unlink with fresh proof (merge design step 2) #84

Merged
heimdall merged 4 commits from heimdall/linked-accounts into main 2026-11-13 20:24:16 +00:00
Member

Step 2 of the account-merge design: a signed-in member sees their Heimdall provider logins, starts a link for another provider, and unlinks with a step-up proof; the last-identity refusal is shown. No merge.

  • Bifrost keeps no Heimdall token: list and unlink each follow a fresh Heimdall sign-in (unlink with stepUp:true); the bearer lives in one request. Snapshot of non-secret fields is in process memory, 5 min, keyed by account.
  • New page /Membership/LinkedAccounts; the Status Google button is replaced by it.
  • Docs: docs/linked-accounts.md. Bifrost has no changelog file.
  • Tests: 1469 pass / 18 fail (same 18 BridgeCli/ProviderAdvertisement failures as clean main, environmental). 16 mutations, all caught.
  • Limits: only Google can give step-up on the bifrost profile and it is unconfigured live (503), so unlink cannot complete in production until that changes. Nothing ran against a live Heimdall.
  • Not deployed.

🤖 Generated with Claude Code

Step 2 of the account-merge design: a signed-in member sees their Heimdall provider logins, starts a link for another provider, and unlinks with a step-up proof; the last-identity refusal is shown. No merge. - Bifrost keeps no Heimdall token: list and unlink each follow a fresh Heimdall sign-in (unlink with stepUp:true); the bearer lives in one request. Snapshot of non-secret fields is in process memory, 5 min, keyed by account. - New page /Membership/LinkedAccounts; the Status Google button is replaced by it. - Docs: docs/linked-accounts.md. Bifrost has no changelog file. - Tests: 1469 pass / 18 fail (same 18 BridgeCli/ProviderAdvertisement failures as clean main, environmental). 16 mutations, all caught. - Limits: only Google can give step-up on the bifrost profile and it is unconfigured live (503), so unlink cannot complete in production until that changes. Nothing ran against a live Heimdall. - Not deployed. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
A member sees their Heimdall logins, links Discord, Patreon or Google, and unlinks one
with a fresh Google step-up sign-in. Bifrost keeps no Heimdall token: each action is a
fresh Heimdall sign-in started by Bifrost whose bearer lives inside the completion
request. The list is kept five minutes in this process as non-secret fields only.

The Status page's Google-only link button and handler are cut; the Linked accounts page
owns link starts. HeimdallStartRequest gains stepUp. Heimdall's member routes use a
client without the app secret.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
With no current list the proof goes only through a provider the member names, never the
session's sign-in provider: a sign-in through an unlinked provider makes Heimdall mint an
orphan account holding that login. Link buttons need a current list. The unlink completion
must say a step-up was requested. POST /auth/heimdall/complete answers no-store. The fake
Heimdall now models orphan minting, derives step_up_at from the start's stepUp flag, and
enforces the app secret, sign_in-only, unsupported-provider and 600 s rules.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
GameCult/Bifrost!84
No description provided.