Security
Checklist
- Enable authentication: set
S3_USERS_FILE(orS3_ACCESS_KEY_ID+S3_SECRET_ACCESS_KEY). Without it, anyone can read and write. - Serve the API over HTTPS only, through a reverse proxy.
- Block
/_loch/usersat the proxy, or leaveS3_ADMIN_API_KEYunset. - Read the master key from a
0400file (S3_ENCRYPTION_KEY_FILE), not from the environment. - Keep the data directory on a case-sensitive filesystem, used only by Loch S3.
- Run the container read-only, without capabilities, with memory and PID limits. See Production deployment.
- Give each application its own user and grant it only the buckets it needs.
Built-in protections
| Area | Protection |
|---|---|
| Signatures | SigV4 checked in constant time; clock skew over 15 minutes refused; host and every x-amz-* header must be signed |
| Request bodies | Signed SHA-256 and aws-chunked chunk signatures verified; nothing is stored on mismatch |
| Presigned URLs | 1 second to 7 days; a bad signature never falls back to anonymous access |
| Paths | Bucket names and keys validated; ., .., empty segments and symlinks refused |
| Policies | Explicit Deny wins; unsupported fields refused instead of ignored; a stored policy that cannot be read denies |
| Encryption | Data encrypted before it is published; plaintext never lands under a bucket |
| Logs | No headers, query strings or keys in the logs |
| Resources | Header and body timeouts, minimum upload rate, connection cap, quota |
Known limits
UNSIGNED-PAYLOADand trailing checksums are accepted without verification: integrity then relies on TLS.- Encrypted objects keep their parameters in a metadata file that is not authenticated.
- A bucket-level
READgrant allows downloading every object of the bucket.
Full audit history and fixes: SECURITY.md.