The following guide uses oase.app as client_id. Your client_id should be the shortest possible domain name you control.
See this guide for your client_id:
Your client_id should be the shortest possible domain name you control. For example: oase.app.
Promise uses a simplified version of the Implicit Flow in the protocol OpenID Connect (OIDC).
To sign in users, redirect them to
https://promiseauthentication.org/a/oase.app?nonce=f02a114a
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://oase.app/authenticate?id_token=eyJhbGc...
The id_token will be a JWT looking like this:
{
"jti": "76b215ee-968e-4b83-9747-ccb5d7247e2f",
"sub": "unique-user-id",
"aud": "oase.app",
"iss": "https://promiseauthentication.org",
"iat": 1773569265,
"nonce": "f02a114a"
}
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.login here. If left out, Promise will show currently logged in user, if the user has chosen to be remembered.
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, id_token_hint.
Promise can be configured by Oase by providing a JSON object on
https://oase.app/.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://oase.app/.well-known/promise.json
we get
{
"allowed_redirect_uris": [
"oase://authenticate",
"https://oase.app/authenticate",
"https://beta.oase.app/authenticate",
"oase://third_party/authenticate",
"https://oase.app/third_party/authenticate",
"http://localhost:3000/third_party/authenticate"
],
"logo_url": "https://oase.app/favicon.png",
"name": "Oase"
}
Here's the logo that Oase provided:
Promise caches the JSON based on the HTTP headers:
{
"accept-ranges": "bytes",
"cache-control": "public,max-age=0,must-revalidate",
"cache-status": "\"Netlify Edge\"; hit",
"content-length": "348",
"content-type": "application/json",
"date": "Sun, 15 Mar 2026 10:07:45 GMT",
"etag": "\"98a34a9efd7b8a3b866267c2c4db523e-ssl\"",
"server": "Netlify",
"strict-transport-security": "max-age=31536000",
"x-nf-request-id": "01KKRFEM6SJQ9BZDJWXE42DJVW"
}
The configuration is needed everytime we show a sign in screen for Oase 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 Oase, you can add your Promise user ID to the Oase configuration of Promise:
{
…
admin_user_ids": [
"your-user-id-on-promise"
],
…
}
✨ That's it (for now)! ✨