CashID is an open protocol that allows secure authentication based on the public key cryptography infrastructure that is currently present in the Bitcoin Cash ecosystem. By authentication we mean to prove to a service provider that we control a specific Bitcoin Cash address by signing a challenge request that links the users address and optional metadata to a task or session with the service provider.
Passwords is an inherently flawed concept (based on sharing secrets) that is increasingly getting hidden away from the users by means of password managers, 'remember me' and single-signon features. Public key cryptography provides a more secure method for authentication where the users secret is never shared.
The problem with public key infrastructure is that managing private keys securely is complex, but this complexity is now being addressed in the cryptocurrency ecosystem which makes it possible to safely implement a better authentication system.
When a user needs to access a restricted area (physically or digitally), they are given a challenge request which can either be transmitted via a QR code, NFC or by any other implementation specific transmission method.
The **Required** and **Optional** parameters allow the service to request personal information from the user. In order to do this in the least amount of space, the information is shorthanded by a letter and a string of numbers representing various pieces of personal information. For **Optional** metadata, the numbers after a letter can be omitted to request all fields in that category. The same metadata can only be requested in either **Required** or **Optional** scope, not both.
7 | Gender | ??? | The sex of the person (I would put the type as Boolean :) But considering the times we are living in, it's probably better be a string...
8 | Birthdate | Date | The date of birth... what format? (YYYY-MM-DD?)
The **signup** command at **example.com** requires **Name**, **Last Name**, **Country** and **Email** to work, and will use **Picture**, **Age**, **Gender** and **City** if provided.
Upon receiving the CashID URI described above via QR or other method, the Identity Manager app (IM) needs to show to the user what metadata was requested, which fields are required and which are optional, and allow to select an identity to use for authentication.
After the user selects the identity and approves the required/optional fields, the Identity Manager must sign the URI with the Bitcoin Cash address tied to the selected identity, and send a POST response to the connection point provided in the URI (i.e. to https://example.com/signup). Plain HTTP responses are not allowed.
(NOTE: the original spec just dumps all the data into POST, this is not always convenient, so maybe we should change it to url-encoded POST, like I described below)
The POST response has a single 'data' variable that must be a valid JSON object:
Member | Data type | Description
--- | --- | ---
uri | String | The original URI requested.
address | String | Native or CashAddr address used to sign the above URI.
signature | String | Hex-encoded signature.
... | ... | Requested metadata fields.
Metadata fields must have names that match the requested scope, for example "i2", "i3" or "c". Multiple items are returned separately, so "i23" will produce two separate members - "i2" and "i3".
In case all the data fields were requested using a single scope letter, they are returned in an array, with that letter being its name.
## Confirmation
The server responds to the POST with a valid JSON object:
Member | Data type | Description
--- | --- | ---
error | String | Textual error description, empty if authentication was successful.
code | Integer | One of the codes described below.
### Error codes
Code | Description (same as 'error' member)
--- | ---
0 | Authentication successful.
1 | Malformed request.
2 | Malformed URI.
3 | Timeout (nonce has expired).
4 | Nonce has been already used (not sure...)
5 | Required metadata is missing. (would be nice to also specify which one...)
6 | Metadata format is not supported (again, would be nice to specify the exact problem...)
7 | Busy, try again later (or Service temporary unavailable).
8 | Signature verification failed.
9 | Access denied for this identity. (can be more detailed ban reason...)
10 | This identity was marked as compromised and cannot be used anymore.
Error codes above 100 are available for custom responses, not specified here. If such a response is received, which IM doesn't recognize, it must simply show the textual error to the user.