This guide describes a procedure that allows you to decrypt all of your Tanker app data, with minimal intervention from Tanker staff.

Tanker being a zero-access technology, the only way to decrypt all the data is to have access to both Tanker's database and the identities stored in your app. Therefore, this procedure requires a dump of the Tanker database, making this feature not available by default. It needs contractual and technical work from both parties before it can be used and it is not reversible.

Among other things, you should reach an agreement with Tanker on how a dump of your application data should be generated and made available to you.


  • An empty PostgreSQL 11 database
  • A 64-bit Linux environment capable of running compiled Go programs
  • The Tanker Exit Tool
  • The aforementioned dump of the Tanker database
  • All your user's identities

Before starting, you should stop encrypting new data in your application by removing all calls to encryption functions such as tanker.encrypt.


Importing the Tanker database

To setup the database, you need to fetch the SQL dump provided by Tanker staff using the agreed upon method and import it into an empty PostgreSQL database. This will create the required tables and populate them with raw data from your app.

The dump is split into multiple files. Each file name is prefixed by a number and a description. The numbers describe the order in which the scripts must be run.

Assuming a PostgreSQL database listening locally on port 5432, and with a user named user having all privileges on database exit, identified by the password p4ssword:

$ psql -v ON_ERROR_STOP=1 postgres://user:p4ssword@localhost:5432/exit < 1_*
$ psql -v ON_ERROR_STOP=1 postgres://user:p4ssword@localhost:5432/exit < 2_*
$ psql -v ON_ERROR_STOP=1 postgres://user:p4ssword@localhost:5432/exit < 3_*

The importation is split into the following three steps:

  1. Create the schema
  2. Insert the data
  3. Create the indexes that will be used by the exit tool


It is possible to speed up the import phase considerably by using UNLOGGED tables. The downside of this option is that if PostgreSQL crashes, all the contents of these tables will be lost, even if it was committed to disk long ago. You can make the tables UNLOGGED by editing the first file 1_schema.sql. For more information, please read the PostgreSQL documentation.

Now, you can run the tanker-exit-tool binary with that database. Here's an example:

$ tanker-exit-tool \
  --listen \
  --db "postgres://user:p4ssword@localhost:5432/exit" \
  --app-id <your app id>

Feel free to run tanker-exit-tool --help to see the full list of available options.

You should now have an HTTP server listening on port 8000. You can check by querying the /healthz end point:

$ curl -v
# should show a 200 OK status

In case of error, the exit tool will log it to stderr, you should forward it to your monitoring infrastructure.

Importing user identities

In order to decrypt any resource, the exit tool needs to access the identity of the user who first created it.

Those identities are stored on your application server, so you must import them inside the exit database.

You can use the following endpoint for this:

PUT /v1/identities
  • A Content-Type: application/json header should be set.
  • The body should be a JSON object contaning a list of user identities:
  "identities": ["<identity 1>", "<identity 2>", ...]

Upon success, a 201 HTTP status will be returned, otherwise an appropriate HTTP status will be returned, along with a json object describing the error.

It is advised to import the identities of your users in several batches. This way, in case of failure, you don't have one single large batch to retry.

Decrypting resources


Before using the decryption route, make sure all user identities have been imported in the exit database.

You can decrypt any resource using the following end-point:

POST /v1/decrypt

To decrypt a resource, send the encrypted binary data directly in the body of the request.

Upon success, a 200 HTTP status will be returned, and the body of the response will be the decrypted data. Otherwise an appropriate HTTP status code will be returned, along a json object describing the error.

This route can be used to decrypt data on the fly by the users of your application. To do that, just replace all calls to tanker.decrypt in your app by an HTTP call to this API.

This route can also be used by a service running in the background decrypting all of the encrypted data from your database.

It is possible to spawn multiple instances of the exit tool on the same database to handle heavy load.