IMP uses S3-compatible object storage for chat attachments, session files, and knowledge source uploads. The bucket must exist before the application starts — IMP does not create it.
Supported backends
- AWS S3 — set
COMPANION_S3_ENDPOINT to empty / omit it.
- MinIO — set
COMPANION_S3_ENDPOINT to the MinIO API URL (e.g. http://exulu-minio:9000) and IMP enables forcePathStyle: true automatically.
- Any other S3-compatible store that supports presigned PUT URLs.
Presigned URL flow
File uploads go directly from the browser to the object store via presigned PUT URLs. The backend generates a signed URL, returns it to the frontend, and the browser uploads the file directly without passing through the backend. This keeps large uploads off the API process.
AWS SDK checksum gotcha. AWS SDK for JavaScript v3.729 and later injects an x-amz-checksum-crc32 header (computed over an empty body) into presigned PUT URLs by default. MinIO and some other S3-compatible stores validate that checksum against the uploaded bytes and reject the PUT with a checksum mismatch error, causing session file uploads to silently fail.IMP disables this default by setting requestChecksumCalculation: "WHEN_REQUIRED" and responseChecksumValidation: "WHEN_REQUIRED" on the shared S3 client (fix shipped in backend commit fa88d2e). If you build @exulu/backend from a revision older than that commit, upgrades to AWS SDK >= 3.729 will break file uploads against MinIO.
Create the bucket before starting IMP
IMP does not create the bucket. Create it first:
Or create it through the MinIO web console at http://localhost:9001.
Configuration reference
Compose excerpt (MinIO)
Point the backend at MinIO:
Operational notes
Network reachability. COMPANION_S3_ENDPOINT is used server-side (by the backend) to generate presigned URLs. The endpoint must be reachable from the backend container. If the backend and MinIO are on the same Docker network, use the container name (e.g. http://exulu-minio:9000). The presigned URL returned to the browser must resolve from the end user’s machine — configure a public URL or reverse proxy for MinIO’s API port if users are outside the Docker network.
Bucket policy. The bucket does not need to be public. Presigned URLs grant time-limited read and write access to individual objects without a bucket-level public policy.
Signature expiry. IMP presigns URLs with a 1-day expiry (expiresIn = 86400). Uploads or downloads attempted after the signature expires will receive a 403 from S3.