Skip to main content

Reveal Tokenized Data

This guide will show you how to reveal sensitive data back to a customer without your frontend or backend code ever needing to touch the actual raw data.

Key concepts in this guide:

Getting Started

To get started, you will need a Basis Theory account.

Creating a Public Application

Next you will need a Public Application in order to create tokens, sessions and initialize our Elements libraries.

Click here to create a Public Application or login to your Basis Theory account and create a new application with the following settings:

  • Name - Public App
  • Application Type - Public
  • Permissions - token:create
Save the API Key from the created Public Application as it will be used later in this guide.

Creating a Token

To reveal tokenized data, you must have a token already created and stored with Basis Theory. If you haven't done it yet, head over to the Collect Data section of our docs for detailed guides on how to safely collect and tokenize data.

Configuring Basis Theory Elements

Basis Theory Elements are available for the following technologies. Click below for detailed instructions on how to install and configure them.

Javascript
React
iOS
Android

Creating a Text Element

To safely reveal tokenized data back to a customer, we must create an Element that will hold and display the data. In this example we'll create a Text Element, which can hold any string value.

import { BasisTheory } from '@basis-theory/basis-theory-js';

let bt;
let textElement;

(async () => {
bt = await new BasisTheory().init('test_1234567890', { elements: true });

textElement = bt.createElement('text', {
targetId: 'exampleTextElement',
});

// here #exampleTextElement is a DOM selector
// example: <div id="exampleTextElement"></div>
await textElement.mount('#exampleTextElement');
})();
Be sure to replace test_1234567890 with the Public API Key you created in Getting Started.

Creating a Session

Next, we'll create a Session. Sessions provide temporary elevated access to your public applications, and we'll use it to safely retrieve the data from the token. Add the following code to create a session:

import { BasisTheory } from '@basis-theory/basis-theory-js';

let bt;
let textElement;

(async () => {
bt = await new BasisTheory().init('test_1234567890', { elements: true });

textElement = bt.createElement('text', {
targetId: 'exampleTextElement',
});

// here #exampleTextElement is a DOM selector
// example: <div id="exampleTextElement"></div>
await textElement.mount('#exampleTextElement');

// this is just an example method that'll have the full lifecycle for revealing
const reveal = async () => {
const session = await bt.sessions.create();
}

})();

Authorizing a Session

In order to use the session to retrieve data, we need to authorize it with a Private Application.

Creating a Private Application

First, lets create the Private Application. To do so, Login to your Basis Theory account and create a new application with the following settings:

  • Name - Reveal Data
  • Application Type - Private
  • Access Rule (Use the Advanced Rule Builder option)
    • Description - Reveal Data
    • Container - /
    • Permissions - token:read
    • Transform - reveal
The Private Application must be in the same Tenant as the token to be revealed.
Save the API Key from the created Private Application as it will be used later in this guide.

Authorizing In the Backend

Using the Private Application API Key, the nonce from our session, and a Condition we ensure we are only granting authorization for the desired token.

The only way to ensure your private API keys are not publically accessible is for this step to execute in your backend service.

In this guide, we'll use Express.js as our backend but docs are available for different technologies. We'll create a backend.js file and add the following code to start the Express.js backend and authorize an incoming session.

backend.js
const express = require("express");
const { BasisTheory } = require("@basis-theory/basis-theory-js");

const app = express();
const port = 4242;

app.post("/authorize", async (request, response) => {
const bt = await new BasisTheory().init("test_priv_1234567890");
const { nonce } = request.body;
// authorizing a session returns an empty 200 response
await bt.sessions.authorize({
nonce: nonce,
rules: [
{
description: "Reveal Token",
priority: 1,
conditions: [
{
attribute: "id",
operator: "equals",
value: "token_id_1234567890",
},
],
permissions: ["token:read", "token:use"],
transform: "reveal",
},
],
});
// this response is arbitrary and not required
response.json({
result: "success",
});
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});

Start the server with the following command (from the same directory as backend.js).

node backend.js
Be sure to replace test_priv_1234567890 with the Private API Key you created in Creating a Private Application and token_id_1234567890 with the id for the token you wish to reveal.
In a real world scenario, make sure to include your own form of authentication between your frontend and backend for this request.

Calling the Authorization Endpoint

Next, from our client application, we'll call the authorization endpoint created on the Authorizing in the Backend step, passing our created session nonce:

import { BasisTheory } from '@basis-theory/basis-theory-js';

let bt;
let textElement;

(async () => {
bt = await new BasisTheory().init('test_1234567890', { elements: true });

textElement = bt.createElement('text', {
targetId: 'exampleTextElement',
});

// here #exampleTextElement is a DOM selector
// example: <div id="exampleTextElement"></div>
await textElement.mount('#exampleTextElement');

// this is just an example method that'll have the full lifecycle for revealing
const reveal = async () => {
const session = await bt.sessions.create();

await fetch('http://localhost:4242/authorize', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ nonce: session.nonce }),
});
}
})();

Retrieving and Revealing a Token

With the authorized session, we can now use the sessionKey to retrieve the token from the Basis Theory backend. We'll add the following code to retrieve the token and set its value to the text element.

import { BasisTheory } from "@basis-theory/basis-theory-js";

let bt;
let textElement;

(async () => {
bt = await new BasisTheory().init("test_1234567890", { elements: true });

textElement = bt.createElement("text", {
targetId: "exampleTextElement",
});

// here #exampleTextElement is a DOM selector
// example: <div id="exampleTextElement"></div>
await textElement.mount("#exampleTextElement");

// this is just an example method that'll have the full lifecycle for revealing
const reveal = async () => {
const session = await bt.sessions.create();

await fetch("http://localhost:4242/authorize", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ nonce: session.nonce }),
});

const token = await bt.tokens.retrieve("token_id_1234567890", {
apiKey: session.sessionKey,
});

textElement.setValue(token.data);
};
})();

🎉 The code above is the last bit that we need to reveal a token!

Conclusion

You can now reveal any data to a customer without your application accessing the underlying value, reducing compliance and regulatory scope. Just execute the reveal method in whichever way you desire (like with the click of a button) and watch the token value appear on your Text Element. If you need to reveal data stored outside of Basis Theory in a similar manner, check our Reveal Data from 3rd Party guide.

Learn More