mirror of https://github.com/lukechilds/docs.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
7.1 KiB
157 lines
7.1 KiB
5 years ago
|
---
|
||
|
layout: learn
|
||
|
permalink: /:collection/:path.html
|
||
|
---
|
||
|
|
||
|
# Guide to Blockstack Auth
|
||
|
{:.no_toc}
|
||
|
|
||
|
Blockstack Auth provides single sign on and authentication without third parties or remote servers. On this page, you'll get an overview of authentication from a developer perspective. The following topics are covered:
|
||
|
|
||
|
* TOC
|
||
|
{:toc}
|
||
|
|
||
|
## Authentication flow
|
||
|
|
||
|
{% include sign_in.md %}
|
||
|
|
||
|
## Scopes
|
||
|
|
||
|
Scopes define the permissions requested from, and that a user accepts, through the sign-in dialog.
|
||
|
Decentralized apps may request any of the following scopes:
|
||
|
|
||
|
| Scope | Definition |
|
||
|
| -------------- | ------------------------------------------------------------------------------------ |
|
||
|
| `store_write` | Read and write data to the user's Gaia hub in an app-specific storage bucket. |
|
||
|
| `publish_data` | Publish data so that other users of the app can discover and interact with the user. | |
|
||
|
|
||
|
The permissions scope should be specified through the <a href="https://blockstack.github.io/blockstack.js/classes/appconfig.html" target="\_blank">AppConfig</a> object. If no `scopes` array is provided to the `redirectToSignIn` or `makeAuthRequest`
|
||
|
functions, the default is to request `['store_write']`.
|
||
|
|
||
|
## Manifest file
|
||
|
|
||
|
Decentralized apps have a manifest file. This file is based on the [W3C web app manifest specification](https://w3c.github.io/manifest/). The following is an example manifest file.
|
||
|
|
||
|
```
|
||
|
{
|
||
|
"name": "Todo App",
|
||
|
"start_url": "http://blockstack-todos.appartisan.com",
|
||
|
"description": "A simple todo app build on blockstack",
|
||
|
"icons": [{
|
||
|
"src": "http://blockstack-todos.appartisan.com/logo.png",
|
||
|
"sizes": "400x400",
|
||
|
"type": "image/png"
|
||
|
}]
|
||
|
}
|
||
|
```
|
||
|
|
||
|
The Blockstack App retrieves the manifest file from the app during the
|
||
|
authentication process and displays the information in it such as the
|
||
|
app `name` and to the user during sign in. The location of the app manifest file is specific
|
||
|
in the authentication request token and **must** be on the same origin as the app
|
||
|
requesting authentication.
|
||
|
|
||
|
The manifest file **must** have [Cross-origin resource sharing (CORS) headers](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) that allow the manifest file to be fetched from any arbitrary source. This usually means returning a header like this:
|
||
|
|
||
|
```
|
||
|
Access-Control-Allow-Origin: *
|
||
|
```
|
||
|
|
||
|
How you implement CORS depends in part on which platform/service you use to serve your application. For example, Netlify and Firebase have two different ways of configuring CORS. Consult your vendor documentation for more information.
|
||
|
|
||
|
## Key pairs
|
||
|
|
||
|
Blockstack Auth makes extensive use of public key cryptography. Blockstack uses ECDSA with the `secp256k1` curve. The following sections describe the three public-private key pairs used in the authentication process:
|
||
|
|
||
|
* how they're generated
|
||
|
* where they're used
|
||
|
* to whom the private key is disclosed
|
||
|
|
||
|
### Transit private key
|
||
|
|
||
|
The transit private is an ephemeral key that is used to encrypt secrets that
|
||
|
need to be passed from the Blockstack App to the decentralized app during the
|
||
|
authentication process. It is randomly generated by the app at the beginning of
|
||
|
the authentication response.
|
||
|
|
||
|
The public key that corresponds to the transit private key is stored in a single
|
||
|
element array in the `public_keys` key of the authentication request token. The
|
||
|
Blockstack App encrypts secret data such as the app private key using this
|
||
|
public key and sends it back to the app when the user signs in to the app. The
|
||
|
transit private key signs the app authentication request.
|
||
|
|
||
|
### Identity address private key
|
||
|
|
||
|
The identity address private key is derived from the user's keychain phrase and
|
||
|
is the private key of the Blockstack username that the user chooses to use to sign in
|
||
|
to the app. It is a secret owned by the user and never leaves the user's
|
||
|
instance of the Blockstack App.
|
||
|
|
||
|
This private key signs the authentication response token for an app to indicate that the user approves sign in to that app.
|
||
|
|
||
|
### App private key
|
||
|
|
||
|
The app private key is an app-specific private key that is generated from the
|
||
|
user's identity address private key using the `domain_name` as input. It is
|
||
|
deterministic in that for a given Blockstack username and `domain_name`, the same
|
||
|
private key is generated each time.
|
||
|
|
||
|
The app private key is securely shared with the app on each authentication, encrypted by the Blockstack App with the transit public key.
|
||
|
|
||
|
## JSON Web Token signatures
|
||
|
|
||
|
Both the `authRequest` and the `authResponse` tokens are [JSON Web Tokens](https://jwt.io/), and they are passed via URL query strings.
|
||
|
|
||
|
Blockstack's authentication tokens are based on the [RFC 7519 OAuth JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519)
|
||
|
with additional support for the `secp256k1` curve used by Bitcoin and many other
|
||
|
cryptocurrencies.
|
||
|
|
||
|
This signature algorithm is indicated by specifying `ES256K` in the token's
|
||
|
`alg` key, specifying that the JWT signature uses ECDSA with the secp256k1
|
||
|
curve. Blockstack provide both [JavaScript](https://github.com/blockstack/jsontokens-js)
|
||
|
and
|
||
|
[Ruby](https://github.com/blockstack/ruby-jwt-blockstack/tree/ruby-jwt-blockstack)
|
||
|
JWT libraries with support for this signing algorithm.
|
||
|
|
||
|
|
||
|
{% include note.html content="The Blockstack JWT implementation is different from other implementations because of the underlying cryptography we employ. There are libraries in <a href='https://github.com/blockstack/jsontokens-js'>Javascript</a> and <a href='https://github.com/blockstack/ruby-jwt-blockstack'>Ruby</a> available on the Blockstack Github to allow you to work with these tokens." %}
|
||
|
|
||
|
### Example: authRequest payload schema
|
||
|
|
||
|
``` JavaScript
|
||
|
const requestPayload = {
|
||
|
jti, // UUID
|
||
|
iat, // JWT creation time in seconds
|
||
|
exp, // JWT expiration time in seconds
|
||
|
iss, // legacy decentralized identifier generated from transit key
|
||
|
public_keys, // single entry array with public key of transit key
|
||
|
domain_name, // app origin
|
||
|
manifest_uri, // url to manifest file - must be hosted on app origin
|
||
|
redirect_uri, // url to which the Blockstack App redirects user on auth approval - must be hosted on app origin
|
||
|
version, // version tuple
|
||
|
do_not_include_profile, // a boolean flag asking Blockstack App to send profile url instead of profile object
|
||
|
supports_hub_url, // a boolean flag indicating gaia hub support
|
||
|
scopes // an array of string values indicating scopes requested by the app
|
||
|
}
|
||
|
```
|
||
|
|
||
|
|
||
|
### Example: authResponse payload schema
|
||
|
|
||
|
```JavaScript
|
||
|
const responsePayload = {
|
||
|
jti, // UUID
|
||
|
iat, // JWT creation time in seconds
|
||
|
exp, // JWT expiration time in seconds
|
||
|
iss, // legacy decentralized identifier (string prefix + identity address) - this uniquely identifies the user
|
||
|
private_key, // encrypted private key payload
|
||
|
public_keys, // single entry array with public key
|
||
|
profile, // profile object or null if passed by profile_url
|
||
|
username, // blockstack username (if any)
|
||
|
core_token, // encrypted core token payload
|
||
|
email, // email if email scope is requested & email available
|
||
|
profile_url, // url to signed profile token
|
||
|
hubUrl, // url pointing to user's gaia hub
|
||
|
version // version tuple
|
||
|
}
|
||
|
```
|