Generates the Ecto migration that creates Encryptor.Ecto.KeyStore's table.
mix encryptor.ecto.gen.key_store_migration [--table NAME] [--migrations-path PATH]The table holds one row per tenant per key version: the six fields
Encryptor.Envelope.WrappedKey fixes, which is the whole of the vault's
storage contract (encryptor ADR-0003 decision 9). The vault owns the
fields; this package owns the table, the migration and the repo.
This task issues no DDL
It writes one file. Nothing here opens a database connection, and nothing in
this package issues CREATE TABLE at runtime or from a task (ADR-0002
decision 9) - Encryptor.Ecto.KeyStore reads the table and reports
{:key_unavailable, selector} where creating it would have been convenient.
The generated file is yours the moment it lands: review it in a diff, commit
it, and run it with your own mix ecto.migrate, on your own deploy schedule
and with your own rollback.
The module name is generated from this project's application name and will need renaming if your repo lives in another namespace.
Flags
| Flag | ||
|---|---|---|
--table NAME | encryptor_wrapped_keys | The table to create. A host that renames it passes the same name as table: in its Encryptor.Ecto.KeyStore provider options |
--migrations-path PATH | priv/repo/migrations | Where to write the file |
Exit codes
0 | The file was written; its path is printed |
2 | Usage error, or a migration for this table already exists in that directory - the generator never overwrites one and never writes a second |
The shape it writes
One row per {tenant_ref, version}, with two unique indexes.
{tenant_ref, version} closes the race encryptor ADR-0003 leaves to this
package: Encryptor.Envelope.provision/3 called twice concurrently for one
tenant can produce two rows claiming the same version, and a candidate list
with two entries for one version is a key nobody can vouch for.
{namespace, name} is the name contract made mechanical. RawAes.unwrap_key/3
accepts an encrypted data key only when the header's provider id and key name
equal the keyring's, so reusing a name for different material makes
previously written messages undecryptable, silently, at some later date. The
database is the only thing that can catch it at write time.
wrapped is :binary and nothing else: it is a complete Encryptor message
produced by the root vault, so its size is the engine's business and not a
length this migration should guess at.