Skip to main content

Reveal Tokenized Data

This guide will show you how to reveal sensitive data back to a customer without touching the data.

Key concepts in this guide:

Getting Started

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

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 is available for the following technologies. Click on the desired one for detailed instructions on how to install and configure it.

JavaScript Elements SDK

basis-theory-js

React Elements SDK

basis-theory-react

iOS Elements SDK

basistheory-ios

Android Elements SDK

basistheory-android

Creating a Text Element

To safely reveal tokenized data back to a customer, we must create an Element that'll hold 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 an alternative mechanism to grant temporary elevated access to your public applications, so we'll will 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

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

Now we can use the created Private Application API Key, and the nonce from our created session to authorize it. We'll also use a Condition to make sure our session is only authorized to reveal our desired token.

This step SHOULD be done on the backend as to not expose the Private Application's API Key publicly. 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}`);
});

Now we can 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, 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 iOS app accessing the underlying value, drastically 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.

Learn More