Documentation

Learn how to architect your data pipeline in minutes.

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.

Required
  • s3:PutObject
  • s3:CreateMultipartUpload
  • s3:UploadPart
  • s3:CompleteMultipartUpload
  • s3:AbortMultipartUpload
  • s3:ListMultipartUploadParts

Core write + multipart. Without these, nothing works.

Recommended
  • s3:ListBucket

Enables directory listings and empty-folder checks for FTP/SFTP clients. Not strictly required for HTTP/TUS uploads.

Situational
  • s3:GetObject
  • s3: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.

iam-policy.json
{
  "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/*"
    }
  ]
}
AWS only: On non-AWS providers like Wasabi or MinIO, 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-Specific Notes

ProviderNotes
AWS S3s3:PutObject implicitly covers multipart sub-actions. The minimal policy works as-is.
Cloudflare R2Uses API tokens, not IAM policies. Grant Object Read & Write scoped to the specific bucket.
WasabiRequires explicit multipart actions in the policy. Use the expanded variant if uploads fail with AccessDenied.
Backblaze B2Create an Application Key scoped to a single bucket with Write Only capability. B2's S3 compatibility layer maps these automatically.
MinIORequires explicit multipart actions. Use the expanded policy, or assign the built-in writeonly MinIO policy.
iDrive E2No 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. Key permissions cannot be changed after creation; delete and regenerate if you need to adjust them.

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.