Vault Proxy

11 min read

Vault proxy overview

In certain cases, your application may need to communicate sensitive data (like PII or PCI data) to third-party services (like payment gateways). With Footprint's Vault Proxy, you can avoid sensitive data touching your application code and infrastructure in plaintext. Not only does vault proxying help strengthen your security posture and avoid data leaks/compromises, but this also helps you satisfy strict compliance requirements (like PCI) by never having this data touch your networks or infrastructure.

The vault proxy supports the following main features:

FeatureOverview
Any HTTPS URL and methodWorks with any HTTPS resource
Flexible detokenizationSupports secure detokenization for any type of request body, content-type agnostic
Fixed IP rangeRequests from Footprint Vault Proxy always come from a fixed set of IP addresses that you can whitelist on the proxy destination
Custom headersAttach custom headers
Authentication secretsSecurely attach custom authentication secrets
Client Certififcates (mTLS)Securely attach a ceritificate + key for mTLS Client Certififcate authentication connections
Server Certificate PinningSpecify one or more Root CAs and leaf certificates to securely validate the destination
Ingress VaultingSecurely vault data that comes back on the ingress. Support for JSONPath (XPath and Regex coming soon) rules

Configuration

The proxy can be configured in two main ways: define the configuration using the dashboard/admin API or dynamically specify all the configuration values via headers "just-in-time."

Both methods support the same fundamental capabilities, but the two options offer flexibility in defining proxy configurations and simplifying the management of sensitive data and authentication credentials.

HeaderUsageDescription
x-fp-proxy-target-urlRequired if "just-in-time"The target destination HTTPS URL to which the request will be routed
x-fp-proxy-idRequired if proxy configurationThe id of the Proxy Configuration declared in the developer dashboard or created via the admin API
Vault proxy configuration

Basic Proxying

Making the proxy request

A vault proxy request consists of a typical authenticated HTTP POST request to the /proxy endpoint of the Footprint API.

For example:

bash


curl https://api.onefootprint.com/proxy \
    -u sk_test_CXUsbCR8j2kH6e5GeEl8eSBnQTIPCUaKpv: \
    -X POST \
    -H 'x-fp-proxy-target-url: https://payments.acmebank.com' \
    -H 'x-fp-proxy-fwd-custom-header: custom value' \
    -H 'x-fp-proxy-fwd-content-type: application/json' \
    --data '{
        "full_name": "{{ fp_id_tctecBEvGc98V7Vx4MhZU.id.first_name }} {{ fp_id_tctecBEvGc98V7Vx4MhZU.id.last_name }}",
        "last4_ssn": "{{ fp_id_tctecBEvGc98V7Vx4MhZU.id.ssn4 }}",
        "cc": "{{ fp_id_tctecBEvGc98V7Vx4MhZU.custom.credit_card }}",
        "cc_exp": "{{ fp_id_tctecBEvGc98V7Vx4MhZU.custom.credit_card_exp }}",
        "cc_cvc": "{{ fp_id_tctecBEvGc98V7Vx4MhZU.custom.credit_card_cvc }}"
    }'

The above request detokenizes each of the fields in the request body in the Footprint vault enclave, and then makes an upstream request with the corresponding in-place-updated plaintext body to the target (in this case https://payments.acmebank.com) with custom headers 'Custom-Header: custom value' and 'Content-type: application/json'.

You can add additional control headers to configure how the upstream proxy request behaves:

HeaderRequired?Function
x-fp-proxy-fwd-<HEADER>OptionalSends a header named <HEADER> with the corresponding value
x-fp-proxy-methodOptionalSelects the HTTP Method Verb to use (defaults to POST if unspecified)
x-fp-proxy-access-reasonOptionalThe decryption reason to use for access/security logs during detokenization. Defaults to empty/no-reason.

Token body template format

Footprint's Vault Proxy will attempt to substitute in-place any tokens found in the body of the request with the corresponding detokenized, plain-text values. A token expression starts with {{ and ends with }}.

Footprint's vault proxy APIs support two methods of specifying tokens in the request body:

Fully-qualified tokens

Each token is specified as {{ <footprint_user_token>.<data_identifier> }}. <footprint_user_token> is the user's footprint token. <data_identifier> can be any identity KYC attribute (prefixed with id.) or any custom attribute defined by you (prefixed with custom.)

Fully-qualified format
{{ fp_id_tctecBEvGc98V7Vx4MhZU.id.last_name }}
{{ fp_id_tctecBEvGc98V7Vx4MhZU.id.ssn9 }}
{{ fp_id_tctecBEvGc98V7Vx4MhZU.id.dob }}
{{ fp_id_tctecBEvGc98V7Vx4MhZU.custom.credit_card }}

Inferred-user tokens

If you're operating on a single Footprint user vault, you can simplify the token body formatting by specifying the following header to identify which user vault is referenced.

HeaderValue
x-fp-proxy-footprint-tokenThe Footprint user token used to infer request tokens

In this case, the token can omit the <footprint_user_token> above and specify tokens as {{ <data_identifier> }}.

Inferred-user format
{{ id.last_name }}
{{ id.ssn9 }}
{{ id.dob }}
{{ custom.credit_card }}

Advanced proxy features

Footprint's vault proxy supports advanced configurations such as mTLS (client certificates), certificate pinning (custom server certificates), and automatically selecting and tokenizing parts of the response data and storing it in the vault. Note that the guide below shows how to configure these advanced features using "just-in-time" headers, but we recommend specifying these instead using the developer dashboard for simplicity and greater security (you won't need to manage authentication secrets for the destination service).

