High-risk transaction step-up flow
When a customer performs a high-risk action within an application (such as initiating a large financial transaction, adding a new payee, or performing other unusual money-movement activity) Strivacity can require <glossary:MFA> again without prompting for the customer’s username or password. This <glossary:MFA>-only step-up flow reuses the customer’s existing session and is handled through an <glossary:OIDC> authorization request combined with an 'After customer identification' lifecycle event hook.
Approach
- Starts a new OIDC authorization request when a high-risk action occurs.
- Passes the customer’s identifier in
login_hintand an encrypted payload containing the current access token inacr_value. - Uses an 'After customer identification' hook to validate the token and suppress the password and “Remember my device” authenticators, leaving only MFA active.
Prerequisites
- The customer is already authenticated, and the application holds a valid access token.
- The same OIDC client is used for both the initial login and the step-up request.
- An 'After customer identification' lifecycle event hook is available in the customer journey.
Where this fits in the journey
- The OIDC request begins the Identify step using the provided
login_hint. - The 'After customer identification' hook runs immediately after the customer is identified, validates the provided context, and configures the journey to require MFA only.
Step-up flow details
- A high-risk action in the application triggers a new <glossary:OIDC> authorization request, initiating a step-up authentication flow.
- The OIDC authorization request includes:
login_hint: the customer’s identifier.acr_value: an encrypted JSON payload that includes the current access token.Both
login_hintandacr_valueare passed as query parameters in the OIDC authorization request and must be URL-encoded to ensure they are transmitted safely in the request URL.
- Strivacity executes the 'After customer identification' hook, which evaluates the presence of an
acr_valueand adjusts the authentication flow accordingly.- If the
acr_valueis not present:
The standard login flow proceeds. MFA is required if defined in the Adaptive access policy. - If the
acr_valueis present:- Decrypt the payload.
- Extract the access token.
- Introspect the token to verify its validity (not expired, subject matches the identified customer, etc.).
- If the token is valid:
- Suppress the password authenticator.
- Suppress "Remember my device".
- Require MFA only.
- If the token is invalid, continue with the full authentication journey.
- If the token is valid:
- If the
- The customer completes MFA.
Use the introspection endpoint (https://{DOMAIN}/oauth2/introspect) to verify that the access token is valid, not expired, and belongs to the same customer.
Security considerations
- Encrypt the
acr_valuepayload (for example, a JSON object containing a timestamp and an access token). Because JWTs are base64-encoded and not encrypted by default, anyone with access to the authorization request could decode the payload if it were sent in clear text. Public-key encryption is recommended, but any secure, reversible encryption method is acceptable. - Include a timestamp or nonce in the payload and enforce a short expiration period to prevent replay attacks.
- Use the same client for both login and step-up.
Example: generating an encrypted acr_value
acr_valueconst PUB_KEY = `<public key>`;
function encryptPublic(data) {
const encryptedText = crypto.publicEncrypt(
{
key: Buffer.from(PUB_KEY),
padding: crypto.constants.RSA_PKCS1_PADDING
},
Buffer.from(JSON.stringify(data))
);
return encodeURIComponent(encryptedText.toString('base64'));
}
console.log(encryptPublic({
timestamp: new Date().getTime(),
accessToken: '<user access token>'
}))
Updated 13 days ago
