ACL
Access control lists (ACL) let several users share one HotKV server, each with its own passwords and its own set of allowed commands, keys and pub/sub channels. Use them to give an application only the commands it needs, to hand out read-only access, or to keep administrative commands away from client code. The rule syntax is the one Redis 7 uses, so existing rules and tools carry over.
For a short overview alongside TLS and protected mode, see Security.
The default user
Section titled “The default user”Every server has a user named default. Out of the box it is on, needs no
password and may run every command on every key and channel:
127.0.0.1:6379> ACL LIST1) "user default on nopass sanitize-payload ~* &* +@all"A connection that has not authenticated runs as default. Setting
requirepass gives default that password, so every client must
authenticate first; ACL SETUSER default ... or a user default line in
the ACL file does the same with full ACL rules. While default has no
password, protected mode serves only clients
on a loopback address.
requirepass "a-long-random-password"CONFIG SET requirepass changes the password at runtime (replacing any
other passwords of default). CONFIG GET requirepass answers (hidden)
once a password is set, not the password itself. The default user cannot
be deleted; turn it off instead to make every client log in as a named
user.
Authenticate
Section titled “Authenticate”Clients authenticate with AUTH:
127.0.0.1:6379> AUTH a-long-random-passwordOK127.0.0.1:6379> AUTH reports reports-passwordOK127.0.0.1:6379> AUTH reports wrong(error) WRONGPASS invalid username-password pair or user is disabled.AUTH password logs in as default; AUTH username password as any user.
Until a client authenticates on a server that requires it, commands fail
with NOAUTH Authentication required.. AUTH password on a server whose
default user has no password fails with an error that says so.
HELLO can authenticate and pick the protocol in one step:
HELLO 3 AUTH reports reports-password SETNAME report-jobEvery HotKV SDK takes a username and password (or a URL with both), and
hotkv-cli takes --user and -a; see hotkv-cli.
Create a user
Section titled “Create a user”ACL SETUSER creates a user or changes one. A new user starts off,
with no password and no permissions, so give it everything it needs in one
command:
127.0.0.1:6379> ACL SETUSER reports on >reports-password ~report:* -@all +@readOK127.0.0.1:6379> ACL LIST1) "user default on nopass sanitize-payload ~* &* +@all"2) "user reports on sanitize-payload #c0a6280be3d2bc0b927b0327bd24bcdde0512a384940aa55ee6caf5c365d7095 ~report:* resetchannels -@all +@read"Passwords are stored and listed as SHA-256 digests (#...), never as
text. Rules apply left to right, and either all of them apply or none
does: one invalid rule leaves the user as it was and names the rule.
127.0.0.1:6379> ACL SETUSER reports +nosuchcommand(error) ERR Error in ACL SETUSER modifier '+nosuchcommand': Unknown command or category name in ACLChanges take effect at once, for connections already logged in as that
user too. Deleting a user with ACL DELUSER disconnects its clients.
Some common users:
# An application: everything except administrative and destructive commandsACL SETUSER app on >app-password ~* &* +@all -@dangerous
# A cache client limited to its own keysACL SETUSER cache on >cache-password ~cache:* -@all +get +set +del +expire
# A worker that only consumes from its channelsACL SETUSER events on >events-password resetchannels &events:* -@all +subscribe +psubscribe
# A monitoring agentACL SETUSER monitor on >monitor-password -@all +info +ping +client|list +slowlog|getGenerate strong passwords with ACL GENPASS, which returns 256 random bits
as 64 hex characters by default (ACL GENPASS 128 for fewer).
User state and passwords
Section titled “User state and passwords”| Rule | Effect |
|---|---|
on / off |
Allow or block logins; an off user’s open connections run no commands |
>password |
Add a password (a user can have several) |
<password |
Remove a password |
#digest / !digest |
Add or remove a password given as its SHA-256 digest (64 lowercase hex characters) |
nopass |
Accept any password, and remove the stored ones |
resetpass |
Remove every password, and nopass |
reset |
Back to a new user: off, no passwords, no permissions, no selectors |
sanitize-payload / skip-sanitize-payload |
Accepted and shown for compatibility; HotKV always checks RESTORE payloads |
Commands
Section titled “Commands”Command rules start from -@all (nothing) unless you give +@all
(allcommands), and later rules refine earlier ones:
| Rule | Effect |
|---|---|
+@all / allcommands |
Allow every command, and start the command rules over |
-@all / nocommands |
Allow no command, and start the command rules over |
+command / -command |
Allow or deny one command, all its subcommands included |
+command|subcommand / -command|subcommand |
Allow or deny one subcommand, such as +config|get |
+command|arg |
Allow a command that has no subcommands only with this first argument, such as +select|0 (allow only; to deny, deny the command) |
+@category / -@category |
Allow or deny every command in a category |
A command, subcommand or category that does not exist is an error, so a typo cannot leave a command allowed by accident.
Categories
Section titled “Categories”ACL CAT lists the categories and ACL CAT <category> the commands and
subcommands in one:
keyspace, read, write, set, sortedset, list, hash, string,
bitmap, hyperloglog, geo, stream, pubsub, admin, fast,
slow, blocking, dangerous, connection, transaction, scripting,
bloom, cms, topk, timeseries.
They match Redis’s core categories, plus bloom, cms, topk and
timeseries for HotKV’s own data types. HotKV has no module categories
such as @json or @search. HotKV’s administrative commands
(LICENSE.*, TENANT.*, ENCRYPTION.*, REPLICATION.*, AUDIT.*) are
in @admin and @dangerous, so -@dangerous keeps them away from
application users.
| Rule | Effect |
|---|---|
~pattern |
Allow reading and writing keys that match the glob pattern |
%R~pattern |
Allow reading only |
%W~pattern |
Allow writing only |
%RW~pattern |
Same as ~pattern |
allkeys / ~* |
Allow every key |
resetkeys |
Remove all key patterns |
A command runs only if the user may use every key it names, for reading,
writing or both as the command does. Adding a pattern after ~* is an
error: use resetkeys first.
Channels
Section titled “Channels”| Rule | Effect |
|---|---|
&pattern |
Allow publishing and subscribing to channels that match the glob pattern |
allchannels / &* |
Allow every channel |
resetchannels |
Remove all channel patterns |
PSUBSCRIBE is allowed only for a pattern that is one of the user’s
channel patterns as written. New users get no channels, unless
acl-pubsub-default is allchannels. When a user loses a channel, its
clients subscribed to that channel are disconnected.
Selectors
Section titled “Selectors”A selector is a second (third, …) set of command, key and channel rules in parentheses. A command runs when the user’s main rules or one of its selectors allow the command together with all its keys and channels:
ACL SETUSER svc on >svc-password ~svc:* -@all +@read (~shared:* +get +set)This user can read svc:* keys, and also GET and SET shared:* keys.
clearselectors removes a user’s selectors. ACL GETUSER shows each
selector’s rules separately.
Inspect and test
Section titled “Inspect and test”| Command | Use |
|---|---|
ACL WHOAMI |
The user of the current connection |
ACL USERS |
All user names |
ACL LIST |
All users as ACL file lines |
ACL GETUSER user |
One user’s flags, password digests, commands, keys, channels and selectors (nil if there is no such user) |
ACL CAT [category] |
The categories, or the commands in one |
ACL DRYRUN user command [arg ...] |
Whether the user could run the command with these arguments |
ACL SETUSER / ACL DELUSER |
Change or delete users |
ACL GENPASS [bits] |
A random password |
ACL LOG [count | RESET] |
Recent denials |
ACL SAVE / ACL LOAD |
Write or read the ACL file |
ACL DRYRUN checks the rules without running anything, even for a user
that is off:
127.0.0.1:6379> ACL DRYRUN reports GET report:2026-09OK127.0.0.1:6379> ACL DRYRUN reports SET report:2026-09 x"User reports has no permissions to run the 'set' command"127.0.0.1:6379> ACL DRYRUN reports GET invoices:1"User reports has no permissions to access the 'invoices:1' key"A denied command fails with a NOPERM error:
127.0.0.1:6379> SET report:2026-09 x(error) NOPERM User reports has no permissions to run the 'set' command127.0.0.1:6379> GET invoices:1(error) NOPERM No permissions to access a keyCommands run from scripts are checked as the calling user, and EXEC checks each queued command again.
The ACL log
Section titled “The ACL log”ACL LOG lists the most recent denied commands, keys and channels and
failed logins, newest first (10 by default, ACL LOG 50 for more). Each
entry has count, reason (command, key, channel or auth),
context (toplevel, multi or lua), object (the command, key or
channel), username, age-seconds, client-info, entry-id,
timestamp-created and timestamp-last-updated. Repeats of the same
denial are counted in one entry. ACL LOG RESET clears it.
The log keeps acllog-max-len entries (default 128). INFO stats
counts denials since startup as acl_access_denied_auth,
acl_access_denied_cmd, acl_access_denied_key and
acl_access_denied_channel.
The ACL file
Section titled “The ACL file”Users made with ACL SETUSER live in memory. To keep them across
restarts, set aclfile:
aclfile /var/lib/hotkv/users.aclIn hotkv.toml it is aclfile under [security]. The file holds one user
per line, in the form ACL LIST shows; blank lines and lines starting with
# are skipped:
user default offuser admin on #<sha256-digest> ~* &* +@alluser app on #<sha256-digest> ~* &* +@all -@dangeroususer reports on #<sha256-digest> ~report:* resetchannels -@all +@read- At startup HotKV loads the file after
requirepass, so auser defaultline wins overrequirepass; without one,defaultkeeps therequirepasspassword. A missing file is not an error: the server starts with the default user. A file with an invalid line stops the start, naming the line. ACL SAVEwrites every user to the file. It writes a new file and renames it into place, so the file is never half written. A new file is readable by its owner only, since it holds password digests.ACL LOADreplaces every user with the file’s. If any line is invalid, nothing changes and the error names the line. Clients whose user no longer exists, or lost a channel they are subscribed to, are disconnected.
Both fail with an error when no aclfile is configured.
Unlike Redis, HotKV does not take user lines in hotkv.conf: a user
directive stops the start. Keep users in the ACL file.
Settings
Section titled “Settings”| Setting | Default | Description |
|---|---|---|
requirepass |
empty | Password of the default user |
aclfile |
empty | File ACL SAVE and ACL LOAD use, and that is loaded at startup |
acl-pubsub-default |
resetchannels |
Channels a new user (or one reset) starts with: resetchannels none, allchannels every channel |
acllog-max-len |
128 |
Entries ACL LOG keeps |
In hotkv.toml they go under [security] with underscores
(acl_pubsub_default, acllog_max_len). requirepass,
acl-pubsub-default and acllog-max-len can be changed with CONFIG SET.
Differences from Redis
Section titled “Differences from Redis”- Users cannot be declared in the configuration file; use
aclfile. CONFIG GET requirepassdoes not reveal the password.skip-sanitize-payloadis accepted butRESTOREpayloads are always checked.- Categories are those listed above: HotKV adds
bloom,cms,topkandtimeseriesand has no module categories. - A TLS client certificate does not log a client in as a user; clients
authenticate with
AUTHorHELLO. - Replicas authenticate their replication link with a shared password,
not an ACL user (
masteruseris accepted and ignored).
Next steps
Section titled “Next steps”- Security: TLS, protected mode, and the audit log.
- ACL users in a cluster: users belong to one node, so create them on every node.
- TLS: encrypt connections, including mutual TLS.
Was this page helpful?
Thanks for the feedback.