Skip to main content

Reveal Data from 3rd Party

This guide will show you how to reveal sensitive data from a third party 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.

Configuring Basis Theory Elements

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

Javascript
React
iOS
Android

Creating a Text Element

To safely reveal 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("<API_KEY>", { 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 <API_KEY> 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 will use it to safely authenticate the request to the third party. 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("<API_KEY>", { 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();
};
})();

Creating a Pre-Configured Proxy

To retrieve data from a third party URL without touching it, we will create a Pre-Configured Proxy

Creating a Management Application

To create a proxy, you will need a Management Application.

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

  • Name - Create Proxy
  • Application Type - Management
  • Permissions: proxy:create

Creating the Proxy in the Backend

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 create a proxy to the third party:

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

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

let bt = await new BasisTheory().init();

app.post("/create-proxy", async (request, response) => {
const proxy = await bt.proxies.create(
{
name: "Proxy to Third Party",
destinationUrl: "http://third_party_url.com",
requestTransform: {
code: `module.exports = async function (req) {
let { args: { body, headers }, bt } = req;

return {
body,
headers: {
...headers,
"Authorization": req.configuration.Credentials
},
}
};`,
},
configuration: {
Credentials: "credential_1234567890",
},
requireAuth: true,
},
{ apiKey: "<MANAGEMENT_API_KEY>" } // management application
);

response.send(proxy);
});

app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});

Notice that we are using a request transform to add the third party credentials to the Authorization header before making the request to the third party. These kind of values can be safely stored in the configuration object and re-use them for every proxy execution.

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

node backend.js

You can now use your favorite API client or just run the following curl command from your terminal:

curl -X POST http://localhost:4242/create-proxy
Be sure to replace <MANAGEMENT_API_KEY> with the Management API Key you created in Creating a Management Application, http://third_party_url.com with the third party URL and credential_1234567890 with the third party credentials (optionally).
Write down the key value returned from the proxy as its going to be used in the next steps.

Authorizing a Session

In order to use the session to securely invoke our proxy, we need to authorize it with a Private Application.

Creating a Private Application

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

  • Name - Invoke Proxy
  • Application Type - Private
  • Permissions - token:use
The Private Application must be in the same Tenant as Public Application used to create the Session.
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 and the nonce from our session we can grant temporary authorization to invoke the proxy.

The only way to ensure your private API keys are not publically accessible is for this step to execute in your backend service.
backend.js
const express = require("express");
const { BasisTheory } = require("@basis-theory/basis-theory-js");

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

let bt = await new BasisTheory().init();

app.post("/create-proxy", async (request, response) => {
const proxy = await bt.proxies.create(
{
name: "Proxy to Third Party",
destinationUrl: "http://third_party_url.com",
requestTransform: {
code: `module.exports = async function (req) {
let { args: { body, headers }, bt } = req;

return {
body,
headers: {
...headers,
"Authorization": req.configuration.Credentials
},
}
};`,
},
configuration: {
Credentials: "credential_1234567890",
},
requireAuth: true,
},
{ apiKey: "<MANAGEMENT_API_KEY>" } // management application
);

response.send(proxy);
});

app.post("/authorize", async (request, response) => {
const { nonce } = request.body;

// authorizing a session returns an empty 200 response
await bt.sessions.authorize(
{
nonce: nonce,
permissions: ["token:use"],
},
{ apiKey: "<PRIVATE_API_KEY>" }
); // private application

// this response is arbitrary and not required
response.json({
result: "success",
});
});

app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
Be sure to replace <PRIVATE_API_KEY> with the Private API Key you created in the Creating a Private Application step.
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("<API_KEY>", { 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 }),
});
};
})();

Invoking the Proxy and Revealing the Data

With the authorized session, we can now use the sessionKey to invoke our created proxy. We'll add the following code to retrieve the data 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("<API_KEY>", { 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 data = await bt.proxy.get({
headers: {
"BT-PROXY-KEY": "proxy_key_1234567890",
},
apiKey: session.sessionKey,
});

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

🎉 The code above is the last bit that we need to reveal data from a third party!

The data you receive as response from the proxy is not the raw data, but a synthetic reference to it that can only be used with setValue to display it.

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 response value from the proxy appear on your Text Element.

Learn More