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.
 |