You agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts. View our Privacy Policy for more information.

Secure Sensitive User Profile Attributes in Auth0 (and other providers)

Privacy
Table of content:
Join our newsletter

Your privacy is important to us, privacy policy.

Using identity providers solution to store sensitive personal information

You may be using or thinking of using a third-party identity provider to deliver a tried and tested login process. You are doing this to take advantage of these products' robust authentication capabilities and the convenience of storing user attributes in user account profiles. This storage feature might seem to simplify data management, particularly in healthcare and financial applications, where ID and access tokens for downstream applications need to include additional user information.

Why you should NOT store personal data while using Identity providers

However, storing sensitive data in user profiles presents significant challenges. Identity providers are not built to store sensitive data, so their controls over user profile data are often limited. For example, these systems might internally log some of this data which could then be visible to the identity provider's engineers, creating an exposure that breaks your privacy policy or contravenes regulations. Therefore, while these systems can safely store basic information such as email or username, storing sensitive data such as social security numbers, health records (PHI), or financial details raises security, privacy, and compliance concerns.

Storing sensitive data in user profiles or embedding it in access tokens can inadvertently expose this information, potentially leading to unauthorized access or data breaches. Therefore, a way to secure this information is needed.

How to protect and store sensitive data while using identity providers solution

This article explores how to migrate and protect sensitive data in Auth0 as part of a lazy migration. However, you can apply the basic principles to other use cases, such as building a new system, and for other identity providers, such as Keycloak, frontegg, Amazon IAM, or Amazon Cognito.

The process of securing sensitive data while using identity providers solution

The migration process works like this: When a user first logs in, Auth0 obtains the user’s PII from your legacy user details database. Auth0 then uses scripts to store these details in Piiano Vault and saves the Piiano Vault object ID on the user’s metadata. Auth0 then shares credentials using a token that provides other systems access to the PII stored in Piiano Vault.

Before starting, you create a Piiano Vault users collection to store the user PII. A collection is easy to create using a free Piiano account. You also obtain an API key and set up users and their policies for the systems the identity provider shares PII with.

Now, the process works like this:

How to create a Piiano Vault users collection to store the user PII

1. The user provides their credentials to the Auth0 new universal login.

2. Auth0 validates the user using custom database lazy migration.

3. Your legacy database returns the user profile with the user PII needed for subsequent logins.

4. Auth0 creates an object for the PII in the users collection within Vault. Auth0 does this with a database action script, that uses Axios to provide promise-based handling of the REST API call, like this:

// Detect PII on first login and generate new object

exports.onExecutePostLogin = async (event, api) => {
    const axios = require('axios');
    const user_id = event.user.app_metadata.user_id;
    const ssn = event.user.app_metadata.ssn;
   
    if (user_id || ssn) {
      const options = {
        method: 'POST',
        url: event.secrets.PIIANO_BASE_URL + '/api/pvlt/1.0/data/collections/users/objects',
        params: {reason: 'AppFunctionality'},
        headers: {
         'Content-Type': 'application/json',
         Authorization: 'Bearer ' + event.secrets.PIIANO_API_KEY
        },
        data: {
          user_id: user_id,
          ssn: ssn
        }
      };
   
      try {
        const { data } = await axios.request(options);
        // console.log(data);
        api.user.setAppMetadata('pii_object_id', data.id);
        api.user.setAppMetadata('user_id', null);
        api.user.setAppMetadata('ssn', null)
      } catch (error) {
        console.error(error);
      }
    }
  };
   

5. Vault returns an object ID for the stored PII that Auth0 adds to the user’s  app_metadata, so it’s coupled to their profile. This process results in user record metadata something like this:

{
  “pii_object_id" : “f846cd21-54d7-4c73-9138-ab23a6538a86”
}
 

6. Auth0 deletes its copy of the PII, minimizing the exposure risk of this PII. 

