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.
Intent | cashid: | This is the protocol name used to identify a **CashID** request
Domain | domain.tld | This is the server domain which hosts the SSL certificate and service command
Command | /command | This is the name of the action or task the service provider requests the user to take part in
Parameters | ?x=nonce<br/>&a=addr<br/>&r=scope<br/>&o=scope | These are settings that a service provider can use to inform the identity manager about what expectations the service provider has with regards to the response data.
The **Nonce** parameter is a set of random data that identifies a task or session on the service providers end, effectively linking it with the users authentication.
There are some tasks that a user can initiate independently from the service provider that also uses the **Nonce** value and service providers should detect these special cases and act accordingly:
**Value** | **Description**
--- | ---
delete | Requests the service provider to delete this identity and related metadata
revoke | Informs the service provider that this identity has been compromised
update | Informs the service provider about changed identity, position or contact metadata
### Address
The **Address** parameter informs the identity manager about which address that the request is valid for.
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 fields can only be requested in either **Required** or **Optional** scope, not both. The field numbers in each category has to be listed in sorted order, starting with the lowest number.
4 | Street name | String | Name of the street, without the street number
5 | Street number | String | The street number
6 | Residence | String | Building or apartment number that uniquely reference a residence
9 | Coordinate | String | Geographical position as specificed in [RFC5870](https://tools.ietf.org/html/rfc5870)<br/>*For example: "geo:13.4125,103.8667"*
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)
Metadata is stored as a JSON object with property names matching the requested field names. Fields that has multiple values (for example social media accounts) is stored as a JSON object with property names matching their identifier and the data matching the field description.
For example, if the request contains **r=i12&o=c** the metadata part of the request answer would look like this:
```javascript
metadata:
{
'name':'John',
'last name':'Doe',
'email':'johndoe@gmail.com',
'social':
{
'facebook':'https://facebook.com/johndoe',
'twitter':'https://twitter.com/johndoe'
}
}
```
*Note that there is two fields for social media presence and no fields for optional contact data the user did not want to supply*
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.