S3 Permissions & IAM Best Practices
The exact IAM policy Rilavek needs to operate. Nothing more.
Quick Reference
Rilavek operates on a write-only, least-privilege model. We never need to read your files back. The permission groups below are ranked by priority.
s3:PutObjects3:CreateMultipartUploads3:UploadParts3:CompleteMultipartUploads3:AbortMultipartUploads3:ListMultipartUploadParts
Core write + multipart. Without these, nothing works.
s3:ListBucket
Enables directory listings and empty-folder checks for FTP/SFTP clients. Not strictly required for HTTP/TUS uploads.
s3:GetObjects3:DeleteObject
GetObject: Keep disabled. A write-only policy means your bucket contents stay private by design, not by luck.
DeleteObject: Only add if you need FTP/SFTP clients to delete files.
IAM Policy
Replace YOUR-BUCKET-NAME with your actual bucket name.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RilavekBucketLevel",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::YOUR-BUCKET-NAME"
},
{
"Sid": "RilavekObjectLevel",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:AbortMultipartUpload",
"s3:ListMultipartUploadParts"
],
"Resource": "arn:aws:s3:::YOUR-BUCKET-NAME/*"
}
]
}s3:PutObject does not implicitly cover multipart actions. Switch to the Expanded policy if uploads fail.Why these actions?
s3:PutObject
The fundamental write operation. Every file Rilavek delivers to your bucket goes through PutObject. On AWS, this implicitly covers CreateMultipartUpload, UploadPart, and CompleteMultipartUpload, which is why the minimal policy is shorter.
s3:AbortMultipartUpload
Used to clean up incomplete uploads when a transfer is cancelled or an UploadId becomes stale. Without this, incomplete parts accumulate in your bucket and incur S3 storage costs.
s3:ListMultipartUploadParts
Before resuming an interrupted upload, Rilavek verifies the UploadId is still valid. This requires ListMultipartUploadParts. Without it, a resume attempt against an expired upload would fail silently with corrupted state rather than cleanly restarting.
s3:ListBucket
Applied at the bucket level, not object level. Used by FTP/SFTP clients to browse directory contents and to verify a folder is empty before deletion. Not required for HTTP/TUS pipelines.
Security Recommendation: Write-Only by Default
The safest configuration is write-only with no read access. With this posture, any access to your ingest credentials can only result in new data being written. Existing data remains inaccessible by design. Rilavek treats your bucket as a drop box, not a full filesystem.
Provider Setup & Access Key Guides
Find the direct credential setup guide and permission requirements for your specific cloud storage provider:
AWS S3
s3:PutObject implicitly covers multipart sub-actions. The minimal policy works as-is.
Backblaze B2
Create an Application Key scoped to a single bucket with Write Only capability. B2's S3 compatibility layer maps these automatically.
Cloudflare R2
Uses API tokens, not IAM policies. Grant Object Read & Write scoped to the specific bucket.
Wasabi Hot Cloud
Requires explicit multipart actions in the policy. Use the expanded variant if uploads fail with AccessDenied.
IDrive e2
No IAM policies. Permissions are set per access key in the e2 console. Select Write Only when creating the key and scope it to the target bucket.
DigitalOcean Spaces
Generate an Access Key under Spaces Object Storage > Access Keys in your DigitalOcean cloud console. Limited (scoped to your bucket) or account-wide Full access keys both work seamlessly.
RustFS
Generate an access token with write capabilities scoped to your target bucket from the RustFS management console.
Troubleshooting
AccessDenied on multipart upload
Your provider requires explicit multipart actions. Switch to the expanded policy.
NoSuchBucket
The bucket name in your data store config does not match an existing bucket. Double-check for typos and confirm the region.
InvalidAccessKeyId / SignatureDoesNotMatch
Credentials are incorrect. Regenerate the access key and secret from your provider console.
Empty directory listing via FTP/SFTP
Your IAM policy is missing s3:ListBucket. Add it to the bucket-level statement.
Resumed upload fails after provider lifecycle cleanup
The multipart upload was expired by a lifecycle rule. Rilavek will detect this and restart, but needs s3:ListMultipartUploadParts to verify the UploadId is still valid before resuming.