136 lines
5.4 KiB
Markdown
136 lines
5.4 KiB
Markdown
issuer@oauth3.org (js)
|
|
======================
|
|
|
|
Implementation of server-side RESTful OAuth3 issuer APIs.
|
|
|
|
These are the OAuth3 APIs that allow for creation and retrieval of public keys
|
|
used for signing identity tokens.
|
|
|
|
"issuer" is somewhat of a misnomer from the OIDC breakdown of authentication /
|
|
authorization parties. What we mean by "issuer" here is actually more like
|
|
"notary" or "authorized verifier". However, since the "iss" field is already
|
|
standardized, we keep that name for consistency.
|
|
|
|
What's to be implemented:
|
|
|
|
Looking at <https://oauth3.org/.well-known/oauth3/directives.json>, the core
|
|
issuer components are these:
|
|
|
|
```
|
|
api: api.:hostname
|
|
authorization_dialog #/authorization_dialog
|
|
logout #/logout
|
|
publish_jwk: :scheme//:hostname/api/issuer@oauth3.org/jwks/:sub
|
|
retrieve_jwk: :scheme//:hostname/api/issuer@oauth3.org/jwks/:sub/:kid.json
|
|
grants: :scheme//:hostname/api/issuer@oauth3.org/grants/:sub/:azp?
|
|
credential_meta: :scheme//:hostname/api/issuer@oauth3.org/logins/meta/:type/:id
|
|
credential_otp: :scheme//:hostname/api/issuer@oauth3.org/otp
|
|
```
|
|
|
|
No `access_token` endpoint is strictly necessary. Since clients can create and
|
|
manage their identity, the can sign create their own tokens. If the identity is
|
|
stored on the issuer, then the issuer can also sign tokens. Doing so gives full
|
|
control of all resources owned by the subject "sub" to the issuer "iss".
|
|
|
|
```
|
|
create_sub: :scheme//:hostname/api/issuer@oauth3.org/subs/:secret/:sub
|
|
```
|
|
|
|
And here are some others that are useful, but could be implemented differently
|
|
without breaking the protocol.
|
|
|
|
```
|
|
credential_create: :scheme//:hostname/api/issuer@oauth3.org/logins
|
|
credential_meta: :scheme//:hostname/api/issuer@oauth3.org/logins/meta/:type/:id
|
|
credential_otp: :scheme//:hostname/api/issuer@oauth3.org/otp
|
|
```
|
|
|
|
subject
|
|
-------
|
|
|
|
The `sub` field must be `sha256(secret + ':' + azp)`.
|
|
|
|
Example:
|
|
|
|
```js
|
|
var secret = '8f7acd369764df342d1581872ff5f70fcc261aa116b3c41dee7ca3474ee2020f' // cryto.randomBytes(32).toString('hex')
|
|
var sha256 = cryto.createHash('sha256');
|
|
sha256.update(new Buffer(secret, 'hex'));
|
|
sha256.update(':' + 'example.com');
|
|
|
|
var sub = sha256.digest('hex');
|
|
```
|
|
|
|
This way any issuer can transfer ownership of identity to any other issuer and
|
|
deterministically reproduce the ppid by virtue of the secret identity of the
|
|
subject and the public identity of the authorized party.
|
|
|
|
JWKs
|
|
----
|
|
We want the users to have the option of signing tokens using keys on their own
|
|
devices. This requires having a place to store the public half of those keys
|
|
on a server that can then server the public keys to resource providers for
|
|
signature verification.
|
|
|
|
### Publishing a JWK ###
|
|
* **URL** `:scheme//:hostname/api/issuer@oauth3.org/jwks/:sub`
|
|
* **Method** `POST`
|
|
* **Url Params**
|
|
* `sub`: The [subject](#subject) using the issuer hostname as the `azp`
|
|
* **Body Params**: The body should be a JSON object representing a
|
|
[JWK](https://tools.ietf.org/html/rfc7517#section-4).
|
|
|
|
### Retrieving a JWK ###
|
|
* **URL** `:scheme//:hostname/api/issuer@oauth3.org/jwks/:sub/:kid.json`
|
|
* **Method** `GET`
|
|
* **Url Params**
|
|
* `sub`: The [subject](#subject) for the 3rd party needing to verify a token
|
|
* `kid`: The [JWK thumbprint](https://tools.ietf.org/html/rfc7638) of the key
|
|
|
|
Currently only `EC` and `RSA` key storage is supported. All provided parameters
|
|
will be stored in the database, but only generic JWK parameters and parameters
|
|
specified as part of the public key for the `kty` by the
|
|
[JWA](https://tools.ietf.org/html/rfc7518#section-6) will be given back by the
|
|
GET request. This is to avoid compromising a key if the private portion or any
|
|
other potentially sensitive fields are given to us.
|
|
|
|
Grants
|
|
------
|
|
Grants represent the list of resources the user has allowed a party to access.
|
|
We store those permissions on the server so that users will not have to grant
|
|
the same privileges multiple times on different machines. We also store the
|
|
[subject](#subject) between the user and the `azp` to allow us to only serve
|
|
public keys associated with the correct user when retrieving JWKs.
|
|
|
|
### Saving/Modifying Grants ###
|
|
* **URL** `:scheme//:hostname/api/issuer@oauth3.org/grants/:sub/:azp`
|
|
* **Method** `POST`
|
|
* **Url Params**
|
|
* `sub`: The [subject](#subject) using the issuer hostname as the `azp`
|
|
* `azp`: The authorized party the grants are for
|
|
* **Body Params**
|
|
* `sub`: The [subject](#subject) using `azp` from the url
|
|
* `scope`: A comma separated list of the permissions granted
|
|
* **Response**: The same object returned when retrieving single grants
|
|
|
|
### Retrieving Grants ###
|
|
* **URL** `:scheme//:hostname/api/issuer@oauth3.org/grants/:sub/:azp`
|
|
* **Method** `GET`
|
|
* **Url Params**
|
|
* `sub`: The [subject](#subject) using the issuer hostname as the `azp`
|
|
* `azp`: The authorized party the grants are for
|
|
* **Response**
|
|
* `sub`: The same `sub` from the url
|
|
* `azp`: The same `azp` from the url
|
|
* `azpSub`: The `sub` for the `azp`
|
|
* `scope`: A comma separated list of the permissions granted
|
|
* `updatedAt`: The ms timestamp for the most recent change to the grants
|
|
|
|
### Retrieving All Grants For a User ###
|
|
* **URL** `:scheme//:hostname/api/issuer@oauth3.org/grants/:sub`
|
|
* **Method** `GET`
|
|
* **Url Params**
|
|
* `sub`: The [subject](#subject) using the issuer hostname as the `azp`
|
|
* **Response**: An array of objects with the same values as the single grant
|
|
get response.
|