Files
cashId/README.md
T

232 lines
10 KiB
Markdown
Raw Normal View History

2018-09-21 18:46:37 +00:00
*Status: Incomplete draft*
2018-09-21 17:04:02 +00:00
# Abstract
2018-09-21 16:52:51 +00:00
2018-09-21 17:04:02 +00:00
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.
2018-09-21 17:04:02 +00:00
# Motivation
Secure authentication and safe storage of credentials is useful for many things, and with added metadata we enable the following usecases:
* Register to a service as a 1-step process.
* Register to a service automatically as part of a payment.
* Authenticate to a service to login without a password.
* Authenticate to a service to act as 2FA complementing existing passwords.
* Provide access control to locks based on payment.
# Rationale
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.
2018-09-21 17:04:02 +00:00
# Specification
## Workflow
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.
2018-09-21 17:04:02 +00:00
## Request
2018-09-22 09:07:06 +00:00
The request consists of an **Intent**, **Domain**, **Command** and set of **Parameters**.
2018-09-22 06:28:41 +00:00
```
2018-09-22 09:07:06 +00:00
cashid:domain.tld/command?x=nonce&a=addr&r=scope&o=scope
2018-09-22 06:28:41 +00:00
```
2018-09-22 09:07:06 +00:00
**Part** | **Example** | **Description**
--- | --- | ---
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.
### Parameters
Every request must have a **Nonce** parameter and may also have an **Address**, **Required** and **Optional** parameter.
2018-09-22 06:45:36 +00:00
**Letter** | **Name** | **Description**
--- | --- | ---
x | Nonce | Random data identifying the task or session
a | Address | When present, the service will only accept a reply from this identity
r | Required | List of metadata that the service needs to function
o | Optional | List of metadata that the service can use but still works without
### Metadata
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.
2018-09-21 18:06:12 +00:00
**Identification** is represented by the letter **i** followed by a list of numbers corresponding to the following table.
2018-09-22 06:45:36 +00:00
**Number** | **Name** | **Data type** | **Description**
--- | --- | --- | ---
1 | Name | String | The first or given name of the person
2 | Family | String | The last name, surname of family name of the person
3 | Nickname | String | A nickname or username
4 | Age | Integer | The number of years the person has lived
5 | Gender | String | The sex of the person, usually "Male" or "Female"
6 | Birthdate | Date | The date of birth... what format? (YYYY-MM-DD?)
8 | Picture | String | URL to a profile picture, or Base64 encoded image
9 | National | string | National identification numbers, such as passport, drivers license and citizenship numbers.
**Position** is represented by the letter **p** followed by a list of numbers corresponding to the following table.
2018-09-22 06:45:36 +00:00
**Number** | **Name** | **Data type** | **Description**
--- | --- | --- | ---
1 | Country | String | Name of the nation
2 | State | String | Name of the state or province
3 | City | String | Name of the city
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"*
2018-09-21 18:06:12 +00:00
2018-09-21 18:06:12 +00:00
**Contact information** is represented by the letter **c** followed by a list of numbers corresponding to the following table.
2018-09-22 06:45:36 +00:00
**Number** | **Name** | **Data type** | **Description**
--- | --- | --- | ---
1 | Email | String | Email address
2 | IM | String | Instant Messenger protocol handle
3 | Social | string | Social media service handle
4 | Mobile phone number | string | Personal cellphone number
5 | Home phone number | string | Residence phone number
6 | Work phone number | string | Work phone number
7 | Postal label | string | Postal label for a physical address to which a service can send letters and packages
### Special commands
The nonce can have a few special values that act as commands:
2018-09-22 06:45:36 +00:00
**Value** | **Description**
2018-09-22 00:08:05 +03:00
--- | ---
delete/cancel | Requests the service to delete this user account.
void/invalid/revoke/recall | This identity was compromised and must be disabled.
These commands must be supported at the same endpoint specified in URI, and can be sent unsolicited at any time by the user.
2018-09-21 19:23:21 +00:00
### Request examples
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.
2018-09-22 06:28:41 +00:00
```
cashid:example.com/signup?x=95261230581&r=i12l1c1&o=i567l3
```
2018-09-21 19:23:21 +00:00
2018-09-21 19:41:07 +00:00
The **verify** command (2FA) at **bankers.net** requires that the address **qqzafeafd...** authenticates
2018-09-22 06:28:41 +00:00
```
cashid:bankers.net/verify?x=23563567325&a=qqzafeafd...
```
2018-09-21 19:41:07 +00:00
The **login** command at **cashtalk.org** can make use of **Name** and **Last Name**, for example to update user profiles.
2018-09-22 06:28:41 +00:00
```
cashid:cashtalk.org/login?x=13534642624&o=i12
```
2018-09-21 19:41:07 +00:00
2018-09-22 06:28:41 +00:00
Request removal of all user data from **sensitive.cash**.
```
**cashid:sensitive.cash/login?x=delete**
```
## Response
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 should contain a single a valid JSON object:
2018-09-22 06:45:36 +00:00
**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.
metadata | String | Requested metadata fields encoded as a JSON object
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*
## Confirmation
The server responds to the POST with a valid JSON object:
2018-09-22 06:45:36 +00:00
**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** | **Error message** | **Description**
--- | --- | ---
0 | Authentication successful | ...
1 | Malformed request | ...
2 | Malformed URI | ...
3 | Timeout (nonce has expired) | ...
4 | Nonce has been already used | ...
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 | Service temporary unavailable | ... (or Busy, try again later)
8 | Signature verification failed | ...
9 | Access denied for this identity | ... (can be more detailed ban reason...)
10 | Access revoked | 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.
# Resources (to-do)
2018-09-21 17:04:02 +00:00
Supply a functional regexp!
* 1: that parses the request string
* 2: that parses the metadata scope
* QR code guidelines (case)
* nonce guidelines (probably alphanumeric, need to see what's good for QR, suggestion for length)
* code examples
* a website with interface/workflow example, similar to BitID
* social integration protocol
* interface guidelines (color-coding privacy impact, etc.)
* What about localization? Are local languages allowed for metadata or not?
* favicon or something more advanced to help identify the site in IM (guideline)