Goal: stop every application sharing one all-powerful Redis password, and fix permission errors quickly when a client starts failing.
Out of the box, every connection is the default user: on nopass ~* &* +@all. That means no password, all keys, all channels, all commands. Setting requirepass only gives that same user a password.
See what you have
ACL WHOAMI # who am I connected as
ACL USERS # user names only
ACL LIST # every user with its rules (passwords shown as hashes)
ACL GETUSER app # one user's flags, keys, channels and commands
ACL CAT # all command categories
ACL CAT dangerous # commands in one category
ACL LOG 10 # last 10 denied attempts
ACL LOG RESET # clear the log
ACL GENPASS # generate a strong random password
ACL DRYRUN app GET app:1 # test a permission without running it (7.0+)
Connect as a named user without putting the password on the command line:
redis-cli -h redis01 --user app --askpass ping
Users for common roles
New users start off, with no password, no commands and no keys. Add what they need. Rules apply left to right, so put removals such as -@dangerous last.
Application with its own key prefix
ACL SETUSER app on >STRONG_PASSWORD ~app:* +@read +@write +@connection +@transaction -@dangerous
Add +@scripting or +@pubsub &app:* only if the application uses them.
Monitoring agent with no key access
ACL SETUSER monitor on >STRONG_PASSWORD +ping +info +client|list +slowlog|get +latency|latest +memory|stats
If your exporter needs more, read ACL LOG and add only that.
Replica
Run this on the primary:
ACL SETUSER replica-user on >STRONG_PASSWORD +psync +replconf +ping
Then set this in redis.conf on each replica:
masteruser replica-user
masterauth STRONG_PASSWORD
Sentinel
Create this user on both the primary and the replicas:
ACL SETUSER sentinel-user on >STRONG_PASSWORD resetchannels &__sentinel__:hello +multi +slaveof +ping +exec +subscribe +config|rewrite +role +publish +info +client|setname +client|kill +script|kill
Then set this in sentinel.conf:
sentinel auth-user mymaster sentinel-user
sentinel auth-pass mymaster STRONG_PASSWORD
Rule reference
| Rule | Effect |
|---|---|
on / off | Allow or block new authentication as this user |
>pass / <pass | Add or remove a password. A user can have several. |
#hash / !hash | Add or remove a SHA-256 password hash |
resetpass | Remove all passwords and the nopass flag |
~pattern | Allow keys matching a glob pattern |
%R~pattern / %W~pattern | Read-only or write-only keys (7.0+) |
allkeys / resetkeys | Same as ~* / clear all key patterns |
&pattern | Allow Pub/Sub channels (6.2+) |
allchannels / resetchannels | Same as &* / clear all channel patterns and disconnect Pub/Sub clients that lose access |
+cmd / -cmd | Allow or block a command |
+cmd|sub / -cmd|sub | Allow or block a subcommand (blocking needs 7.0+) |
+@cat / -@cat | Allow or block a category |
(rules) | Add a selector, a second independent permission set (7.0+) |
reset | Return the user to its just-created state: off, no passwords, no keys, no commands |
Three behaviours that catch people out
ACL SETUSER adds to an existing user. It doesn't replace the rules. To redefine a user, start with reset and include the password again:
ACL SETUSER app reset on >STRONG_PASSWORD ~app:* +@read +@connection -@dangerous
off doesn't disconnect anyone. Connections that have already authenticated keep working. To really cut a user off:
ACL SETUSER app off
CLIENT KILL USER app
Key patterns don't limit commands with no key argument. SCAN and RANDOMKEY can still expose names outside the user's prefix, and FLUSHALL wipes everything if it is allowed. -@dangerous removes FLUSHALL, FLUSHDB and KEYS, but not SCAN. On a shared instance, also block it for tenants that don't need it:
ACL SETUSER tenant1 -scan -randomkey
Fix permission errors
Start with the log. It shows the user, the command or key that was denied, and the client address:
ACL LOG 5
reason is command, key, channel or auth, and object is the name that was refused. Error wording varies by version:
| Error or symptom | Likely cause | Fix |
|---|---|---|
NOAUTH Authentication required | Client sent no credentials; default is off or has a password | Configure the client's user name and password |
WRONGPASS invalid username-password pair or user is disabled | Wrong password, user is off, or the client sent only a password so it authenticated as default | Check ACL GETUSER; set the user name in the client |
NOPERM naming a command | Command or category not granted | ACL LOG, then add the single command |
NOPERM naming a key | Key outside the user's patterns, or read/write permission mismatch | Fix the pattern or the key prefix |
NOPERM naming a channel | Channels default to resetchannels from 7.0 | Grant &pattern, or set acl-pubsub-default allchannels temporarily |
ERR This Redis instance is not configured to use an ACL file | ACL SAVE or ACL LOAD with no aclfile set | Use CONFIG REWRITE, or configure aclfile |
Redis won't start after adding aclfile | user lines also exist in redis.conf; the two are incompatible | Move the users to the ACL file |
Replica shows master_link_status:down | masteruser or its rules are wrong | Check ACL LOG on the primary; recreate replica-user |
Test the fix with ACL DRYRUN app SET app:1 hello before the application team retries.
Make the changes survive a restart
ACL SETUSER only changes memory. Save it using whichever method the instance is set up for:
| Setup | Save | Reload edited file |
|---|---|---|
aclfile /etc/redis/users.acl | ACL SAVE | ACL LOAD |
Users in redis.conf | CONFIG REWRITE | Restart |
ACL LOAD only succeeds if every user in the file is valid. Otherwise it returns an error and the old rules stay in place.
ACLs are per node. They don't replicate, so a failover to a replica without the user causes an immediate WRONGPASS. Run the same changes on every node, including replicas and all Redis Cluster nodes, and save on each. Cluster-aware clients also need topology commands such as +cluster|slots or +cluster|shards; check your client library's documentation.
Rotate a password without downtime
A user can hold two passwords during the change:
ACL SETUSER app >NEW_PASSWORD
# deploy the new password to the application and restart it
ACL SETUSER app <OLD_PASSWORD
Lock down the default user
First create an admin user:
ACL SETUSER admin on >STRONG_PASSWORD allkeys allchannels +@all
Log in as that user in a separate session, and check who still relies on default:
redis-cli --user admin --askpass CLIENT LIST | grep 'user=default'
When the only remaining connections are ones you expect to lose, switch default off from the admin session:
ACL SETUSER default off
CLIENT KILL USER default
Caution
Do this only after replicas and Sentinels have named users. Anything sending only
masterauthor a password-onlyAUTHauthenticates asdefaultand fails, which can break replication and failover. If you lock yourself out, the fix is editing the ACL file orredis.confand restarting Redis.
Prevent it next time
- Give each application and agent its own user.
ACL LOGandCLIENT LISTthen show who did what. - Alert on rising denials.
INFO statsreports counters such asacl_access_denied_authandacl_access_denied_cmd; names vary by version, so check your build's output. - Compare
ACL LISTacross nodes on a schedule to catch drift before a failover finds it. - On managed Redis, don't assume these commands work. Redis Cloud and Redis Software, for example, don't support
ACL SETUSER.