Skip to content

S3 Streaming and Multipart Uploads

Jaspreet Singh edited this page Apr 25, 2026 · 2 revisions

ActiveCipherStorage supports encrypted S3 workflows outside Rails Active Storage.

Use the S3 adapter when you want a Ruby service object, job, or API endpoint to encrypt files before uploading them to S3 and decrypt files when downloading or streaming them.

Direct S3 Encryption

s3 = Aws::S3::Client.new(region: "us-east-1")

adapter = ActiveCipherStorage::Adapters::S3Adapter.new(
  bucket: "my-bucket",
  s3_client: s3
)

adapter.put_encrypted("uploads/report.pdf", File.open("report.pdf", "rb"))
plaintext = adapter.get_decrypted("uploads/report.pdf").read

Streaming Downloads

For large encrypted objects, stream decrypted bytes without loading the whole file into memory:

adapter.stream_decrypted("uploads/large-video.bin") do |chunk|
  response.stream.write(chunk)
end

Streaming download validates encrypted chunk order and rejects trailing bytes after the final frame.

Multipart Uploads

For frontend chunk upload flows, the browser sends plaintext chunks to your backend. The backend encrypts those chunks and uploads encrypted multipart parts to S3.

uploader = ActiveCipherStorage::EncryptedMultipartUpload.new(
  s3_client: s3,
  bucket: "my-bucket"
)

session_id = uploader.initiate(key: "uploads/big-file.bin")
uploader.upload_part(session_id: session_id, chunk_io: params[:chunk].tempfile)
uploader.complete(session_id: session_id)

S3 Part Size

S3 requires multipart parts to be at least 5 MiB except for the final part. ActiveCipherStorage validates this early and raises a clear error if chunk_size is too small for multipart uploads.

Clone this wiki locally