Encryptor.Vault.Partition (Encryptor v0.2.0)

Copy Markdown View Source

Derives the fixed-width cache partition id a vault hands the caching CMM.

One cache process serves every partition within a vault (ADR-0001 decision 3), so the thing that keeps one tenant's data key out of another tenant's cache lookup is the partition id, not a second process. Decision 7 fixes the derivation:

partition_id = binary_part(sha256(vault_namespace, 0, encoded_selector), 0, 16)

and this module is the only place it is computed. The result is what the vault hands the engine's caching CMM as :partition_id; the call path that builds that CMM is the encrypt path's, and lands with it.

Why the width is fixed, and why it is 16

The engine's cache-id computation (compute_encryption_cache_id/3 in the aws_encryption_sdk caching CMM) concatenates the partition id into the cache id pre-image with no length prefix. A variable-width partition id therefore makes the pre-image ambiguous, and two different partitions could in principle hash to one cache id - which is two tenants sharing a data key. Sixteen bytes is the width of the UUID the engine generates when no partition id is given, so matching it removes the ambiguity by construction rather than by argument.

Nothing here may be relaxed into "any binary": the width is load-bearing.

What a partition id is not

It is a cache-key input only. It is not key material, it is not secret, and it never reaches a message. Deriving it by hash rather than using the raw selector keeps tenant identifiers out of a structure this package does not control the lifetime of, and buys the uniform width for free.

Records: ADR-0001 decisions 3 and 7; the selector type is ADR-0004 decision 3.

Summary

Functions

The width every partition id has, in bytes.

The 16-byte partition id for a vault and a key selector.

Functions

bytes()

@spec bytes() :: pos_integer()

The width every partition id has, in bytes.

iex> Encryptor.Vault.Partition.bytes()
16

id(vault, selector)

@spec id(module(), Encryptor.Error.selector()) :: binary()

The 16-byte partition id for a vault and a key selector.

Pure, total over the selector types ADR-0004 decision 3 admits, and allocating nothing that outlives the call.

iex> id = Encryptor.Vault.Partition.id(MyApp.Vault, "tenant-42")
iex> byte_size(id)
16

iex> Encryptor.Vault.Partition.id(MyApp.Vault, "tenant-42") ==
...>   Encryptor.Vault.Partition.id(MyApp.Vault, "tenant-43")
false

iex> Encryptor.Vault.Partition.id(MyApp.Vault, :default) ==
...>   Encryptor.Vault.Partition.id(MyApp.OtherVault, :default)
false