AWS Encryption SDK for Elixir
An Elixir implementation of the AWS Encryption SDK, providing client-side encryption compatible with all other AWS Encryption SDK implementations (Python, Java, JavaScript, C, CLI).
Current Status
Version: 1.0.0
Features
- Algorithm suite definitions (all 17 ESDK suites)
- HKDF key derivation per RFC 5869
- Message format serialization/deserialization (v1 and v2 headers)
- Basic encrypt/decrypt operations
- Framed and non-framed body formats
- Key commitment verification for committed algorithm suites
- Test vector harness for cross-SDK compatibility testing
- Keyring behaviour interface
- Raw AES keyring
- Raw RSA keyring (all 5 padding schemes)
- Multi-keyring composition
- Cryptographic Materials Manager (CMM) with Default implementation
- Client module with commitment policy enforcement
- ECDSA signing for signed algorithm suites (P-384)
- Support for all 17 algorithm suites
- AWS KMS Keyring
- AWS KMS Discovery Keyring
- AWS KMS MRK Keyring
- AWS KMS MRK Discovery Keyring
- Streaming encryption/decryption
- Caching CMM
- Required Encryption Context CMM
Test Coverage
- 852 tests passing
- 92.6% code coverage
Installation
Add aws_encryption_sdk to your list of dependencies in mix.exs:
def deps do
[
{:aws_encryption_sdk, "~> 1.0"}
]
end
That is the complete installation for raw-keyring usage (RawAes,
RawRsa, and Multi compositions of them): fully offline envelope
encryption in the ESDK message format, with no AWS account, credentials,
or HTTP stack involved.
With AWS KMS
The AWS client stack is optional. To use the KMS keyrings
(AwsKms, AwsKmsDiscovery, AwsKmsMrk, AwsKmsMrkDiscovery), add
the four optional dependencies to your own list:
def deps do
[
{:aws_encryption_sdk, "~> 0.7.0"},
{:ex_aws, "~> 2.7"},
{:ex_aws_kms, "~> 2.6"},
{:hackney, "~> 4.0"},
{:sweet_xml, "~> 0.7"}
]
end
Without them the KMS-backed client module is simply not compiled; everything else works unchanged.
Usage
Basic Encryption with Raw Keyring
alias AwsEncryptionSdk.Client
alias AwsEncryptionSdk.Cmm.Default
alias AwsEncryptionSdk.Keyring.RawAes
# Create a raw AES keyring
key = :crypto.strong_rand_bytes(32)
{:ok, keyring} = RawAes.new("my-app", "data-key-1", key, :aes_256_gcm)
# Create CMM and client
cmm = Default.new(keyring)
client = Client.new(cmm)
# Encrypt data
plaintext = "Hello, World!"
{:ok, ciphertext} = Client.encrypt(client, plaintext,
encryption_context: %{"purpose" => "example"}
)
# Decrypt data
{:ok, {decrypted, context}} = Client.decrypt(client, ciphertext)
# decrypted == "Hello, World!"
AWS KMS Integration
The SDK provides four KMS keyring types for different use cases:
| Scenario | Recommended Keyring |
|---|---|
| Single key, known at encrypt/decrypt | AwsKms |
| Unknown key at decrypt time | AwsKmsDiscovery |
| Cross-region disaster recovery | AwsKmsMrk |
| Cross-region discovery | AwsKmsMrkDiscovery |
| Multiple keys for redundancy | Multi with KMS generator |
Basic KMS Encryption
alias AwsEncryptionSdk.Client
alias AwsEncryptionSdk.Cmm.Default
alias AwsEncryptionSdk.Keyring.AwsKms
alias AwsEncryptionSdk.Keyring.KmsClient.ExAws
# Create KMS client
{:ok, kms_client} = ExAws.new(region: "us-west-2")
# Create keyring with your KMS key ARN
{:ok, keyring} = AwsKms.new(
"arn:aws:kms:us-west-2:123456789012:key/12345678-1234-1234-1234-123456789012",
kms_client
)
# Create CMM and client
cmm = Default.new(keyring)
client = Client.new(cmm)
# Encrypt data
{:ok, ciphertext} = Client.encrypt(client, "Hello, World!",
encryption_context: %{"purpose" => "example"}
)
# Decrypt data
{:ok, {plaintext, _context}} = Client.decrypt(client, ciphertext)
AWS Credentials
The SDK uses ExAws for AWS integration. Configure credentials via:
- Environment variables:
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEY - Instance profile: Automatic on EC2/ECS/Lambda
- Explicit configuration:
{:ok, client} = ExAws.new(
region: "us-west-2",
config: [
access_key_id: "AKIAIOSFODNN7EXAMPLE",
secret_access_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
]
)
See examples/ for complete working examples.
Documentation
- Getting Started Guide - Quick introduction to encryption basics
- Choosing Components - Guide to selecting keyrings and CMMs
- Security Best Practices - Production security guidelines
- API Stability Policy - Versioning and compatibility guarantees
- Examples - Working code examples for all features
- API Reference - Complete API documentation
Requirements
- Elixir 1.16 or later
- Erlang/OTP 26 or later
Related Projects
Official AWS Encryption SDKs
Specification
Contributing
See CONTRIBUTING.md for guidelines.
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.