Active Cipher Storage 2.0.0
This is a breaking release that simplifies configuration, aligns the Rails integration with the official Active Storage service API, and removes legacy/unfinished APIs.
Highlights
- Rails integration now uses the canonical
ActiveStorage::Service::ActiveCipherStorageService. - Active Storage config remains simple:
service: ActiveCipherStoragewithwrapped_service:. - Provider setup is centralized through
config.providerandconfig.provider_options. EnvProvidernow receives the actual Base64 encryption key viaprovider_options[:encryption_key].- Large multipart uploads and streaming downloads are documented with clearer memory behavior.
- Legacy Active Storage adapter aliases and key-rotation APIs were removed.
Breaking Changes
-
Removed
ActiveCipherStorage::Adapters::ActiveStorageService.
UseActiveStorage::Service::ActiveCipherStorageServicethrough Railsstorage.yml. -
Removed
active_cipher_storage/active_storage_integration.
The engine now loads the Active Storage service directly. -
Removed global
Configuration#chunk_size.
Passchunk_sizewhere it is used:storage.ymlfor the Active Storage serviceS3Adapter.new(...)EncryptedMultipartUpload.new(...)StreamCipher.new(...)
-
Removed provider-specific config helpers such as
aws_kms/env_provider.
Useprovider_optionsinstead. -
Changed
EnvProviderconfiguration.Before:
config.provider_options[:env_var] = "ACTIVE_CIPHER_MASTER_KEY"
Now:
config.provider = :env config.provider_options[:encryption_key] = ENV.fetch("ACTIVE_CIPHER_MASTER_KEY")
-
Removed key rotation APIs:
ActiveCipherStorage::KeyRotationActiveCipherStorageService#rekeyBlobMetadata.blobs_forBlobMetadata.update_after_rotation- provider
wrap_data_key/rotate_data_key
Configuration
Environment key provider:
ActiveCipherStorage.configure do |config|
config.provider = :env
config.provider_options[:encryption_key] = ENV.fetch("ACTIVE_CIPHER_MASTER_KEY")
endAWS KMS provider:
ActiveCipherStorage.configure do |config|
config.provider = "aws:kms"
config.provider_options[:key_id] = Rails.application.credentials.dig(:aws, :kms_key_id)
config.provider_options[:region] = "us-east-1"
endAwsKmsProvider now builds its own Aws::KMS::Client and accepts endpoint, access_key_id, secret_access_key, and encryption_context.
Active Storage
Use the Rails-standard service wrapper:
encrypted_s3:
service: ActiveCipherStorage
wrapped_service: s3
chunk_size: 6291456The service wraps another Active Storage service, encrypts uploads before storage, and decrypts downloads transparently.
Multipart Uploads And Streaming Downloads
For frontend chunked uploads, use EncryptedMultipartUpload.
The app does not assemble the whole file before uploading. Each frontend chunk is read, encrypted into an authenticated ACS frame, and flushed to S3 multipart upload parts as encrypted bytes accumulate.
For large downloads, use streaming:
s3.stream_decrypted(key) do |chunk|
response.stream.write(chunk)
endAvoid get_decrypted for huge files because it buffers the encrypted object before decrypting.
Other Changes
- Blob metadata failures now rescue
StandardErroronly and re-raise in development. path_fornow raisesNotImplementedErrorwhen the wrapped Active Storage service does not support local paths.- The tracked
examples/directory was removed. Local sample apps can still be generated outside git as needed.
Verification
- RSpec:
120 examples, 0 failures - RuboCop: no offenses