Skip to main content
Some operations take Provider credentials, such as an API key or an OAuth client secret. These operations accept only an encrypted body. Your code encrypts the body with your Workspace’s public key, and only Parable can decrypt it. The private key stays in your Workspace’s key ring, the credential-encryption key that Data Encryption describes. The SDKs encrypt the body for you. Plain HTTP clients build the envelope themselves.

Operations that need an encrypted body

The API reference shows the body of these operations before encryption. Encrypt that JSON, then send the envelope in its place. If you send the plain JSON, the request fails with 400 Encrypted payload is required and changes nothing.

Get your Workspace’s public key

Each Workspace has its own key. Send GET /api/security/encryption-key with the X-Tenant header of the Workspace that you call. The operation needs no token.
Response (shortened)
You can keep the key and use it for many requests. A body that you encrypt with the key of a different Workspace fails to decrypt.
GET /api/security/content-encryption-key returns a different key, which Pulse clients use. A request body that you encrypt with it fails.

Encrypt with an SDK

Get the key with the SDK, give it to the client, then call the operation as usual. The client encrypts the body of each operation that needs it. It sends other operations unchanged.
The TypeScript, Python, and Go clients also take the key when you create them, as encryption.publicEncryptionKey, public_encryption_key, or Encryption.PublicEncryptionKey. Each call can also take its own key. The Rust client takes the key on each call only. Each SDK page shows how to create the client.

Build the envelope yourself

The AES_256_GCM_RSA_OAEP_256 envelope encrypts the body with a new AES key, then encrypts that AES key with your Workspace’s RSA key. Do these steps for each request:
  1. Serialize the request body as UTF-8 JSON.
  2. Make a random 32-byte AES key and a random 12-byte IV.
  3. Encrypt the JSON with AES-256-GCM, with no additional data. Keep the 16-byte authentication tag at the end of the ciphertext.
  4. Encrypt the AES key with RSA-OAEP. Use SHA-256 for the hash and for MGF1, with no label.
  5. Encode each binary value in standard Base64, with padding.
  6. Send this JSON object as the request body, with the usual Authorization, X-Tenant, and Content-Type: application/json headers.
The Python example needs the requests and cryptography packages. The Node.js example needs Node.js 18 or later.

The RSA-only envelope

The RSA_OAEP_256 envelope encrypts the JSON body directly with RSA-OAEP and SHA-256. It has only algorithm, keyId, and payload. A 4096-bit key encrypts at most 446 bytes this way, so most connection bodies do not fit. Use AES_256_GCM_RSA_OAEP_256.

Errors

Parable checks the token and its permissions first, then decrypts the body. A decryption error is a 400 problem response with no code. Its detail says what failed.