Skip to main content
Payload encryption provides an additional encryption layer on top of standard TLS to support end-to-end privacy in scenarios such as man-in-the-middle attacks. This feature encrypts the uploaded file bytes before uploading to the presigned URL.
This is an optional feature and requires configuration parameters from Resistant AI.
Payload encryption is only available for API-based submissions. When enabled for your tenant, Web UI uploads will be disabled. Users will not be able to upload documents through the Web UI. Only submissions via the Documents API will be supported.

How it works (high level)

  1. You create a submission (standard flow).
  2. The API returns a presigned upload URL.
  3. You create a JWE compact encrypted payload from the original file bytes.
  4. You upload the encrypted payload to the presigned URL (same upload step, different request body).
  5. Resistant AI fetches the encrypted payload from object storage, decrypts it, and processes the file.
Payload Encryption Api Calls

Encryption format and algorithms

Payload encryption uses the JWE (JSON Web Encryption) standard in compact format with asymmetric key wrapping of the content encryption key (CEK). Supported algorithms:
  • Key management: RSA-OAEP-256
  • Content encryption: A256GCM (AES-256-GCM)

JOSE header requirements

Your JWE protected header must follow JOSE header rules and include: Example header:
  • alg (required): fixed to supported algorithm (RSA-OAEP-256) 
  • enc (required): fixed to supported encryption (A256GCM) 
  • kid (required): key identifier used for key rotation (provided by Resistant AI) 
  • zip (optional): compression algorithm applied before encryption; recommended to speed up transfer 
Header values must correspond to the actual JWE message; incorrect values can prevent decryption. 

Supported endpoints

Payload encryption currently applies to:
  • Data upload via presigned URL (only the upload request body differs; other parameters remain the same). 

Key rotation (kid)

Key rotation is supported using the kid header field.  Key rotation rules:
  • You must send the kid that matches the public key you use for encryption. 
  • When keys rotate, you must update both:
    • kid
    • the public key used for encryption 
  • Resistant AI provides:
    • new kid
    • new public key
    • timeline and transition period (old + new key valid for a period). 
If kid does not correspond to the public key used, decryption will fail on the Resistant AI side. 

Configuration required from Resistant AI

Configuration is specific per stage (testing vs production) and cell/region, and includes: 
  • Public key (public part of the asymmetric key)
  • Key ID (kid) corresponding to that public key
  • Key spec of the asymmetric key

Example implementation (Python)

Any RFC 7516 compatible JWE library can be used.  Example (Authlib JOSE) from the documentation: 

Operational impact

Web UI uploads are disabled when payload encryption is enabled. Users will not be able to submit documents through the Web UI. All submissions must go through the Documents API with encrypted payloads.
When payload encryption is enabled for your tenant:
  • API submissions only — all document uploads must use the Documents API with JWE-encrypted payloads
  • Web UI disabled — users cannot upload documents via the Web UI
  • Offline iFrame viewer — remains available for viewing results, but submission must be via API
  • Integration requirement — you must implement JWE encryption in your integration before enabling this feature

Operational guidance

  • Treat payload encryption as a per-environment configuration (testing/prod keys differ). 
  • Log only non-sensitive metadata (submission_id, timestamp, kid, environment). Do not log ciphertext or keys.
  • Plan a key rotation procedure (update public key + kid during the transition window).