Skip to content

Request Encryption

All Flanks APIs use TLS on top of the HTTP connection to provide point-to-point encryption and ensure the content of any intercepted request remains secret.

However, sometimes there’s a need to provide an extra layer of encryption. For example, if a request must pass through different internal systems and you don’t want those systems to have access to the request content. This may be the case if one component has the Flanks access_key and acts as a “proxy” for other components, but does not need to know the content of the requests.

For this, Flanks uses JSON Web Encryption, or JWE. JWE’s are a special kind of JSON Web Tokens (JWT)

Encrypted Requests with JWE

JSON Web Encryption (JWE) represents encrypted content using JSON-based data structures. It is a standardized protocol and many programming languages have tooling to generate, decrypt and validate them.

  • The sender generates the original message (OM) as a JSON string
  • The sender obtains a public key (PK) from Flanks
  • Then, it generates a Content Encryption Key (CEK), a single-use symmetric only for the request.
  • Then, a JWE is assembled:
  • The original message (OM) is encrypted using the CEK
  • The CEK is itself encrypted using the public key (PK)

This ensures that the content is only accessible to whoever has the private key corresponding to the public key (PK) used in the generation of the JWE.

Flanks Public Key Set

The public keys accepted by Flanks are published using a standard format, JSON Web Key Set, which is a JSON file with a list of JSON Web Keys (JWK). This file is meant for automatic consumption and it’s always available at:

https://api.flanks.io/.well-known/jwks.json

All the keys present there can be used to encrypt a JWE at the moment of consumption.

Sending a JWE to Flanks

All the requests to our APIs accept the application/json format. You can choose to send a JWE instead for any request.

To send a JWE, you need to:

  • Choose one of the available public keys from flanks’ JWKS
  • Generate the JWE token (in compact form) from your original content
  • Send a request with the JWE as the body and set the header "Content-Type": "application/jose"

Python Example

import json
import requests
from jwcrypto import jwe, jwk


# Original content, as JSON string
original_conent = json.dumps({})


# Get Flanks' public keys and select one
r = requests.get("https://api.flanks.io/.well-known/jwks.json")
jwks = jwk.JWKSet.from_json(r.text)
public_key = list(jwks)[0]


# Generate the JWE object
protected_header = {
   "alg": "RSA-OAEP-256",
   "enc": "A256CBC-HS512",
   "typ": "JWE",
   # This will instruct the receiver to use this specific key to
   # decrypt the JWE
   "kid": public_key.kid,
}
jwe_obj = jwe.JWE(
   original_conent,
   recipient=public_key,
   protected=protected_header,
)
# The JWE in JWT compact format
encrypted_content = jwe_obj.serialize(compact=True)


# Send the request to Flanks
r = requests.post(
   "https://api.flanks.io/any-endpoint",
   headers={
       # Signal the content is a JWT (JWE)
       "Content-Type": "application/jose",
       # Authentication works the same way
       "Authorization": "Bearer YOUR_ACCESS_TOKEN",
   },
   data=encrypted_content,
)