Client certificate authentication (mTLS)

Optionally, specify a client certificate and key in order to connect securely to the proxy destination using Mutual TLS (mTLS).

Only a single cert/key pair can be supplied. Note the format of the certificate/key is in PEM and then Percent-encoded.

Service certificate pinning and Root CAs

Optionally, specify zero or more server certificates or Root CAs to pin the upstream proxy request server certificate validation.

If multiple certificates are specified, all the supplied certificates will be used in the validation process and as long as a single certificate can validate the incoming certificate chain, the connection will succeed. Note the format of the certificate/key is in PEM format and then Percent-encoded.

Ingress Vaulting

Ingress vaulting rules define how to tokenize and vault certain sensitive fields that appear in the response from the upstream proxy destination. This allows the vault proxy to not only de-tokenize outgoing data but to also tokenize incoming data to vault it just in time.

For simplicity, you can also define all of your ingress vaulting rules via the developer dashboard or admin API and simply reference the proxy configuration via the x-fp-proxy-id header.

However, when you declare ingress vaulting rules in the configuration, you still need to denote in the proxy request into which Footprint user vault to tokenize the data. Therefore, the following header value is required when using ingress rules for pre-configured proxy:

HeaderFormatvalue
x-fp-proxy-footprint-token<footprint_user_id>The Footprint user token for which the vaulting rules apply too

For example: add the header 'x-fp-proxy-footprint-token: fp_id_tctecBEvGc98V7Vx4MhZU' where the rule in the proxy configuration would be defined as custom.credit_card_number=$.data.card.number.

Just-in-time ingress vaulting

The format of the rule is defined as <footprint_token_id>.custom.<property_name>=<path-to-value> where the path format is relative to the content-type being used.

Note if using a dynamic proxy configuration (just-in-time), you must specify a single x-fp-proxy-ingress-content-type header if one more x-fp-proxy-ingress-rule headers are present. Ingress rules use a similar token format to the body format above, except without the {{ and }} delimiters.

JSONPath

Currently ingress only supports JSON and the associated JSONPath format for specifying a target value.

bash

-H 'x-fp-proxy-ingress-rule: fp_id_tctecBEvGc98V7Vx4MhZU.custom.credit_card_number=$.data.card.number'

The above token would extract 4242424242424 from the following response object and vault it under the custom.credit_card_number field for fp_id_tctecBEvGc98V7Vx4MhZU's user vault.

json

{
  "data": {
    "card": {
      "number": "4242424242424",
      "exp": "04/24"
    },
    "processor": "amex"
  }
}
More examples
fp_id_tctecBEvGc98V7Vx4MhZU.custom.credit_card.number=$.data.card.number
fp_id_tctecBEvGc98V7Vx4MhZU.custom.credit_card.exp=$.data.card.expiration
fp_id_tctecBEvGc98V7Vx4MhZU.custom.credit_card.cvc=$.data.card.security_code

Header and Configuration Reference

Below find the complete reference guide of headers and their uses for both configuring and invoking the proxy "just-in-time". Note that some values can be defined in the proxy configuration settings and do not need to be sent each time.

