# Security

> TLS, protected mode, ACL, authentication, encryption at rest, and the audit log.

URL: https://docs.hotkv.com/security/

HotKV's security features range from what every plan gets (TLS, protected
mode, ACL, password authentication) to what HotKV Cloud's Scale plan and an
On-Premise license with those features unlock (encryption at rest and the
audit log). See [Persistence and backups](https://docs.hotkv.com/persistence/index.md) for how data at
rest is saved and restored.

## TLS

HotKV supports encrypted connections over TLS via OpenSSL. Plain TCP and
TLS can run on different ports at the same time, or you can run TLS-only.

```
tls-port 6380
tls-cert-file /path/to/server.crt
tls-key-file /path/to/server.key
tls-ca-cert-file /path/to/ca.crt
```

Connect with TLS from the CLI. `hotkv-cli --tls` checks the server
certificate against the system CA store and the host name; `--cacert`
trusts your own CA instead, and `--cert`/`--key` present a client
certificate when the server requires one:

```bash
hotkv-cli --tls -h db.example.com -p 6380 -a <password>
hotkv-cli -p 6380 --tls --cert /path/to/client.crt --key /path/to/client.key --cacert /path/to/ca.crt
```

For TLS-only operation, set `port 0` and configure `tls-port`. To keep
plain connections for local tools only, set `bind 127.0.0.1` and
`tls-bind 0.0.0.0`: remote clients then have to use TLS. A renewed
certificate takes effect without a restart:
`CONFIG SET tls-cert-file /path/to/server.crt` reloads the files. Every
official SDK can connect over TLS; see [Connecting and SDKs](https://docs.hotkv.com/sdks/index.md), and
[TLS](https://docs.hotkv.com/operate/tls/index.md) for the full server setup.

On HotKV Cloud every instance accepts TLS connections only, with a
publicly trusted certificate for its own name, so clients need no CA
file; see the [Cloud quickstart](https://docs.hotkv.com/quickstart-cloud/index.md).

<div className="table-scroll">
<table>
<thead><tr><th>Directive</th><th>Default</th><th>Description</th></tr></thead>
<tbody>
<tr><td><code>tls-port</code></td><td><code>0</code> (disabled)</td><td>Port for TLS connections</td></tr>
<tr><td><code>tls-bind</code></td><td>same as <code>bind</code></td><td>Address the TLS listener binds to</td></tr>
<tr><td><code>tls-cert-file</code></td><td>&nbsp;</td><td>Server X.509 certificate (PEM)</td></tr>
<tr><td><code>tls-key-file</code></td><td>&nbsp;</td><td>Server private key (PEM)</td></tr>
<tr><td><code>tls-key-file-pass</code></td><td>&nbsp;</td><td>Passphrase for an encrypted private key</td></tr>
<tr><td><code>tls-ca-cert-file</code></td><td>&nbsp;</td><td>CA certificate for client verification</td></tr>
<tr><td><code>tls-ca-cert-dir</code></td><td>&nbsp;</td><td>Directory of hashed CA certificates</td></tr>
<tr><td><code>tls-auth-clients</code></td><td><code>yes</code></td><td>Require client certificates: <code>yes</code>/<code>no</code>/<code>optional</code></td></tr>
<tr><td><code>tls-protocols</code></td><td>unset: TLS 1.2 and 1.3</td><td>Allowed protocol versions, e.g. <code>TLSv1.2 TLSv1.3</code></td></tr>
<tr><td><code>tls-ciphers</code></td><td>OpenSSL default</td><td>TLSv1.2 cipher list</td></tr>
<tr><td><code>tls-ciphersuites</code></td><td>OpenSSL default</td><td>TLSv1.3 ciphersuites</td></tr>
<tr><td><code>tls-dh-params-file</code></td><td>&nbsp;</td><td>DH parameters file for DHE key exchange</td></tr>
<tr><td><code>tls-prefer-server-ciphers</code></td><td><code>yes</code></td><td>Prefer server cipher order</td></tr>
<tr><td><code>tls-session-caching</code></td><td><code>yes</code></td><td>Enable TLS session caching</td></tr>
<tr><td><code>tls-session-cache-size</code></td><td><code>20480</code></td><td>Max cached sessions (<code>0</code> = unlimited)</td></tr>
<tr><td><code>tls-session-cache-timeout</code></td><td><code>300</code></td><td>Session cache lifetime (seconds)</td></tr>
</tbody>
</table>
</div>

For production, use certificates from a trusted CA, restrict
`tls-protocols` to `TLSv1.2 TLSv1.3`, and set `tls-auth-clients yes` for
mutual TLS. In `hotkv.toml` these settings go under `[tls]` without the
`tls-` prefix and with underscores (`port`, `cert_file`, `key_file`,
`ca_cert_file`, ...).

### TLS between nodes

`tls-cluster yes` puts the cluster bus on TLS, and `tls-replication yes` the
replication links. They use the certificate, key and CA above and need no
`tls-port`. On these links both ends present a certificate and check the
other's against `tls-ca-cert-file` or `tls-ca-cert-dir`, so use a CA that
signs certificates for your nodes only. A node with either setting on
refuses plain connections on that port, so turn it on for every node of a
cluster (a primary and all its replicas) at the same restart.
`tls-replication` needs a restart to change; `tls-cluster` takes effect at
once for the bus connections made afterwards. If `tls-cert-file` is issued for
server use only,
give the node a certificate for the links it opens with
`tls-client-cert-file` and `tls-client-key-file` (and
`tls-client-key-file-pass` for an encrypted key).

```
tls-cert-file /etc/hotkv/tls/node.crt
tls-key-file /etc/hotkv/tls/node.key
tls-ca-cert-file /etc/hotkv/tls/ca.crt
tls-cluster yes
tls-replication yes
```

In `hotkv.toml` they are `cluster = true` and `replication = true` under
`[tls]`. Without them neither link is encrypted, so keep the bus port (and
the replication port, if you set `replication.dedicated-port`) reachable only
from the other nodes. [Cluster over TLS](https://docs.hotkv.com/clustering/tls/index.md) is a walkthrough;
see also [Clustering](https://docs.hotkv.com/clustering/index.md).

## Protected mode

`protected-mode` is on by default. While the default user has no password
(no `requirepass`, and none set with `ACL SETUSER` or in the ACL file),
HotKV serves only clients on a loopback address (`127.0.0.0/8`, `::1`),
whatever `bind` says. A client from another host gets a `DENIED` error
that says why, and is disconnected. This covers the TLS port and the
replication port too, but not the cluster bus.

To serve other hosts, set a password (recommended), or set
`protected-mode no` (`protected_mode = false` under `[network]` in
`hotkv.toml`) where the network already keeps strangers out.
`CONFIG SET protected-mode` applies to new connections.

## Authentication

Set `requirepass` (or `[security] requirepass` in TOML) to require a
password before any other command:

```
requirepass "your-password-here"
```

Clients authenticate with `AUTH [username] password`, or by passing the
password at connect time; every HotKV SDK accepts a `password` (and
`username`) option. `hotkv-cli`/`redis-cli` use `-a password` (and `--user`
for a username). On HotKV Cloud, the password is generated for you and
shown on your instance's Connection tab; see
[Quick start: HotKV Cloud](https://docs.hotkv.com/quickstart-cloud/index.md).

## ACL

Beyond a single shared password, `ACL` manages multiple users, each with
its own commands, keys and pub/sub channels, as in Redis 7. A typical
application user can do everything except the commands that administer,
empty or take down the server:

```
ACL SETUSER app on >app-password ~* &* +@all -@dangerous
```

A read-only user limited to some keys:

```
ACL SETUSER reports on >reports-password ~report:* -@all +@read
```

Rules apply in order, and the last one that covers a command decides:

- **Passwords:** `>password` and `<password` add or remove one (a user can
  have several). `#hash` and `!hash` do the same with a SHA-256 digest.
  `nopass` accepts any password, and `resetpass` clears them all.
- **State:** `on` and `off` turn the user on or off; a user that is off
  cannot log in, and its open connections run nothing. `reset` takes the
  user back to what a new user is.
- **Commands:** `+@all` and `-@all` start over. Then `+command`,
  `-command`, `+command|subcommand`, `-command|subcommand`, `+@category`
  and `-@category` apply in order. A command, subcommand or category that
  does not exist is an error, so a typo cannot leave a command allowed.
- **Keys:** `~pattern` allows reading and writing, `%R~pattern` reading
  only and `%W~pattern` writing only. `allkeys` (`~*`) allows every key
  and `resetkeys` clears the patterns.
- **Channels:** `&pattern`, `allchannels` (`&*`) and `resetchannels`. New
  users get no channels unless `acl-pubsub-default` is `allchannels`. Clients
  subscribed to a channel their user loses are disconnected.
- **Selectors:** `(rules)` adds another set of command, key and channel
  rules. A command runs when one set allows the command, all its keys and
  all its channels.

New users start `off` with no permissions. `ACL CAT` lists the categories,
and `ACL CAT <category>` the commands and subcommands in one; `CLIENT
SETNAME` is a connection command, for example, while `CLIENT KILL` is also
`@admin` and `@dangerous`. HotKV's administrative commands (`LICENSE.*`,
`TENANT.*`, `ENCRYPTION.*`, `REPLICATION.*`, `AUDIT.*`) are `@admin` and
`@dangerous` too. Commands run from scripts are checked as the calling
user, and `EXEC` checks each queued command again.

<div className="table-scroll">
<table>
<thead><tr><th>Command</th><th>Description</th></tr></thead>
<tbody>
<tr><td><code>ACL SETUSER username [rule ...]</code></td><td>Create or modify a user; every rule applies or none does</td></tr>
<tr><td><code>ACL GETUSER username</code></td><td>A user's flags, passwords, commands, keys, channels and selectors</td></tr>
<tr><td><code>ACL DELUSER username [...]</code></td><td>Delete users and disconnect their clients</td></tr>
<tr><td><code>ACL LIST</code></td><td>All users as ACL file lines</td></tr>
<tr><td><code>ACL USERS</code></td><td>All user names</td></tr>
<tr><td><code>ACL WHOAMI</code></td><td>The current connection's user</td></tr>
<tr><td><code>ACL CAT [category]</code></td><td>The categories, or the commands in one</td></tr>
<tr><td><code>ACL DRYRUN username command [arg ...]</code></td><td>Whether the user may run the command with these keys and channels</td></tr>
<tr><td><code>ACL LOG [count | RESET]</code></td><td>Denied commands, keys and channels, and failed logins</td></tr>
<tr><td><code>ACL GENPASS [bits]</code></td><td>A random password from the system's cryptographic generator</td></tr>
<tr><td><code>ACL SAVE</code> / <code>ACL LOAD</code></td><td>Write the users to, or read them from, <code>aclfile</code></td></tr>
</tbody>
</table>
</div>

`SLOWLOG` and `MONITOR` never show passwords: they show `(redacted)`
instead.

## Roles and single sign-on

With the `enterprise-iam` license feature, people can log in through an LDAP
directory (`AUTH alice password`) or an OpenID Connect identity provider
(`IAM.AUTH oidc - <token>`) instead of having an ACL user, and what they can
do comes from roles you define with `IAM.ROLE.CREATE` and give with
`IAM.USER.ASSIGN`. Roles are enforced as ACL rules are, and take effect on
open connections at once. See [Roles and single sign-on](https://docs.hotkv.com/operate/iam/index.md).

## Encryption at rest

With the `encryption-at-rest` license feature, HotKV encrypts its snapshots
with AES-256-GCM as they are written and decrypts them as they are read, so
the plaintext never reaches the disk; the temporary copy a full sync sends
to a replica is encrypted too. The AOF is not encrypted: with encryption at
rest, prefer snapshots, or keep the data directory on an encrypted volume.

```toml
[encryption]
enabled = true
provider = "local"
key_path = "/etc/hotkv/master.key"   # a file holding a 32-byte key
```

In `hotkv.conf` the same settings are `encryption.enabled yes`,
`encryption.provider local` and `encryption.key-file /etc/hotkv/master.key`.
Keep the key file readable by the HotKV user only, and keep a copy
somewhere safe: a snapshot cannot be read without the key it was written
with.

`ENCRYPTION.INFO` reports status, `ENCRYPTION.ROTATE <new_key_file>`
switches to the key at the given path for every snapshot written from then
on (run `BGSAVE` next, and point `key_path` at the new key before the next
restart), and `ENCRYPTION.VERIFY <file>` checks a file's integrity.
Encryption only runs while a snapshot is written or loaded, so commands
are not slowed down. If the key cannot be loaded at startup, HotKV does
not start rather than write snapshots in plaintext.

## Audit log

With the `audit-log` license feature, HotKV writes a tamper-evident audit
trail: every entry carries a SHA-256 hash that covers the entry before it,
so deleting, inserting, or editing an entry after the fact breaks the
chain, which `AUDIT.VERIFY` detects.

```toml
[audit]
enabled = true
file = "/var/log/hotkv/audit.log"
format = "jsonl"                    # export format: "jsonl", "csv", "cef"
exclude_commands = ["PING", "INFO"]
exclude_patterns = ["__internal:*"] # skip commands on matching keys
max_size = 104857600                # rotate past this many bytes
```

The file defaults to `audit.hkv.log`. In `hotkv.conf` the settings are
`audit.enabled`, `audit.file`, `audit.export-format`,
`audit.exclude-commands`, `audit.exclude-patterns` and `audit.max-size`.

Each entry records the sequence number, a nanosecond timestamp, the
authenticated username, source IP, command and keys accessed, alongside
the hash chain fields. `AUDIT.INFO` reports the entry count, file size,
whether the chain is valid and the last sequence number, `AUDIT.VERIFY`
walks and verifies the whole chain, `AUDIT.EXPORT <file> [FORMAT
jsonl|csv|cef]` exports it, and `AUDIT.ROTATE` rotates the log file. Each
node of a cluster keeps its own audit log.

## Next steps

- [Persistence and backups](https://docs.hotkv.com/persistence/index.md)
- [Command reference](https://docs.hotkv.com/commands/index.md) for the full audit and
  encryption command lists
- [Clustering](https://docs.hotkv.com/clustering/index.md)