Sealing at rest: what the native backend stores that must not be read
back from the table (a TOTP secret) is sealed with AES-256-GCM, OTP's
:crypto, under a key from the configuration (sealing_key:,
Macaw.Auth.Native.Config).
- The key.
sealing_keyis a binary of at least 32 bytes, or{module, function, args}returning one, called at each use (so a host can keep it in its data directory, or derive it from itssecret_key_base, without this library depending on how). It is never logged and never in telemetry; the configuration'sinspectleaves it out. A missing or short key isMacaw.Auth.Native.SealingKeyErrorat first use, naming the fault and never the value. - Derived, not used as is. The AES key is HMAC-SHA256 of a fixed
label under the configured key, so a host may pass a longer secret it
also uses elsewhere (its
secret_key_base) and the two uses never share a key. - Bound to its row. Each sealed value carries associated data (the purpose and the user's id), so a sealed secret copied onto another user's row does not unseal there.
- The format.
<<1, iv::12 bytes, tag::16 bytes, ciphertext>>, the first byte a version, so a later scheme can be told apart. A fresh random IV for every seal.
unseal/3 returns {:error, :wrong_key} for anything that fails to
authenticate: a different key, a tampered value, another row's value.
Summary
Functions
The AES key from the configured sealing_key; raises
Macaw.Auth.Native.SealingKeyError when it is missing, short, or its
function returns something that isn't a key.
The smallest key accepted, in bytes.
Seals plaintext under key (from key!/1), bound to aad.
Unseals: {:ok, plaintext}, or {:error, :wrong_key} when it doesn't authenticate.
Types
Functions
@spec key!(key_source()) :: binary()
The AES key from the configured sealing_key; raises
Macaw.Auth.Native.SealingKeyError when it is missing, short, or its
function returns something that isn't a key.
@spec min_bytes() :: pos_integer()
The smallest key accepted, in bytes.
Seals plaintext under key (from key!/1), bound to aad.
Unseals: {:ok, plaintext}, or {:error, :wrong_key} when it doesn't authenticate.