7. When a downstream system needs the PII, Auth0 uses the object ID in a call to the Vault REST API tokenize operation to generate a non-sensitive ID.

Auth0 does this with a script like this:

// Detect a Piiano object record and request a PII token for the access token
 
exports.onExecutePostLogin = async (event, api) => {
    const axios = require('axios');
    const piiano_object_id = event.user.app_metadata.pii_object_id;
    if (piiano_object_id) {
      const options = {
       method: 'POST',
       url: event.secrets.PIIANO_BASE_URL + 'api/pvlt/1.0/data/collections/demo0/tokens',
       params: {reason: 'AppFunctionality'},
       headers: {
        'Content-Type': 'application/json',
         Authorization: 'Bearer ' + event.secrets.PIIANO_API_KEY
       },
       data: [
        {
         type: 'randomized',
         object: {id: piiano_object_id},
         props: ['user_id', 'ssn']
        }
       ]
      };
   
      try {
        const { data } = await axios.request(options);
        // console.log(data);
        api.accessToken.setCustomClaim('https://samyap.dev/pii_token', data[0].token_id);
      } catch (error) {
        console.error(error);
      }
    }
  };
   

8. Vault returns a token ID, which Auth0 appends to an access token for downstream systems to consume.

When the downstream system requests the PII, the token is exchanged securely for the PII by calling the Vault REST API detokenize operation.

In addition, the system owner can give each downstream system a profile that determines how it can access the PII data. For example, Vault could provide the raw user ID for third-party Substitutable Medical Applications and Reusable Technologies (SMART) on Fast Healthcare Interoperability Resources (FHIR) services.

On the other hand, for user verification during support workflows, it may provide a masked SSN that only exposes the last 4 digits. Looking at this in more detail, here is a user’s custom claim for a token with the ID 3e84e552-4d6d-43cb-a21e-0ae5b8ffb54d.

{
  "https://example.com/pii_token": "3e84e552-4d6d-43cb-a21e-0ae5b8ffb54d", 
  "iss": "https://auth.example.com/", 
  "sub": "google-oauth2|100614615268183779229", 
  "aud": [ 
    "http://localhost:8080", "https://examplecom.us.auth0.com/userinfo" 
  ],
  "iat": 1698092110,
  "exp": 1698128110,
  "azp": "jy9k2snrECCsGY6iDyTAOUFH9UEApycT",
  "scope": "openid profile email offline_access",
  "permissions": [
    "read:api",
    "write:api"
  ]
}
 

The other system can retrieve the PII from the vault using the token. In Vault, the client is set to receive a masked copy of the Social Security number. So it gets a response that looks like this: 

[ 
  { 
    "fields": { 
     "user_id": "45860945864", 
     "ssn": "***-**-1234" 
    }, 
    "token_id": "3e84e552-4d6d-43cb-a21e-0ae5b8ffb54d"
  } 
]
 
 

Conclusion

Identity providers are not designed to provide sensitive data with the protection users and regulation require. Following the process described in this article, for Auth0 or your choice of identity provider, you can take advantage of platforms like Piiano Vault to add the protection needed. Using Piiano Vault ensures sensitive user profile attributes are subject to less exposure risk, better protected, and privacy compliant while providing for your secure login requirements.

Share article

Powering Data Protection

Skip PCI compliance with our tokenization APIs

Skip PCI compliance with our tokenization APIs

It all begins with the cloud, where applications are accessible to everyone. Therefore, a user or an attacker makes no difference per se. Technically, encrypting all data at rest and in transit might seem like a comprehensive approach, but these methods are not enough anymore. For cloud hosted applications, data-at-rest encryption does not provide the coverage one might expect.

John Marcus

Senior Product Owner

const protectedForm = 
pvault.createProtectedForm(payment Div, 
secureFormConfig);
Thank you! Your submission has been received!

We care about your data in our privacy policy

Oops! Something went wrong while submitting the form.
Submit