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 , the core issuer components are these: ``` api: api.:hostname create_jwk: :scheme//:hostname/api/issuer@oauth3.org/jwks/:sub jwks: :scheme//:hostname/api/issuer@oauth3.org/jwks/:thumbprint.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 authorization_decision :scheme//:hostname/api/issuer@oauth3.org/authorization_decision authorization_dialog :scheme//:hostname/api/issuer@oauth3.org/authorization_dialog logout :scheme//:hostname/api/issuer@oauth3.org/#/logout ``` 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 and the key is known to be good if the issuer "iss" can supply the public key that verifies the token, identified by its thumbprint "kid" (which the issuer knows without revealing its ppid of the subject and without the authorized party needing to reveal its ppid of the subject. 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. ### Saving 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/:kid.json` * **Method** `GET` * **Url Params** * `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. TODO: we need to somehow associate a key with a particular user without needing the issuer's subject. Resources providers will not have that subject but will need to be able to retrieve only public keys that actually belong to the user that are trying to validate. 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. ### 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** * `scope`: A comma separated list of the permissions granted ### 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 * `scope`: A comma separated list of the permissions granted * `updatedAt`: The timestamp for the most recent change to the grants