Hey team! I was reading about the step up flow her...
# ask-a-descoper
f
Hey team! I was reading about the step up flow here: https://docs.descope.com/mfa-and-step-up/step-up and the article says that performing a step up will result with the token having
su
claim set to true with a specified expiry time. Can we narrow down the step up only to a specific action? We're building a fintech app where we want to perform the step up before financial transactions but we want to make sure that the
su
claim can be used only to a specific transaction, for example user is allowed to perform a transaction for X EUR to Y bank account. Are there any articles / examples that cover that scenario?
✅ 1
d
Hi, I'm Descope's AI assistant. I've put together an initial response below based on your question. A member of the support team will take over and follow up shortly. Step-Up + FGA Pattern To effectively implement step-up authentication tied to specific transactions in your fintech use case, follow this approach: 1. Trigger step-up before financial transactions 2. Use ReBAC/ABAC to validate specific transaction parameters 3. Combine both checks in your application logic Implementation Strategy After successfully triggering step-up authentication, you can use the following code to sign in:
Copy code
// After successful step-up (su: true in JWT)
const resp = await descopeClient.otp.signIn<loginId, {stepup: true}, token|deliveryMethod>;
Then validate the specific transaction using Fine-Grained Authorization (FGA): • Check if the user has permission for the specific amount • Verify recipient account authorization • Validate transaction-specific attributes FGA Documentation For more details on implementing relationship-based permissions (ReBAC) and attribute-based rules (ABAC), refer to the FGA documentation which covers the necessary controls to handle your transaction-specific requirements. This pattern provides both the security of step-up authentication and the granular control needed for financial transactions.
a
Hi @Filip Kajetaniak Thanks for reaching out! The
su
claim in the JWT is intentionally kept generic (a boolean + expiry) and doesn't natively bind to a specific transaction. However, you can absolutely achieve what you're describing by combining step-up with custom claims and/or FGA (Fine-Grained Authorization). Here's the pattern we'd recommend for your fintech use case: 1. Encode transaction context into custom claims at step-up time When triggering step-up, pass the transaction details as custom data so they get embedded into the JWT:
Copy code
// Trigger step-up with transaction-specific context
await descopeClient.flow.start("step-up-flow", {
  customClaims: {
    txn_amount: 500,
    txn_currency: "EUR",
    txn_recipient: "IBAN_XXXXXXXX",
    txn_id: "txn_abc123"
  }
});
2. Validate on your backend When the token reaches your backend, verify both the
su: true
claim and the transaction-specific claims match the operation being attempted:
Copy code
// Backend validation
const { su, txn_id, txn_amount, txn_recipient } = decodedToken;
if (!su || txn_id !== requestedTxnId || txn_amount !== requestedAmount) {
  return res.status(403).json({ error: "Step-up token not valid for this transaction" });
}
3. Keep the step-up expiry short Set a tight
suExpiresIn
(e.g., 60–120 seconds) so the elevated token can only be used in a narrow window, reducing replay risk. 4. Optionally layer FGA on top For even more granular control (e.g., does this user have permission to send to this recipient account at all?), you can use Descope's ReBAC/ABAC — docs here: https://docs.descope.com/authorization/rebac Descope handles the authentication elevation (step-up), but the transaction-specific authorization lives in your claims validation logic or FGA rules. The two work together rather than one replacing the other. Let me know if this helps you!
🙌 1
f
Thank you @Akash Jivane!!! Very helpful
🙏 1