allow, step_up, review or block.
Auth0 already knows facts that make the score more accurate. Examples are whether the user verified the email and when the user last passed a second factor. auth_context is the part of the assessment request that carries these facts. fromAuth0 is the Auth0 adapter in each NoResponse SDK. It builds auth_context from the ID token claims that you verified, and you add the facts from the Auth0 user and session records.
Your backend does five things:
- Verifies the ID token: its signature, issuer and audience.
users.get: gets the account age and the verified phone.sessions.get: gets the session age.fromAuth0: turns the claims and the records intoauth_context.assessments.create: NoResponse returns the assessment.
What Auth0 can supply
The session record comes from the sessions endpoint of the Management API. Auth0 offers this endpoint on its Enterprise plans. On another plan, delete the session lines from the samples. The assessment then has no session age.
What Auth0 cannot supply
- Impersonation. Auth0 no longer offers impersonation. So the adapter sends
impersonated: false, unless an Action of yours adds anactclaim. - Roles. Auth0 puts roles in a namespaced custom claim that you choose, so the adapter does not read them. To keep them with the assessment, pass them as an override, such as
roles: ["admin"]. - An assurance level. Auth0 has no equivalent of
assurance_level.
Install
TypeScript
auth0 7 for Node.js, auth0-python 6 and go-auth0 1. Version 4 of the Node.js package has a different Management API client.
Do these three things in Auth0:
- Request the
openid email phonescopes at login, so that the ID token carriesemail_verifiedandphone_number_verified. - Create a machine-to-machine application with access to the Management API and the
read:usersandread:sessionsscopes. - Keep the ID token signing algorithm at RS256, the Auth0 default.
AUTH0_DOMAIN: your Auth0 tenant domain, such asexample.us.auth0.com. The Management API calls use it.AUTH0_ISSUER: optional. Set it when users log in through a custom domain. The value ishttps://, then that domain, then a trailing/. This value is theissof the ID token. The default ishttps://, thenAUTH0_DOMAIN, then/.AUTH0_CLIENT_ID: the client ID of the application that users log in to. It is the audience of the ID token.AUTH0_M2M_CLIENT_IDandAUTH0_M2M_CLIENT_SECRET: the credentials of the machine-to-machine application.NORESPONSE_API_KEY: your NoResponse key, with theassessscope. The TypeScript and Python clients read it themselves. The Go client takes it as an argument. The quickstart tells you how to get one.
Assess the new account
Assess each new account once. Do it on the first authenticated request for an Auth0 user that your database does not know yet. Do it before you create your own records for the account or give it access. The API answers within 3 seconds. The ID token is theid_token in the Auth0 token response. Your callback route receives it after the login redirect. Pass an ID token, not an access token for your API, because an access token carries no verified email. Your Auth0 SDK can verify the ID token first. Then pass its claims to the adapter and skip step 1. In express-openid-connect the claims are req.oidc.idTokenClaims.
TypeScript
ip is the public address of the client. Behind a load balancer, read it from the header that the load balancer sets, such as the last address that it appended to X-Forwarded-For. Never read it from a value that the client controls.
The Auth0 user id is the account_id, unchanged. auth0|64abc0de1234567890abcdef is a valid account id, and the Management API takes it when you act on the result later.
The flow is account creation, so NoResponse waits up to 3000 ms for its full set of sources. To wait only for the sources that answer within 500 ms, send depth: "quick". The other sources still finish later, and their results reach you through the webhook.
Act on the answer
The answer starts withassessment.account, the one current risk of the account. Your code acts on assessment.account.risk.decision, the decision for the flow that you sent:
allow: let the account in.step_up: ask for more proof first, such as a second factor.review: hold the account until your team looks at it.block: refuse the account. NoResponse answersblockafter you set a block threshold and the score reaches it.- Any other value: treat it as
review.
assessment.account.risk.score and assessment.account.risk.reasons tell you why. assessment.detail holds the facts of this assessment, such as its status, the sources that did not answer and the summary facts.
assessment.accountis absent while the first assessment of the account is still pending. Apply your fallback. Then take the final assessment from the webhook when it arrives.- If the call fails or times out, apply the same fallback.
What the adapter sends
This is theauth_context for a new user with a verified email who passed a one-time code a minute ago:
auth_context for a new user
audience is the audience of the ID token, which is the client ID of your application. audiences lists every value when aud holds more than one.
That context fires four reasons. account.risk.reasons lists each one with its weight:
auth_new_sessionandauth_new_accountraise the score for any new account.auth_email_verifiedandauth_mfa_recentlower it. They make this account different from one with nothing verified.
Late results
A slow source can raise an assessment after you allowed the new account. NoResponse then sendsassessment.updated. The Auth0 late-result provider in each SDK then acts on the Auth0 user through the Management API. It is auth0Actions in TypeScript, auth0_actions in Python and Auth0Actions in Go.
Act on late results has the full webhook handlers for Auth0. This section tells you what the Auth0 actions do on each plan.
The handler needs its own machine-to-machine application, with access to the Management API and these scopes:
Auth0 offers the session and refresh-token endpoints only on Enterprise plans. On every other plan, Free included, they answer
403 with the error code feature_not_enabled. The handler then falls back:
Without the sessions API, your code cannot end a login session. An application can use a login session to get new tokens through silent authentication. Blocking the user stops that, because Auth0 refuses the logins and refresh token grants of a blocked user. So on those plans
revoke_sessions does what ban does, and the result reports ban. Log result.action to see which one ran.
To let a blocked user back in, unblock the user in the Auth0 dashboard. You can also send PATCH /api/v2/users/{id} with {"blocked": false}.
Both actions are safe to repeat. A second delivery sets blocked: true again and finds no refresh tokens left to delete. A 404 for a user or credential that is already gone counts as done.
The Management API has rate limits, and the limits of the Free plan are low. Without the sessions API, a revoke makes one call per refresh token. When Auth0 answers 429, the handler waits and sends the same call again. A 429 means that Auth0 did nothing, so a repeat is safe for a delete too. The handler waits for the first of these that applies:
- The time that
Retry-Aftergives. - Else, until
X-RateLimit-Reset. - Else, 250 ms, 500 ms, 1 s and 2 s, in that order.
ProviderActionError with status 429. Answer with a 5xx, and NoResponse delivers the event again. Revoke and ban are safe to repeat.
Next steps
Turn an assessment into a decision
Rules for
allow, step_up, review and block.Pending, retries and idempotency
What a
pending answer carries and how retries work.Pass your auth session
Every
auth_context field and the six auth reason codes.Act on late results
Revoke sessions or ban when an assessment rises after account creation.