| 
									
										
										
										
											2017-06-27 10:19:39 -06:00
										 |  |  | issuer@oauth3.org (js) | 
					
						
							|  |  |  | ====================== | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Implementation of server-side RESTful OAuth3 issuer APIs. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-30 14:26:12 -06:00
										 |  |  | These are the OAuth3 APIs that allow for creation and retrieval of public keys | 
					
						
							|  |  |  | used for signing identity tokens. | 
					
						
							| 
									
										
										
										
											2017-06-27 10:19:39 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-30 14:26:12 -06:00
										 |  |  | "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. | 
					
						
							| 
									
										
										
										
											2017-06-27 10:19:39 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | What's to be implemented: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-30 14:26:12 -06:00
										 |  |  | Looking at <https://oauth3.org/.well-known/oauth3/directives.json>, the core | 
					
						
							|  |  |  | issuer components are these: | 
					
						
							| 
									
										
										
										
											2017-06-27 10:19:39 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | api:                    api.:hostname | 
					
						
							| 
									
										
										
										
											2017-07-12 14:39:53 -06:00
										 |  |  | authorization_dialog    #/authorization_dialog | 
					
						
							|  |  |  | logout                  #/logout | 
					
						
							| 
									
										
										
										
											2017-08-01 10:16:09 -06:00
										 |  |  | publish_jwk:            :scheme//:hostname/api/issuer@oauth3.org/jwks/:sub | 
					
						
							| 
									
										
										
										
											2017-07-20 11:34:33 -06:00
										 |  |  | retrieve_jwk:           :scheme//:hostname/api/issuer@oauth3.org/jwks/:sub/:kid.json | 
					
						
							| 
									
										
										
										
											2017-06-27 10:19:39 -06:00
										 |  |  | 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 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-30 14:26:12 -06:00
										 |  |  | 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". | 
					
						
							| 
									
										
										
										
											2017-06-27 10:19:39 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | create_sub:       :scheme//:hostname/api/issuer@oauth3.org/subs/:secret/:sub | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-30 14:26:12 -06:00
										 |  |  | And here are some others that are useful, but could be implemented differently | 
					
						
							|  |  |  | without breaking the protocol. | 
					
						
							| 
									
										
										
										
											2017-06-27 10:19:39 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2017-08-01 10:16:09 -06:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2017-06-27 10:19:39 -06:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | subject | 
					
						
							|  |  |  | ------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `sub` field must be `sha256(secret + ':' + azp)`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Example: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-30 14:26:12 -06:00
										 |  |  | ```js | 
					
						
							| 
									
										
										
										
											2017-06-27 10:19:39 -06:00
										 |  |  | 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'); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-30 14:26:12 -06:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2017-07-12 14:39:53 -06:00
										 |  |  | subject and the public identity of the authorized party. | 
					
						
							| 
									
										
										
										
											2017-06-27 10:19:39 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-30 16:04:14 -06:00
										 |  |  | JWKs | 
					
						
							| 
									
										
										
										
											2017-06-27 10:19:39 -06:00
										 |  |  | ---- | 
					
						
							| 
									
										
										
										
											2017-06-30 16:04:14 -06:00
										 |  |  | 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 10:16:09 -06:00
										 |  |  | ### Publishing a JWK ###
 | 
					
						
							| 
									
										
										
										
											2017-06-30 16:04:14 -06:00
										 |  |  |   * **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 ###
 | 
					
						
							| 
									
										
										
										
											2017-07-12 14:39:53 -06:00
										 |  |  |   * **URL** `:scheme//:hostname/api/issuer@oauth3.org/jwks/:sub/:kid.json` | 
					
						
							| 
									
										
										
										
											2017-06-30 16:04:14 -06:00
										 |  |  |   * **Method** `GET` | 
					
						
							|  |  |  |   * **Url Params** | 
					
						
							| 
									
										
										
										
											2017-07-12 14:39:53 -06:00
										 |  |  |     * `sub`: The [subject](#subject) for the 3rd party needing to verify a token | 
					
						
							| 
									
										
										
										
											2017-06-30 16:04:14 -06:00
										 |  |  |     * `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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-30 16:09:04 -06:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2017-07-12 14:39:53 -06:00
										 |  |  | 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. | 
					
						
							| 
									
										
										
										
											2017-06-30 16:09:04 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | ### 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** | 
					
						
							| 
									
										
										
										
											2017-07-12 14:39:53 -06:00
										 |  |  |     * `sub`: The [subject](#subject) using `azp` from the url | 
					
						
							| 
									
										
										
										
											2017-06-30 16:09:04 -06:00
										 |  |  |     * `scope`: A comma separated list of the permissions granted | 
					
						
							| 
									
										
										
										
											2017-08-01 14:23:43 -06:00
										 |  |  |   * **Response**: The same object returned when retrieving single grants | 
					
						
							| 
									
										
										
										
											2017-06-30 16:09:04 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | ### 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 | 
					
						
							| 
									
										
										
										
											2017-08-01 14:23:43 -06:00
										 |  |  |     * `azpSub`: The `sub` for the `azp` | 
					
						
							| 
									
										
										
										
											2017-06-30 16:09:04 -06:00
										 |  |  |     * `scope`: A comma separated list of the permissions granted | 
					
						
							| 
									
										
										
										
											2017-06-30 16:33:51 -06:00
										 |  |  |     * `updatedAt`: The ms timestamp for the most recent change to the grants | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-12 14:39:53 -06:00
										 |  |  | ### Retrieving All Grants For a User ###
 | 
					
						
							| 
									
										
										
										
											2017-06-30 16:33:51 -06:00
										 |  |  |   * **URL** `:scheme//:hostname/api/issuer@oauth3.org/grants/:sub` | 
					
						
							|  |  |  |   * **Method** `GET` | 
					
						
							|  |  |  |   * **Url Params** | 
					
						
							|  |  |  |     * `sub`: The [subject](#subject) using the issuer hostname as the `azp` | 
					
						
							| 
									
										
										
										
											2017-07-12 14:39:53 -06:00
										 |  |  |   * **Response**: An array of objects with the same values as the single grant | 
					
						
							| 
									
										
										
										
											2017-06-30 16:33:51 -06:00
										 |  |  |     get response. |