Upgrading to v2.0.0
Version 2.0.0 introduces a supervised machine ID API. NoNoncense.MachineId no longer
calculates a static ID with id!/1; it is now a supervisor that acquires a machine ID and
initializes one or more NoNoncense instances.
Replace manual machine ID initialization
Before v2, applications typically calculated a machine ID during startup and passed it to
NoNoncense.init/1 themselves:
defmodule MyApp.Application do
use Application
def start(_type, _args) do
machine_id = NoNoncense.MachineId.id!(node_list: [:"myapp@127.0.0.1"])
:ok = NoNoncense.init(machine_id: machine_id, base_key: System.fetch_env!("BASE_KEY"))
Supervisor.start_link([], strategy: :one_for_one, name: MyApp.Supervisor)
end
endIn v2, add NoNoncense.MachineId to your supervision tree. It blocks application startup
until it has acquired an ID, then initializes the nonce factories in :instances:
defmodule MyApp.Application do
use Application
def start(_type, _args) do
children = [
MyApp.Repo,
{NoNoncense.MachineId,
strategy: NoNoncense.MachineId.Strategy.SqlLease,
strategy_opts: [repo: MyApp.Repo],
instances: [[base_key: System.fetch_env!("BASE_KEY")]]}
]
Supervisor.start_link(children, strategy: :one_for_one, name: MyApp.Supervisor)
end
endSee the NoNoncense.MachineId module documentation for the available machine ID strategies
and their configuration options.
If you prefer to keep the old host-identifiers based behavior,
you can use NoNoncense.MachineId.Strategy.HostIdentifiers and pass your node list to its opts.
Bring down all nodes when switching strategies
When switching strategies, a rolling restart can temporarily run old nodes that are unmanaged by the new strategy. During that window, machine ID conflicts are possible. Stop all nodes before deploying the new strategy.
Upgrading to v1.0.0
Version 1.0.0 introduces breaking changes to the encrypted nonce API. This guide will help you migrate your application safely.
Overview of Changes
- Encryption keys moved from
encrypted_nonce/2toNoNoncense.init/1 - Default encryption algorithm changed from 3DES to Blowfish (64/96-bit nonces)
- New
encrypted_nonce/2signature:encrypted_nonce(name \\ __MODULE__, bit_size)
Critical: Preserving Uniqueness Guarantees
If you are using 0.x.x encrypted nonces in production, you MUST:
- pass your old encryption key(s) to
NoNoncense.init/1using the:key64,:key96and:key128opts - (when using encrypted 64 and/or 96-bit nonces) pass algorithm
:des3toNoNoncense.init/1using the:cipher64and:cipher96opts
If you don't, you will break the uniqueness guarantee of your nonces, potentially causing collisions in your database or application.
Before (v0.x)
defmodule MyApp.Application do
def start(_type, _args) do
machine_id = NoNoncense.MachineId.id!(node_list: [:"myapp@127.0.0.1"])
:ok = NoNoncense.init(machine_id: machine_id)
# ... supervisor setup
end
end
# Elsewhere in your code:
key64 = :crypto.strong_rand_bytes(24) # 3DES key
nonce = NoNoncense.encrypted_nonce(64, key64)After (v1.0) - preserving 3DES
defmodule MyApp.Application do
def start(_type, _args) do
machine_id = NoNoncense.MachineId.id!(node_list: [:"myapp@127.0.0.1"])
:ok = NoNoncense.init(
machine_id: machine_id,
key64: System.fetch_env!("NONCE_KEY_64"), # Your existing 192-bit 3DES key,
key96: System.fetch_env!("NONCE_KEY_96"), # Your existing 192-bit 3DES key,
cipher64: :des3, # MUST specify to prevent default change
cipher96: :des3 # MUST specify to prevent default change
)
# ... supervisor setup
end
end
# Elsewhere in your code:
nonce = NoNoncense.encrypted_nonce(64) # Key comes from init