Skip to content

feat: Sign in with CoinPay - #333

Merged
sh1pt-actions-fleet[bot] merged 1 commit into
masterfrom
feat/coinpay-signin
Oct 29, 2026
Merged

sh1pt-actions-fleet[bot] merged 1 commit into
masterfrom
feat/coinpay-signin

Conversation

@sh1pt-actions-fleet

Copy link
Copy Markdown
Contributor

CoinPay is the fleet master account: a person can sign in to agenticjobs with CoinPay, not only connect it to an account they already have.

Sign in

  • GET /auth/coinpay?next= starts it: PKCE S256 + state + nonce, state pinned to the browser by an HttpOnly aj_coinpay_state cookie (login CSRF). The existing registered callback /api/v1/coinpay/callback finishes it and mints a session.
  • The account is found by coinpay_accounts.coinpay_sub (already unique), never by the CoinPay email (CoinPay does not verify addresses). A first CoinPay sign-in creates a new account with a random @coinpay.agenticjobs.invalid placeholder, is_admin = false, and stores the connection (wallets) like a connect. .invalid addresses can no longer be typed into sign-in/sign-up.
  • "Sign in with CoinPay" is first on /login and /signup. The CLI (agenticjobs login, device flow) approves through /login, so it inherits CoinPay.

Connect (audit) already sent PKCE and the client secret and bound by sub with a session-started state. It now also sends a nonce and checks the id_token (iss/aud/exp/nonce, sub equals userinfo sub) via @profullstack/coinpay-onboard 0.3.1. Flows already in flight at deploy (no nonce) finish as before.

Disconnect is refused (409 / notice) while CoinPay is the only way in (placeholder address and no passkey).

Migration 0027_coinpay_sign_in.sql: coinpay_oauth_states.user_id nullable, mode, nonce.

Tests (api.test.ts, Postgres): CoinPay first on /login and /signup; new account bound to sub, never admin, same sub signs into the same account; email collision does not take over; a connected account signs into the account that connected it; missing browser cookie or wrong nonce refused; disconnect refused when it is the only way in. Full suite 1040/1040 against a fresh Postgres 17, typecheck clean.

🤖 Generated with Claude Code

CoinPay is the fleet master account: a person can now sign in here with
CoinPay, not only connect it to an account they already have.

- /auth/coinpay starts a sign-in (PKCE S256 + state + nonce), the state pinned
  to the browser by an HttpOnly cookie; the existing callback
  /api/v1/coinpay/callback finishes it and mints a session.
- The account is found by coinpay_accounts.coinpay_sub (unique), never by the
  CoinPay email. A new CoinPay sign-in makes a new account with a random
  .invalid placeholder address, never an admin; .invalid can no longer be
  typed into sign-in or sign-up.
- Connect (already PKCE + secret) now sends a nonce too and checks the
  id_token (iss/aud/exp/nonce, sub == userinfo sub) via
  @profullstack/coinpay-onboard 0.3.1.
- Disconnect is refused while CoinPay is the only way in (placeholder address
  and no passkey).
- "Sign in with CoinPay" first on /login and /signup; the CLI's device flow
  approves through /login, so it inherits CoinPay.
- Migration 0027: coinpay_oauth_states gets mode + nonce, user_id nullable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​profullstack/​coinpay-onboard@​0.3.17610010093100

View full report

@sh1pt-actions-fleet
sh1pt-actions-fleet Bot merged commit 37aff4d into master Oct 29, 2026
4 checks passed
@sh1pt-actions-fleet
sh1pt-actions-fleet Bot deleted the feat/coinpay-signin branch October 29, 2026 05:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant