Skip to content

Broker-side autonomous signup + io.pilot.didit one-call signup#77

Merged
Alexgodoroja merged 4 commits into
mainfrom
feat/otp-signup-broker
Jul 8, 2026
Merged

Broker-side autonomous signup + io.pilot.didit one-call signup#77
Alexgodoroja merged 4 commits into
mainfrom
feat/otp-signup-broker

Conversation

@Alexgodoroja

Copy link
Copy Markdown
Collaborator

Summary

Adds the broker-signup pattern — a per-user provider API key with no email and no code — and switches io.pilot.didit to it: didit.signup {} now mints a Didit key in one call.

Complements the no-broker register/verify flow (kept). For providers that gate the key behind an email OTP (and reject disposable mailboxes), the broker runs the whole signup on infrastructure we control and hands back the key.

What's here

  • internal/otpmail (+ cmd/otpmail) — a receive-only mail server: catch-all SMTP for one domain + a token-authed control API (provision / read-OTP / teardown). Receive-only, so no SPF/DKIM/PTR. Keeps mail only for provisioned addresses, tmpfs, never logs the code or body.
  • internal/otpsignup (+ cmd/otpsignup-broker) — a signed HTTP broker: provisions a mailbox, drives the provider register→OTP→verify, mints the key, returns it. Reuses the shared broker's ed25519 caller-verify; idempotent per caller; AES-GCM encrypted-at-rest ledger; per-IP Sybil cap.
  • scaffold — a signup: { step: broker } route (adapter signs one keyless call to the broker and caches {email,api_key}; ops stay byo) + step: account (retrieve the cached account). Emits the signer + broker-call runtime; grants key.sign + net.dial-broker.
  • submissions/io.pilot.diditdidit.signup {} (one call, no email) + didit.account; help + long description updated.
  • docs/BROKER-SIGNUP.md — the pattern for future apps.

Everything provider- and host-specific is configuration; nothing is compiled in.

Validation

  • Full suite green (otpmail, otpsignup, scaffold, publish); generated broker-signup project compiles; verify-submission passes on all 4 platforms.
  • Live end-to-end: deployed both services, and didit.signup {} — installed from a signed catalogue → prod R2, through the daemon — minted a real Didit key in ~6s with no email/code, retrievable via didit.account, with ops (billing_balance, create_workflow) authenticating. The broker logs each mint (no secrets) and tears the mailbox down.

Supersedes the two-step submission from #75.

Alex Godoroja added 4 commits July 7, 2026 16:39
Add the broker-signup pattern: obtain a per-user provider API key that a
provider gates behind an email OTP, with NO email input from the user and no
key held on our side after handoff.

- internal/otpmail: a receive-only mail server (catch-all SMTP for one domain
  + token-authed control API for provision/read-OTP/teardown). Keeps mail only
  for provisioned addresses, tmpfs maildir, never logs the code or body.
- internal/otpsignup: a signed HTTP broker that provisions a mailbox, drives the
  provider register→OTP→verify handshake, mints the key, and returns it. Reuses
  the shared broker's ed25519 caller-identity verify; idempotent per caller with
  an AES-GCM encrypted-at-rest ledger; per-IP Sybil cap.
- scaffold: a new signup `step: broker` (the adapter signs one keyless call to
  the broker and caches {email,api_key} to secrets.json; ops stay byo) plus a
  `step: account` local reader to retrieve the cached account. Emits the signer +
  a broker_signup.go runtime; grants key.sign + net.dial-broker.

All provider- and host-specifics are configuration; nothing is compiled in.
Tests cover SMTP delivery, OTP parse, control API, the full signed mint,
idempotency, encryption at rest, the per-IP cap, and generated-project compile.
didit.signup {} now mints the per-user Didit key via the Pilot broker in one
call (no email, no code); adds didit.account to retrieve the cached account;
drops the two-step register/verify. Help + long description updated.
@Alexgodoroja Alexgodoroja merged commit d01fa23 into main Jul 8, 2026
7 checks passed
@Alexgodoroja Alexgodoroja deleted the feat/otp-signup-broker branch July 8, 2026 00:19
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