Migrating user data
4 min read
This guide moves sensitive user data from your own data stores into Footprint's Nitro Enclave-backed vaults. Migrated users use the same vaulting APIs as users who onboard through Footprint's embedded KYC flows: create, decrypt, search, and proxy all work the same way. Progressive onboarding, watchlist checks, and embedded components also work on migrated user data.
Before you start
You need a server-side API key; see API authentication.
1. Create a user vault
If the user has no fp_id yet, create a vault with POST /users. Pass the data you already hold for the user as a key-value map, and the vault is created with it.
bash
The response returns the user's fp_id.
json1{ 2 "id": "fp_id_K0q6Eh6Rr3WOOfFBLPiHsr" 3}
The fp_id is the only identifier you need to store for this vault; every piece of vault data is referenced by it.
fp_id alongside the user's existing record in your database. Each user in your database should map to a single fp_id in Footprint.A successful response means the data passed validation, the vault exists, and the data is stored. Otherwise the error names the field that failed validation, and no vault is created.
A vault holds identity data, debit and credit card data, identity documents such as driver's licenses and passports, custom key-value records, and more. Footprint validates structured data as it is vaulted. The POST /users reference covers the field names and the request in detail.
2. Check data integrity (optional)
On a large migration you may want proof that what landed in the vault matches your database byte for byte. The integrity endpoint computes signed HMAC-SHA256 hashes of the vaulted values so you can compare them against your own. It is being phased out in favor of the transforms option on decrypt, which covers the same need; prefer that in a new integration.
Send a hex-encoded signing_key and the fields to check in fields. For each key in fields, the response contains hmac-sha256(signing_key, vault[key]).
bash1curl https://api.onefootprint.com/users/fp_id_K0q6Eh6Rr3WOOfFBLPiHsr/vault/integrity \ 2 -X POST \ 3 -u sk_test_CXUsbCR8j2kH6e5GeEl8eSBnQTIPCUaKpv: \ 4 -d '{ 5 "fields": ["id.first_name", "id.last_name", "id.ssn9", "card.my_alias.number"], 6 "signing_key": "a1f928d87278290bf9dece075d0e46330a01d21b346073f4f193739078dca458" 7 }'
The response returns one signature per field.
json1{ 2 "id.first_name": "6e9b8af84ffc8829f03911f73c997d27c62a4c2078d90320ebcb7dbbce0e39a5", 3 "id.last_name": "55c6c9c45dc54391fdd2f98d719095479ca3022f8583d1a6442d4c66889f8bb9", 4 "id.ssn9": "18568e3cd81f27a50e56750317d3446a3080f3aba4a726af3b848b51eb37071f", 5 "card.my_alias.number": "4f8a7abfbf11912991b364fd429f2a59cea4c859619692e712b628752cb83ecf" 6}
Next steps
- API reference for
POST /users. - Vault introduction covers reading, decrypting, and searching vault data.
- Vault Proxy lets you use vaulted data without your backend touching it.
Manual migration assistance
For help with a migration, email support@onefootprint.com with the details of your request. Encrypt any sensitive data with the PGP key below before sending it.
Footprint PGP instructions
Use GPG to import the public key below, then encrypt each file.
bash1gpg --encrypt --recipient 1ED420961981B558 <FILENAME>
In this command:
1ED420961981B558is Footprint's key ID.<FILENAME>is the plaintext file you are encrypting.<FILENAME>.gpgis the encrypted output to send to Footprint.
Footprint PGP public key
text1-----BEGIN PGP PUBLIC KEY BLOCK----- 2 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 50OwC3wKkvTn6QpiPA9DDuE3PSp2ZZ 51=EpSl 52-----END PGP PUBLIC KEY BLOCK-----