HeaderUsageDescription
x-fp-proxy-target-urlRequired if "just-in-time"The target destination HTTPS URL to which the request will be routed
x-fp-proxy-idRequired if proxy configurationThe id of the Proxy Configuration declared in the developer dashboard or created via the admin API
x-fp-proxy-methodOptional.Selects the HTTP Method Verb to use (defaults to POST if unspecified). Overrides a configuration's value if present.
x-fp-proxy-fwd-<HEADER>Optional. Multiple allowed.Sends a header named <HEADER> with the corresponding value
x-fp-path-and-queryOptional.Use this header to customize/add additional path and/or query parameters to your existing proxy target URL
x-fp-proxy-footprint-tokenOptional.The Footprint user token for which the proxy rules apply to. Required if tokens in the body dont specify an fp_id_ prefix.
x-fp-proxy-access-reasonOptional.The decryption reason to use for access/security logs during detokenization. Defaults to empty/no-reason.
x-fp-proxy-client-certOptional. Percent-encoded PEMThe client certificate to use
x-fp-proxy-client-keyOptional. Percent-encoded PEMThe client certificate private key to use
x-fp-proxy-pin-certOptional. Percent-encoded PEM. Multiple allowed.A root CA certificate or self-signed certificate to validate the certificate of the server
x-fp-proxy-ingress-content-typeOptional.The content-type of the response to process ingress rules. Currently only json is supported, but regex and xml are coming soon!
x-fp-proxy-ingress-ruleOptional. <token>=<path>. Multiple allowed.Ingress rule itself, assigning a specific namepspeced token to the corresponding path of the value to vault

Configure via Admin API

In some cases you may want to create a proxy configuration in an API call.

First specify your proxy configuraton object

json

{
  "url": "https://api.acmepayments.com/v1/generate_card",
  "method": "POST",
  "name": "Acme Payment Gateway Proxy",
  "access_reason": "Generate credit card number for user",
  "pinned_server_certificates": [
    "-----BEGIN CERTIFICATE-----\nMIIFiDCCA3CgAwIBAgIJAJONEl2..."
  ],
  "client_identity": {
    "certificate": "-----BEGIN CERTIFICATE-----\nMIIFa...",
    "key": "-----BEGIN PRIVATE KEY-----\nMIIJRAIBADAN..."
  },
  "headers": [
    {
      "name": "content-type",
      "value": "application/json"
    }
  ],
  "secret_headers": [
    {
      "name": "x-acme-api-key",
      "value": "6WvVKOtTi9NAvJTfPDxZOPwa..."
    }
  ],
  "ingress_settings": {
    "content_type": "json",
    "rules": [
      {
        "token": "custom.credit_card",
        "target": "$.data.card_number"
      }
    ]
  }
}

Note that pinned_server_certificates and client_identity parameters are optional settings and can be omitted. Only uses these if the third-party destination requires mTLS and/or uses custom server certificate CAs.

POST the Proxy Configuration

bash

curl -X POST -u <YOUR_API_KEY>: https://api.onefootprint.com/org/proxy_configs -H 'Content-Type: application/json' -d @object.json

{
  "id":"proxy_id_AY5ec7I5QDUFWG8BAQG78k",
  ...
}

Take note of the id that comes back, for example: proxy_id_AY5ec7I5QDUFWG8BAQG78k. You will use this to invoke the proxy.

Invoke the Proxy

In this example we invoke the proxy to generate a credit card number for user by securely passing tokens for the user's PII and on the recieving end vaulting the resulting card number to the user's vault.

bash

curl  -X POST -u <YOUR_API_KEY>: \
      -H 'x-fp-proxy-id: proxy_id_AY5ec7I5QDUFWG8BAQG78k' \
      -H 'x-fp-proxy-footprint-token: fp_id_ABoOtcf9DbF6shyLNONT3n' \
      --data '{
          "ssn_last_four": "{{ id.ssn4 }}",
          "date_of_birth": "{{ id.dob }}",
          "name_on_card": "{{ id.first_name }} {{ id.last_name }}",
          "data": { "card_number": "1234-4567-8910"}
      }'

Playground

Use our ditto server to test your proxy configurations. Sending requests to https://ditto.footprint.dev will replay the headers and body of any incoming requests. Give it a try!

Basic usage

bash

$ curl -i -X POST https://ditto.footprint.dev -H 'Test-Header: FootprintRocks'  --data '{"hello": "world" }'

test-header: FootprintRocks
content-type: application/x-www-form-urlencoded

{"hello": "world" }

By using https://ditto.footprint.dev as your proxy destination target, you can test that the proxy decryption and token templating is working as expected.

Testing with client certificates

The footprint ditto server also supports testing mTLS with client certificates: use https://ditto.footprint.dev:8443 (port 8443). Note that the server certificate is self-signed so you must either trust it or pin it the configuration.

bash

$ curl --cert client.crt --key client.key -i -k -X POST https://ditto.footprint.dev:8443 -H 'Test-Header: FootprintRocks' --data '{"hello": "world" }'

x-ditto-client-cert-serial: 12431179266346922388
test-header: FootprintRocks
content-type: application/x-www-form-urlencoded

{"hello": "world" }

Note the ditto server echoes the client certificate SERIAL (if a client certificate is used) in the special header x-ditto-client-cert-serial.