Skip to content

Explore human-entered email confirmation codes for contact enrollment #36

Description

@Sequela02

Problem

Vigil 7.3.0 provides a route-free contact-enrollment primitive with one canonical proof representation: a 256-bit random value encoded as 43-character Base64URL. That is a strong transport token for a verification link, but it is not suitable for manual entry.

Some host applications may prefer a conventional password sign-up flow in which the person submits an email address and password, then deliberately enters a short code delivered to that address. Today, supporting that presentation would require the host to replace or duplicate proof-generation and validation policy outside Vigil, even though Vigil owns the contact-proof lifecycle.

This issue proposes investigating whether Vigil should support a human-entered email confirmation-code mode. It does not assume that OTP is appropriate for every consumer or that six decimal digits are the final design.

Related: #31.

External evidence

Research checked on 2026-09-12:

Proposed investigation

Evaluate these alternatives against the existing enrollment boundary:

  1. Keep the current opaque link proof as the only Vigil mechanism and document how hosts should handle explicit confirmation and mail-link prefetching.
  2. Add an opt-in, human-entered confirmation-code strategy while preserving the current opaque link token as the compatibility default.
  3. Expose a constrained proof-generation/presentation SPI so hosts can select a representation without taking ownership of proof validation and lifecycle policy.

The investigation should answer:

  • Whether the choice belongs in configuration or in an explicit strategy contract.
  • Which code alphabets and lengths provide acceptable usability and online-guessing resistance under bounded attempts.
  • Whether code TTL should differ from the existing link-proof TTL.
  • How resend rotates the active generation and invalidates earlier codes without extending the total lifecycle.
  • How EnrollmentDeliveryPort can identify the presentation mode without owning a mail provider, template, route, or UI.
  • Whether the existing store commands can remain stable or need additive versioned data.
  • How to preserve generic responses, canonical email binding, audience/purpose/context binding, digest-only storage, recovery behavior, and atomic one-time verification.

Boundary constraints

  • Vigil should continue to own only contact-proof generation, validation, throttled lifecycle, and receipt orchestration.
  • Host applications continue to own passwords, pending registration state, users/accounts, sessions, routes, UI, email infrastructure, organization membership, authorization, and account linking.
  • A confirmation code must not create credentials, sessions, memberships, or authority by itself.
  • Existing 7.x consumers should not silently change proof representation or security behavior.

Acceptance criteria for the investigation

  • A documented decision compares the three alternatives using security, usability, compatibility, host complexity, and operational recovery.
  • The selected direction defines randomness, minimum effective entropy, canonical representation, digesting, expiry, attempt limits, resend rotation, one-time use, concurrency behavior, and log redaction.
  • Direct-link prefetching and cross-device behavior are addressed explicitly.
  • Pre-account-hijacking and future password/social-account linking are included in the threat analysis without moving those responsibilities into Vigil.
  • Any proposed public API or configuration change is additive by default, or includes an explicit migration and versioning decision.
  • Observable tests are identified for invalid format, guessing exhaustion, expiry boundaries, resend races, old-generation replay, concurrent verification, delivery ambiguity, and receipt recovery.

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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