mirror of
https://github.com/mailscope/kumomta.git
synced 2026-08-18 18:38:18 +00:00
161 lines
4.6 KiB
Markdown
161 lines
4.6 KiB
Markdown
# KeySource Object
|
|
|
|
KeySource objects are used in several places:
|
|
|
|
* Embedded into DKIM signer objects.
|
|
* The `tls_certificate` and `tls_key` fields of listeners.
|
|
* To hold credentials for [SMTP AUTH](./kumo/make_egress_path/smtp_auth_plain_password.md).
|
|
* With the [kumo.secrets.load](kumo.secrets/load.md) function.
|
|
|
|
## Acceptable Values
|
|
|
|
KeySources pattern match from one of the following shapes:
|
|
|
|
### Local File
|
|
|
|
When the value is a simple string value, it is interpreted as
|
|
the path to a file from which the key will be loaded when needed:
|
|
|
|
```lua
|
|
local file_signer = kumo.dkim.rsa_sha256_signer {
|
|
key = '/path/to/file.pem',
|
|
}
|
|
```
|
|
|
|
### Caller Provided Data
|
|
|
|
!!! note
|
|
Please also take a look at the callback/event based example further below
|
|
|
|
When the value is a table with the field `key_data`,
|
|
the value of the `key_data` field will be used as the key
|
|
data when needed:
|
|
|
|
```lua
|
|
local file_signer = kumo.dkim.rsa_sha256_signer {
|
|
key = {
|
|
-- Doing literally this is probably unwise;
|
|
-- see the example below for a more practical
|
|
-- and manageable way to use this
|
|
key_data = '-----BEGIN RSA PRIVATE KEY----....',
|
|
},
|
|
}
|
|
```
|
|
|
|
`key_data` exists to allow you to manage loading key data
|
|
via some other lua function, for example, you could load
|
|
your keys from a sqlite database:
|
|
|
|
```lua
|
|
function get_key(domain, selector)
|
|
local db = sqlite:open '/opt/kumomta/etc/dkim/keys.db'
|
|
local result = db:execute(
|
|
'select data from keys where domain=? and selector=?',
|
|
domain,
|
|
selector
|
|
)
|
|
return result[1]
|
|
end
|
|
|
|
local sqlite_signer = kumo.dkim.rsa_sha256_signer {
|
|
key = {
|
|
key_data = get_key(msg:from_header().domain, 'default'),
|
|
},
|
|
}
|
|
```
|
|
|
|
### HashiCorp Vault
|
|
|
|
You may store and manage your keys in a [HashiCorp
|
|
Vault](https://www.hashicorp.com/products/vault):
|
|
|
|
```lua
|
|
local vault_signer = kumo.dkim.rsa_sha256_signer {
|
|
key = {
|
|
vault_mount = 'secret',
|
|
vault_path = 'dkim/' .. msg:from_header().domain,
|
|
|
|
-- Specify how to reach the vault; if you omit these,
|
|
-- values will be read from $VAULT_ADDR and $VAULT_TOKEN
|
|
-- Note that these environment vars must be accessible
|
|
-- by the kumod user. If using systemd, edit the systemd
|
|
-- service file. [Look here](docs/tutorial/using_vault/) for more information
|
|
|
|
-- vault_address = "http://127.0.0.1:8200"
|
|
-- vault_token = "hvs.TOKENTOKENTOKEN"
|
|
|
|
-- Optional: specify the key name within the vault secret
|
|
-- {{since('2025.10.06-5ec871ab', inline=True)}}
|
|
-- Defaults to "key" if not specified
|
|
-- vault_key = "my_custom_key_name"
|
|
},
|
|
}
|
|
```
|
|
|
|
The key must be stored under the `path` specified. By default, it looks for a field named `key` in the vault secret.
|
|
For example, you might populate it like this:
|
|
|
|
```console
|
|
$ vault kv put -mount=secret dkim/example.org key=@example-private-dkim-key.pem
|
|
```
|
|
|
|
If you want to use a different field name, you can specify it with `vault_key` {{since('2025.10.06-5ec871ab', inline=True)}}:
|
|
|
|
```lua
|
|
local vault_signer = kumo.dkim.rsa_sha256_signer {
|
|
key = {
|
|
vault_mount = 'secret',
|
|
vault_path = 'dkim/' .. msg:from_header().domain,
|
|
vault_key = 'private_key', -- Look for 'private_key' instead of 'key'
|
|
},
|
|
}
|
|
```
|
|
|
|
And store it in vault like this:
|
|
|
|
```console
|
|
$ vault kv put -mount=secret dkim/example.org private_key=@example-private-dkim-key.pem
|
|
```
|
|
|
|
### Callback/Event based Data Source
|
|
|
|
{{since('2025.12.02-67ee9e96')}}
|
|
|
|
You may define an event handling function to perform parameterized data
|
|
fetching. This is in some ways similar to using the `key_data` form described
|
|
above, but has the advantage of allowing deferred rather than eager access to
|
|
the data.
|
|
|
|
For example, you could enhance the sqlite dkim example above to use this form;
|
|
the advantage is that the cache keys become smaller and more efficient, and the
|
|
key source object is then a bit more declarative:
|
|
|
|
```lua
|
|
-- Define the event handling callback. The name must match up to the
|
|
-- event_name field used in the keysource object below
|
|
kumo.on('fetch-my-domain-key', function(domain, selector)
|
|
local db = sqlite:open '/opt/kumomta/etc/dkim/keys.db'
|
|
local result = db:execute(
|
|
'select data from keys where domain=? and selector=?',
|
|
domain,
|
|
selector
|
|
)
|
|
-- The callback must return a string which, depending on
|
|
-- the code that is consuming the keysource, may be binary.
|
|
-- DKIM keys are PEM encoded ASCII.
|
|
return result[1]
|
|
end)
|
|
|
|
local sqlite_signer = kumo.dkim.rsa_sha256_signer {
|
|
key = {
|
|
-- name of the event handling callback you
|
|
-- have registered via kumo.on.
|
|
event_name = 'fetch-my-domain-key',
|
|
-- The list of parameters that will be passed to
|
|
-- the event handling callback
|
|
event_args = { msg:from_header().domain, 'default' },
|
|
},
|
|
}
|
|
```
|
|
|