Home / Databases / Redis

DatabasesCheat sheetBeginner

Redis ACL cheat sheet: users, key patterns, command categories and NOPERM errors

Create least-privilege Redis users, read ACL LOG to fix NOPERM and WRONGPASS errors, rotate passwords without downtime, lock the default user and keep ACLs across restarts.

Deepak Bhardwaj7 min read

Applies toRedis 6.0 and later. Channel rules need 6.2; selectors, %R~/%W~ key permissions and ACL DRYRUN need 7.0. Managed services restrict these commands, so check your provider.

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 masterauth or a password-only AUTH authenticates as default and fails, which can break replication and failover. If you lock yourself out, the fix is editing the ACL file or redis.conf and restarting Redis.

Prevent it next time

  • Give each application and agent its own user. ACL LOG and CLIENT LIST then show who did what.
  • Alert on rising denials. INFO stats reports counters such as acl_access_denied_auth and acl_access_denied_cmd; names vary by version, so check your build's output.
  • Compare ACL LIST across 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.