Skip to main content

S3 Body Archival

Large or file-typed request and response bodies are offloaded to object storage instead of Postgres, for compliance and audit retention and to keep the dashboard responsive. Any S3-compatible store works: Amazon S3, Cloudflare R2, MinIO, DigitalOcean Spaces. Scope: Global defaults. Archival runs on the platform credential. On KnoxCall Cloud it is KnoxCall’s bucket and there is nothing to configure; on a self-hosted deployment save your bucket under Global defaults. The card is also offered under This tenant, but a workspace-scoped S3 row is not used for archival today — save it at platform scope.

1. In AWS (or your S3-compatible provider)

  1. Create the bucket first, with Block Public Access on and default encryption enabled. Note its region.
  2. IAM → Users → Create user, without console access.
  3. Attach an inline policy granting object operations only on that one bucket:
s3:ListBucket is not needed — KnoxCall addresses objects by key and never enumerates the bucket. No other service, no other bucket.
  1. Security credentials → Create access key → Application running outside AWS. Copy both halves.
Cloudflare R2: R2 → Manage R2 API tokens → a token with Object Read & Write on the one bucket; the endpoint is https://<account id>.r2.cloudflarestorage.com and the region is auto. MinIO: a service account scoped to the bucket; the endpoint is your MinIO URL.

2. Enter it in KnoxCall

Settings → Integrations → Global defaults → S3Configure: Save credentials.

3. Switch archival on (self-hosted)

The credential is where bodies go; a deployment flag decides whether they go. On a self-hosted host set in the server environment:
Bodies larger than the threshold, and file-typed bodies, are archived; the log entry keeps a reference and the dashboard fetches on demand.

4. Verify

Proxy a request with a large JSON response and open it under API logs — the body loads from the archive. On the store side, objects appear under an environment-named prefix.

Things that bite

  • Both key halves, or nothing. With one half stored the row is ignored and a self-hosted host falls back to the AWS_S3_* environment variables, or to no archival.
  • Region mismatch produces a 301 on every write. The region must be the bucket’s.
  • Storing the key does not turn archival on. Without the flag the row is inert.
  • Deletion and retention are KnoxCall’s: the retention purge deletes archived objects when it deletes the log rows they belong to, which is why DeleteObject is in the policy.