Securing your Flow integration
How to take the next step and ensure your Flow is secure
The code we've written so far is for helping you try out Flow in your app quickly, but to deploy Flow live to your customers you need to cryptographically sign the
customer_reference field using your API secret.
NOTE: Without signing the
customer_reference field, your Flow integration will stop working after you've created 100 Flow sessions.
Signing your Customer Reference
To access your API secret, visit the "API Keys" tab in the integration settings modal you used earlier.
Using your API secret in the backend part of your application, create a Base64 encoded SHA-256 HMAC signature of the user identifier that you're passing to the
customerReference field for Flow.
We realize that's a mouthful, so for example, imagine we are using these values for our integration:
- Our customer's id is the UUID value
- Our API secret is
The correct signature for these values would be
TIP: Try confirming that your signature function outputs the same value as the example above before you move on to using real customer ids with your actual secret!
In Ruby, we would compute the signature with this code:
require 'openssl' require 'base64' def sign_customer_reference(api_secret:, customer_reference:) digest = OpenSSL::HMAC.digest( OpenSSL::Digest.new('SHA256'), api_secret, customer_reference ) return Base64.strict_encode64(digest) end signature = sign_customer_reference( api_secret: 'live_secret_abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234', customer_reference: "3a409367-a417-4d46-9a92-3d7bc5dc4605" ) puts signature # => yw0hqBPOIWcHPFZBsaMPnxktOrWwWkZcWP+TneV5D48=
If you need help generating your signature, please feel free to email
Providing your signature to Flow
Once you've got your customer referencing signing code implemented, we can shift our focus back to the frontend. You should now update your Flow initialization code to look like this:
currentUser.flowSignature is the value of the signature computed using your API secret and
Once you've updated your code, try launching Flow again like you did before we added signature. If your signature is correct, the Flow modal should open like it did before. If it doesn't, check the browser's developer console for error messages. Flow will log to
console.error if it detect an integration issue like an invalid signature.
Security checklist for signed requests
Before you go move on, review this checklist to make sure you're keeping your users secure
Flow signatures should only be computed on your backend.
Your application's backend should compute the Flow signature, then serve it to your frontend. Computing the signature on the frontend would expose your API secret to the world, giving anyone the ability to access all of the sensitive data associated with your Cognito account. If we detect API secrets exposed in insecure settings, we will immediately revoke the keys, which will break your integration.
Your users should not be able to generate signatures for anything besides their own id.
How you serve the signature from your backend is up to you. One approach would be to compute the signature on each page load using the current user's id and render it directly into the page. Another approach might be to implement an internal API endpoint like
/api/users/current/flow_signaturewhich computes the signature based on the user id associated with the current users session.
An insecure approach would be providing an internal API endpoint like
/api/compute_signaturewhich accepts a value for the backend to sign. This is insecure for the similar reasons to the first checklist item. An attacker could easily send many different values to this endpoint and create unique Flow sessions with them in order to subvert the compliance and anti-fraud checks Flow provides you.
customer_referencemust be unique and persistent per-user
Cognito uses the
customer_referenceto enforce that each of your customers can only complete their Flow once unless you authorize retries. If the
customer_referenceyou provide for a user in your system changes, Cognito cannot enforce this access control. You can read more about how the
customer_referenceis critical for your integration working properly and securely in the customer references section.
Your API secret should loaded into your application securely, and you should share it with as few employees as possible
In our code example above, we hardcoded the API secret for the sake of simplicity. In a real application, your API secret should be set as an environment variable on your production servers. For your development machines, you can use your Playground API Keys. When configuring your development machines, make sure a publishable key and template id from our playground environment
Requiring signed requests
Once you've verified that customer signatures are working with your application, you need to configure your Flow integration to only accept signed requests. You can enable this by visiting the Flow dashboard, opening the Integration Settings for your Flow template, selecting the "Going Live" tab, and toggling the setting for "Require Signed Requests."
NOTE: Your Flow integration will stop working after you've created 100 Flow sessions unless you have enabled "Require Signed Requests."
To sanity check that you've secured your integration, please review this checklist before going live:
- You've read the security checklist for signing customer signatures
- The value you're providing to
customerReferenceis unique and persistent for each user
- Your webhook receiver makes sure to check the signature of each request before processing the data
- Your domain whitelist settings contain only the domains you intend to use Flow on, and you've removed any temporary servers (like ngrok) once you're done using them
- You've added signed customer references to your integration, and understand that the API will stop working after 100 Flow sessions if you haven't enabled the "Require Signed Requests" setting