A stateless approach to archtect the identifier attestation issuer site

I was having this conversation this morning with Hu on the design of attestation.id where he asked if there is any use of a database on attestation.id, the forthcoming attestation issuer site we are going to make and maintain.

For those who didn't follow the TokenScript weekly meetings (of which I stopped making meeting minutes which typically takes 1~2 hours each week that I no longer could afford), attestation.id is going to be a website that issues attestation on email identifiers, similar to how CACERT.org did email certificates for the last decade and Thawte did before that through their Web-Of-Trust, in the era when Shuttleworth still drove the project and had not moved on to the making of Ubuntu. The difference is that we cryptographically hide the email address in the "certificate" (now called identifier attestation but still based on x.509) so that it can be used on public blockchain like Ethereum.

The part where the identifier attestation state needs to be "remembered is to "remember" the verification code, typically a 6-digit decimal sent in an email to the user.

The easy way is to use a session manager and keep the 6-digit one time code in the session (held by the server memory - lost by reboots). The user has to type the same 6-digit code to get the server to agree to issue an identifier attestation. However, it doesn't allow the use-case where the user opens a link in a different browser than where they requested it, and it doesn't allow the use of micro architect (such as AWS Lambda) unless a state-persisting database is used, which stores the 6-digit one time code until it expires.

The following protocol should allow the return of micro architect as an option or keeping such an option open for future use without much modification.

  1. Assume that the server-side has a static key 𝑠 on top of a signing key which it already has.

  2. When the user requests an attestation, the server sends a signed message 𝑚 to the user, which contains the user's email address and a validity field that times out in a few minutes. In the meanwhile, it sends the user a 6-digit code by email, which is the decimal representation of the first 10 bits of ℎ𝑚𝑎𝑐(𝑠, 𝑚). The static key 𝑠 is not shared with the user.

  3. When the user types the 6-digit code in a web form, the web form submits the message 𝑚 together with its signature to the server in the same POST.

  4. The server verified that the message was signed by its own private key, hence not forged by the user. It then verifies the validity, then computes the first 10 bits of ℎ𝑚𝑎𝑐(𝑠, 𝑚) and checks against the user's input. The user is not able to forge the 6-digits unless she received it by email.

This allows the server to be completely stateless. Just an idea. Do you think it might work or be simplified?

This method would require the user to submit CSR at the same time it submits the 6-digit code, so the server can issue attestation in one go without having to store anything in the session.

I think the overall idea is good, and I don't immediately see any big issue with it, except that we still need the same browser window in the same browser to both send the request and type-in the verification code. This is because the message m must be returned with the verification code.

One other issue is that a 6-digit numerical code is too short, as it is basically only 20 bits of entropy. This is fine for a second factor code, but here there is no other factor in place and this code is the only authentication mechanism. Furthermore, if we use a short code we should be able to throttle requests for a specific email on the server-side to e.g. 3 failed sign-in attempts per day (and even a single wrong attempt with a code should result it that code being invalidated). If we want to rely on a stateless server I think we should ensure very high entropy in the verification code since it will only be able to throttle based on IP and not user mail. For this reason the code should instead be a base64 code of at least 20 characters that the user needs to copy and paste from the mail into the browser.
Unfortunately this will of course be more annoying from the user's perspective.

That's a good point so I think that concludes the discussion, that we can't cut corners here and the capacity to store the one time code on the server-side is required, and we should not make a state-less web server without session management capability