Encryptor

CIHex.pm VersionHex DownloadsHex DocsLicense

Ergonomic envelope encryption for Elixir - a vault module, pluggable key providers, and per-tenant keys - on the aws_encryption_sdk engine.

Status: designed, not built

The five founding architecture decision records were accepted on 2026-08-27. They fix the contracts this package is made of. No implementation has landed yet: lib/ holds a moduledoc, the package is not published, and nothing below is a promise about a function you can call today.

RecordDecides
ADR-0001The vault layer: one host-owned module that wraps the engine completely, what it supervises, how it is configured, how its cache is bounded, and its error vocabulary
ADR-0002The key-provider behaviour: a provider resolves a selector to a key descriptor, and only the vault turns a descriptor into a keyring
ADR-0003The per-tenant envelope: a tenant key is 32 random bytes wrapped into an ordinary message, and the host stores the wrapping
ADR-0004The encryption-context convention: the canonical keys, who supplies each, and how a vault enforces them
ADR-0005Rotation and crypto-shred: three independent lifecycles, four operator procedures, and the one step that cannot be undone

The implementation graph derived from them is docs/plans/260827-enc-2y3-b3-implementation-graph.md. Work is tracked in this repository's own beads database, under the epic "Implement the vault core".

Read the records before writing code here. Until a contract is fixed by an accepted record, it is open - and a cryptographic choice made inline in an implementation is a defect even when the choice happens to be a good one, because the record is what makes it reviewable.

The charter

Application-level encryption in Elixir usually arrives as one of two things: a thin wrapper over :crypto that leaves key management to the caller, or a full ESDK client whose surface is shaped for the cryptography rather than for the application. Neither answers the questions a real application asks - which key does this tenant's data use, how does that key rotate without a migration, where does the key material actually come from. This package is the layer that answers them:

The engine stays aws_encryption_sdk. Raw-keyring usage pulls no AWS, HTTP, or XML libraries - that client stack is optional in the engine, and only KMS-backed providers will bring it in.

The family

PackageOwns
encryptor (here)The vault surface, the key-provider behaviour, the envelope and key-derivation scheme, the encryption-context convention, the rotation model
encryptor_ectoThe Ecto types, the schema conventions, the wrapped-key storage and its migration, the re-encryption migrator

The split is deliberate and it is a boundary, not a layering convenience: no function in this package takes a repo, a query, a table, or a batch size, and this package defines no storage schema at all.

Engine notes

The design is written against aws_encryption_sdk v1.0.0 as published, with module paths cited so every claim can be re-checked. Two upstream issues are open and the design works around both until they move:

Installation

def deps do
[
{:encryptor, "~> 0.1"}
]
end

Not yet published to Hex.

License

Apache-2.0 - see LICENSE.