Promise uses a simplified version of the Implicit Flow in the protocol OpenID Connect (OIDC).
The following guide uses example.com
as client_id
. Your client_id
should be the shortest possible domain name you control.
To sign in users, redirect them to
https://promiseauthentication.org/a/example.com?nonce=f67c2cee
The nonce
is a randomly generated string that enables protection against replay attacks.
Please notice that the client_id
is part of the URI. The other Authentication Request parameters are supplied as URL query parameters. Eg. ?nonce=abc
.
Now, Promise will take care of authentication and redirect the user back to
https://example.com/authenticate?id_token=eyJhbGc...
The id_token
will be a JWT looking like this:
{
"jti": "32e98538-264d-412f-b763-950af1d15519",
"sub": "unique-user-id",
"aud": "example.com",
"iss": "https://promiseauthentication.org",
"iat": 1714108533,
"nonce": "f67c2cee"
}
When receiving the id_token
, you have to
nonce
is not replayed.
https://promiseauthentication.org/.well-known/jwks.json
You can do that by using your preferred JWT library. Find yours here.
When you have validated the JWT, you must identify the user by concatenating both iss
and sub
. For example:
https://promiseauthentication.org|unique-user-id
This is important as this enables Promise in the future to delegate the responsibility of authentication to a provider chosen by the user.
Please notice that the users e-mail is not included in the JWT. This is by design. If you need an e-mail, or any other personal data belonging to the user, you will have to get that yourself by asking nicely.
The Authentication Request used in the implementation on Promise differs a bit from the general specification of the Authentication Request and the specification of Authentication Requests specifically for the Implicit Flow.
The parameters scope
and response_type
are ignored as they do not convey anything meaningful in the implementation used at Promise. response_type
is always "id_token"
.
sub
) for each client_id
. So you should pick your client_id
to be the shortest possible domain you control.redirect_uri
in the allowed_redirect_domain_names
in the configuration.jti
in the generated token, requiring a nonce is not the only possible way to mitigate replay attacks.
The following parameters is not implemented yet:
max_age
, ui_locales
, login_hint
, acr_values
.
The following parameters will probably never be implemented:
response_mode
, display
, prompt
, id_token_hint
.
Promise can be configured by example.com by providing a JSON object on
https://example.com/.well-known/promise.json
redirect_uri
. This list does not have to include the default redirect_uri
. Also be aware that localhost
and 127.0.0.1
is allowed by default, so no need to add that. You can also provide IP addresses.When fetching from
https://example.com/.well-known/promise.json
we get
{
}
Promise caches the JSON based on the HTTP headers:
{
"cache-control": "max-age=604800",
"content-type": "text/html; charset=UTF-8",
"date": "Fri, 26 Apr 2024 05:15:34 GMT",
"expires": "Fri, 03 May 2024 05:15:34 GMT",
"server": "EOS (vny/0451)",
"content-length": "433"
}
The configuration is needed everytime we show a sign in screen for example.com to a user, so allowing Promise to cache it seems sensible.
Suggested headers include Etag
and Cache-Control: public, must-revalidate, max-age=300
. But that would be your call.
If you want to become an admin for example.com, you can add your Promise user ID to the example.com configuration of Promise:
{
…
admin_user_ids": [
"your-user-id-on-promise"
],
…
}
✨ That's it (for now)! ✨