VALKEY-ACL(7)

๐Ÿ“ฆ
version 9.0.6 ยท 2 versions
, in fedora 44

โœจ NAME โœจ

okay so this is the VALKEY-ACL(7) manual page, bestie โ€” and it's all about valkey-acl, which literally just means ACL (Access Control List). That's the name. That's the vibe. periodt. ๐Ÿ’…


๐Ÿ’– DESCRIPTION ๐Ÿ’–

okay so the Valkey ACL โ€” short for Access Control List โ€” is a feature that lets you limit certain connections in terms of the commands they can execute and the keys they can access. The way it works is that, after connecting, a client has to provide a username and a valid password to authenticate. If authentication succeeds, the connection is associated with a given user and all the limits that user has. Valkey can be configured so that new connections are already authenticated with a โ€œdefaultโ€ user (and yes, that's the default configuration). Configuring the default user has, as a side effect, the ability to provide only a specific subset of functionalities to connections that are not explicitly authenticated. no cap.

The standard way to authenticate is the two-argument form of the AUTH command:

AUTH <username> <password>

If the password is valid matches, the connection will be authenticated to the user with the name <username>. (yes, โ€œvalid matchesโ€ โ€” that's exactly what the manual says, bestie.)

When the single argument form of the command is used, where only the password is specified, it is assumed that the implicit username is โ€œdefaultโ€:

AUTH <password>

This form authenticates against the โ€œdefaultโ€ userโ€™s password, either set by ACLs or by setting requirepass. ๐Ÿ’–


๐ŸŒŸ When ACLs are useful ๐ŸŒŸ

Before using ACLs, you may want to ask yourself whatโ€™s the goal you want to accomplish by implementing this layer of protection. Normally there are two main goals that are well served by ACLs:

  1. You want to improve security by restricting the access to commands and keys, so that untrusted clients have no access and trusted clients have just the minimum access level to the database in order to perform the work needed. For instance, certain clients may just be able to execute read only commands.
  2. You want to improve operational safety, so that processes or humans accessing Valkey are not allowed to damage the data or the configuration due to software errors or manual mistakes. For instance, there is no reason for a worker that fetches delayed jobs from Valkey to be able to call the FLUSHALL command.

Another typical usage of ACLs is related to managed Valkey instances. Valkey is often provided as a managed service both by internal company teams that handle the Valkey infrastructure for the other internal customers they have, or is provided in a software-as-a-service setup by cloud providers. In both setups, we want to be sure that configuration commands are excluded for the customers. ๐Ÿซถ


๐Ÿ› ๏ธ Configure ACLs with the ACL command ๐Ÿ› ๏ธ

ACLs are defined using a DSL (domain specific language) that describes what a given user is allowed to do. Such rules are always implemented from the first to the last, left-to-right, because sometimes the order of the rules is important to understand what the user is really able to do. iykyk.

By default there is a single user defined, called default. We can use the ACL LIST command in order to check the currently active ACLs and verify what the configuration of a freshly started, defaults-configured Valkey instance is:

> ACL LIST
1) "user default on nopass ~* &* +@all"

The command above reports the list of users in the same format that is used in the Valkey configuration files, by translating the current ACLs set for the users back into their description.

The first two words in each line are โ€œuserโ€ followed by the username. The next words are ACL rules that describe different things. Weโ€™ll show how the rules work in detail, but for now it is enough to say that the default user is configured to be active (on), to require no password (nopass), to access every possible key (~*) and Pub/Sub channel (&*), and be able to call every possible command (+@all). โœจ

Also, in the special case of the default user, having the nopass rule means that new connections are automatically authenticated with the default user without any explicit AUTH call needed. iconic.


๐ŸŽ€ ACL rules ๐ŸŽ€

The following is the list of valid ACL rules. Certain rules are just single words that are used in order to activate or remove a flag, or to perform a given change to the user ACL. Other rules are char prefixes that are concatenated with command or category names, key patterns, and so forth. ๐Ÿ’…

๐Ÿ‘‘ Enable and disallow users ๐Ÿ‘‘

  • on โ€” Enable the user: it is possible to authenticate as this user.
  • off โ€” Disallow the user: itโ€™s no longer possible to authenticate with this user; however, previously authenticated connections will still work. Note that if the default user is flagged as off, new connections will start as not authenticated and will require the user to send AUTH or HELLO with the AUTH option in order to authenticate in some way, regardless of the default user configuration.

๐Ÿ”ฅ Allow and disallow commands ๐Ÿ”ฅ

  • +<command> โ€” Add the command to the list of commands the user can call. Can be used with | for allowing subcommands (e.g โ€œ+config|getโ€).
  • -<command> โ€” Remove the command to the list of commands the user can call. Starting Valkey 7.0, it can be used with | for blocking subcommands (e.g โ€œ-config|setโ€).
  • +@<category> โ€” Add all the commands in such category to be called by the user, with valid categories being like @admin, @set, @sortedset, ... and so forth, see the full list by calling the ACL CAT command. The special category @all means all the commands, both the ones currently present in the server, and the ones that will be loaded in the future via modules.
  • -@<category> โ€” Like +@<category> but removes the commands from the list of commands the client can call.
  • +<command>|first-arg โ€” Allow a specific first argument of an otherwise disabled command. It is only supported on commands with no sub-commands, and is not allowed as negative form like -SELECT|1, only additive starting with โ€œ+โ€. This feature is deprecated and may be removed in the future.
  • allcommands โ€” Alias for +@all. Note that it implies the ability to execute all the future commands loaded via the modules system.
  • nocommands โ€” Alias for @all.

๐Ÿ—๏ธ Allow and disallow certain keys and key permissions ๐Ÿ—๏ธ

  • ~<pattern> โ€” Add a pattern of keys that can be mentioned as part of commands. For instance ~* allows all the keys. The pattern is a glob-style pattern like the one of KEYS. It is possible to specify multiple patterns.
  • %R~<pattern> โ€” Add the specified read key pattern. This behaves similar to the regular key pattern but only grants permission to read from keys that match the given pattern. See key permissions for more information.
  • %W~<pattern> โ€” Add the specified write key pattern. This behaves similar to the regular key pattern but only grants permission to write to keys that match the given pattern. See key permissions for more information.
  • %RW~<pattern> โ€” Alias for ~<pattern>.
  • allkeys โ€” Alias for ~*.
  • resetkeys โ€” Flush the list of allowed keys patterns. For instance the ACL ~foo:* ~bar:* resetkeys ~objects:*, will only allow the client to access keys that match the pattern objects:*.

๐Ÿ“ก Allow and disallow Pub/Sub channels ๐Ÿ“ก

  • &<pattern> โ€” Add a glob style pattern of Pub/Sub channels that can be accessed by the user. It is possible to specify multiple channel patterns. Note that pattern matching is done only for channels mentioned by PUBLISH and SUBSCRIBE, whereas PSUBSCRIBE requires a literal match between its channel patterns and those allowed for user.
  • allchannels โ€” Alias for &* that allows the user to access all Pub/Sub channels.
  • resetchannels โ€” Flush the list of allowed channel patterns and disconnect the userโ€™s Pub/Sub clients if these are no longer able to access their respective channels and/or channel patterns.

๐Ÿ” Configure valid passwords for the user ๐Ÿ”

  • ><password> โ€” Add this password to the list of valid passwords for the user. For example >mypass will add โ€œmypassโ€ to the list of valid passwords. This directive clears the nopass flag (see later). Every user can have any number of passwords.
  • <<password> โ€” Remove this password from the list of valid passwords. Emits an error in case the password you are trying to remove is actually not set.
  • #<hash> โ€” Add this SHA-256 hash value to the list of valid passwords for the user. This hash value will be compared to the hash of a password entered for an ACL user. This allows users to store hashes in the acl.conf file rather than storing cleartext passwords. Only SHA-256 hash values are accepted as the password hash must be 64 characters and only contain lowercase hexadecimal characters.
  • !<hash> โ€” Remove this hash value from the list of valid passwords. This is useful when you do not know the password specified by the hash value but would like to remove the password from the user.
  • nopass โ€” All the set passwords of the user are removed, and the user is flagged as requiring no password: it means that every password will work against this user. If this directive is used for the default user, every new connection will be immediately authenticated with the default user without any explicit AUTH command required. Note that the resetpass directive will clear this condition.
  • resetpass โ€” Flushes the list of allowed passwords and removes the nopass status. After resetpass, the user has no associated passwords and there is no way to authenticate without adding some password (or setting it as nopass later).
Note: if a user is not flagged with nopass and has no list of valid passwords, that user is effectively impossible to use because there will be no way to log in as that user. ๐Ÿ˜ญ

๐ŸŽฏ Configure selectors for the user ๐ŸŽฏ

  • (<rule list>) โ€” Create a new selector to match rules against. Selectors are evaluated after the user permissions, and are evaluated according to the order they are defined. If a command matches either the user permissions or any selector, it is allowed. See selectors for more information.
  • clearselectors โ€” Delete all of the selectors attached to the user.

๐Ÿงน Reset the user ๐Ÿงน

  • reset โ€” Performs the following actions: resetpass, resetkeys, resetchannels, allchannels (if acl-pubsub-default is set), off, clearselectors, @all. The user returns to the same state it had immediately after its creation.

๐ŸŒˆ Create and edit user ACLs with the ACL SETUSER command ๐ŸŒˆ

Users can be created and modified in two main ways:

  1. Using the ACL command and its ACL SETUSER subcommand.
  2. Modifying the server configuration, where users can be defined, and restarting the server. With an external ACL file, just call ACL LOAD.

okay so first things first โ€” this is where we learn how to define users using the ACL command. once you've got this in your head, doing the exact same things via the configuration files is gonna be trivial, fr. (Defining users in the configuration deserves its own whole section though, and we'll get to that separately later. ๐Ÿ’…)

To start, try the simplest ACL SETUSER command call:

> ACL SETUSER alice
OK

The ACL SETUSER command takes the username and a list of ACL rules to apply to the user. But bestie... the example above didn't specify any rule at all. ๐Ÿ‘€ That just creates the user if it did not exist, using the defaults for new users. If the user already exists, the command above will do nothing at all. not a single thing. ๐Ÿ’€

Check the default user status:

> ACL LIST
1) "user alice off resetchannels -@all"
2) "user default on nopass ~* &* +@all"

The new user "alice" is:

  • In the off status, so AUTH will not work for the user "alice".
  • The user also has no passwords set.
  • Cannot access any command. Note that the user is created by default without the ability to access any command, so the -@all in the output above could be omitted; however, ACL LIST attempts to be explicit rather than implicit.
  • There are no key patterns that the user can access.
  • There are no Pub/Sub channels that the user can access.

Such user is completely useless. ๐Ÿ˜ญ Let's try to define the user so that it is active, has a password, and can access with only the GET command to key names starting with the string "cached:":

> ACL SETUSER alice on >p1pp0 ~cached:* +get
OK

Now the user can do something, but will refuse to do other things:

> AUTH alice p1pp0
OK
> GET foo
(error) NOPERM this user has no permissions to access one of the keys used as arguments
> GET cached:1234
(nil)
> SET cached:1234 zap
(error) NOPERM this user has no permissions to run the 'set' command

Things are working as expected. โœจ In order to inspect the configuration of the user alice (remember that user names are case sensitive), it is possible to use an alternative to ACL LIST which is designed to be more suitable for computers to read, while ACL GETUSER is more human readable.

> ACL GETUSER alice
1) "flags"
2) 1) "on"
3) "passwords"
4) 1) "2d9c75..."
5) "commands"
6) "-@all +get"
7) "keys"
8) "~cached:*"
9) "channels"
10) ""
11) "selectors"
12) (empty array)

The ACL GETUSER returns a field-value array that describes the user in more parsable terms. The output includes the set of flags, a list of key patterns, passwords, and so forth. The output is probably more readable if we use RESP3, so that it is returned as a map reply:

> ACL GETUSER alice
1# "flags" => 1~ "on"
2# "passwords" => 1) "2d9c75273d72b32df726fb545c8a4edc719f0a95a6fd993950b10c474ad9c927"
3# "commands" => "-@all +get"
4# "keys" => "~cached:*"
5# "channels" => ""
6# "selectors" => (empty array)
Note: from now on, we'll continue using the Valkey default protocol, version 2

Using another ACL SETUSER command (from a different user, because alice cannot run the ACL command), we can add multiple patterns to the user:

> ACL SETUSER alice ~objects:* ~items:* ~public:*
OK
> ACL LIST
1) "user alice on #2d9c75... ~cached:* ~objects:* ~items:* ~public:* resetchannels -@all +get"
2) "user default on nopass ~* &* +@all"

The user representation in memory is now as we expect it to be. ๐Ÿซถ


๐ŸŒธ Multiple calls to ACL SETUSER ๐ŸŒธ

It is very important to understand what happens when ACL SETUSER is called multiple times. What is critical to know is that every ACL SETUSER call will NOT reset the user, but will just apply the ACL rules to the existing user. The user is reset only if it was not known before. In that case, a brand new user is created with zeroed-ACLs. The user cannot do anything, is disallowed, has no passwords, and so forth. This is the best default for safety. ๐Ÿ›ก๏ธ

However later calls will just modify the user incrementally. For instance, the following sequence:

> ACL SETUSER myuser +set
OK
> ACL SETUSER myuser +get
OK

Will result in myuser being able to call both GET and SET:

> ACL LIST
1) "user default on nopass ~* &* +@all"
2) "user myuser off resetchannels -@all +get +set"

๐ŸŒˆ Command categories ๐ŸŒˆ

Setting user ACLs by specifying all the commands one after the other is really annoying, so instead we do things like this:

> ACL SETUSER antirez on +@all -@dangerous >42a979... ~*

By saying +@all and @dangerous, we included all the commands and later removed all the commands that are tagged as dangerous inside the Valkey command table. Note that command categories never include modules commands with the exception of +@all. If you say +@all, all the commands can be executed by the user, even future commands loaded via the modules system. However if you use the ACL rule +@read or any other, the modules commands are always excluded. This is very important because you should just trust the Valkey internal command table. Modules may expose dangerous things and in the case of an ACL that is just additive, that is, in the form of +@all -... You should be absolutely sure that you'll never include what you did not mean to. โš ๏ธ

The following is a list of command categories and their meanings:

  • admin - Administrative commands. Normal applications will never need to use these. Includes REPLICAOF, CONFIG, DEBUG, SAVE, MONITOR, ACL, SHUTDOWN, etc.
  • bitmap - Data type: bitmaps related.
  • blocking - Potentially blocking the connection until released by another command.
  • connection - Commands affecting the connection or other connections. This includes AUTH, SELECT, COMMAND, CLIENT, ECHO, PING, etc.
  • dangerous - Potentially dangerous commands (each should be considered with care for various reasons). This includes FLUSHALL, MIGRATE, RESTORE, SORT, KEYS, CLIENT, DEBUG, INFO, CONFIG, SAVE, REPLICAOF, etc.
  • geo - Data type: geospatial indexes related.
  • hash - Data type: hashes related.
  • hyperloglog - Data type: hyperloglog related.
  • fast - Fast O(1) commands. May loop on the number of arguments, but not the number of elements in the key.
  • keyspace - Writing or reading from keys, databases, or their metadata in a type agnostic way. Includes DEL, RESTORE, DUMP, RENAME, EXISTS, DBSIZE, KEYS, EXPIRE, TTL, FLUSHALL, etc. Commands that may modify the keyspace, key, or metadata will also have the write category. Commands that only read the keyspace, key, or metadata will have the read category.
  • list - Data type: lists related.
  • pubsub - PubSub-related commands.
  • read - Reading from keys (values or metadata). Note that commands that don't interact with keys, will not have either read or write.
  • scripting - Scripting related.
  • set - Data type: sets related.
  • sortedset - Data type: sorted sets related.
  • slow - All commands that are not fast.
  • stream - Data type: streams related.
  • string - Data type: strings related.
  • transaction - WATCH / MULTI / EXEC related commands.
  • write - Writing to keys (values or metadata).

Valkey can also show you a list of all categories and the exact commands each category includes using the Valkey ACL CAT command. It can be used in two forms:

ACL CAT -- Will just list all the categories available
ACL CAT <category-name> -- Will list all the commands inside the category

Examples:

> ACL CAT
 1) "keyspace"
 2) "read"
 3) "write"
 4) "set"
 5) "sortedset"
 6) "list"
 7) "hash"
 8) "string"
 9) "bitmap"
10) "hyperloglog"
11) "geo"
12) "stream"
13) "pubsub"
14) "admin"
15) "fast"
16) "slow"
17) "blocking"
18) "dangerous"
19) "connection"
20) "transaction"
21) "scripting"

As you can see, so far there are 21 distinct categories. Now let's check what command is part of the geo category:

> ACL CAT geo
 1) "geohash"
 2) "georadius_ro"
 3) "georadiusbymember"
 4) "geopos"
 5) "geoadd"
 6) "georadiusbymember_ro"
 7) "geodist"
 8) "georadius"
 9) "geosearch"
10) "geosearchstore"

Note that commands may be part of multiple categories. For example, an ACL rule like +@geo -@read will result in certain geo commands to be excluded because they are read-only commands. ๐Ÿง 


๐Ÿ’… Allow/block subcommands ๐Ÿ’…

Subcommands can be allowed/blocked just like other commands (by using the separator | between the command and subcommand, for example: +config|get or -config|set)

That is true for all commands except DEBUG. In order to allow/block specific DEBUG subcommands, see the next section. ๐Ÿ™ˆ


๐ŸŽ€ Allow the first-arg of a blocked command ๐ŸŽ€

Note: This feature is deprecated and may be removed in the future.

Sometimes the ability to exclude or include a command or a subcommand as a whole is not enough. Many deployments may not be happy providing the ability to execute a SELECT for any DB, but may still want to be able to run SELECT 0.

In such case we could alter the ACL of a user in the following way:

ACL SETUSER myuser -select +select|0

First, remove the SELECT command and then add the allowed first-arg. Note that it is not possible to do the reverse since first-args can be only added, not excluded. It is safer to specify all the first-args that are valid for some user since it is possible that new first-args may be added in the future. ๐Ÿ”ฎ

Another example:

ACL SETUSER myuser -debug +debug|digest

Note that first-arg matching may add some performance penalty; however, it is hard to measure even with synthetic benchmarks. The additional CPU cost is only paid when such commands are called, and not when other commands are called.

It is possible to use this mechanism in order to allow subcommands in Valkey versions prior to 7.0 (see above section).


๐Ÿ‘‘ +@all VS @all ๐Ÿ‘‘

In the previous section, it was observed how it is possible to define command ACLs based on adding/removing single commands. ๐Ÿ‘€

โœจ Selectors โœจ

Okay so bestie, Valkey can have multiple sets of rules that get evaluated independently of each other. These secondary permission sets are called selectors, and you add them by wrapping a set of rules inside parentheses. To run a command, either the root permissions (the rules defined outside parentheses) or any of the selectors (rules defined inside parentheses) has to match the command. Internally, root permissions get checked first, then selectors in the order they were added. ๐Ÿ’…

For example, imagine a user with ACL rules +GET ~key1 (+SET ~key2). This user can execute GET key1 and SET key2 hello, but not GET key2 or SET key1 world. Periodt.

Unlike the userโ€™s root permissions, selectors cannot be modified after theyโ€™re added. Instead, you remove selectors with the clearselectors keyword, which nukes all the added selectors. Note that clearselectors does not remove the root permissions. ๐Ÿ™ˆ


๐Ÿ”‘ Key permissions ๐Ÿ”‘

key patterns can also define how a command is able to touch a key. This happens through rules that define key permissions. The key permission rules look like %(<permission>)~<pattern>. Permissions are individual characters that map to these key permissions:

  • W (Write) โ€” the data stored inside the key can be updated or deleted.
  • R (Read) โ€” user-supplied data from the key is processed, copied, or returned. Note that this does not include metadata like size info (example STRLEN), type info (example TYPE), or info about whether a value exists inside a collection (example SISMEMBER).

You can compose permissions by specifying multiple characters. If you specify the permission as RW, thatโ€™s considered full access and is analogous to just passing in ~<pattern>. Slay.

For a concrete example, think of a user with ACL rules +@all ~app1:* (+@read ~app2:*). This user has full access on app1:* and readonly access on app2:*. But some commands support reading data from one key, doing some transformation, and storing it into another key. One such command is the COPY command, which copies data from the source key into the destination key. The example set of ACL rules canโ€™t handle a request copying data from app2:user into app1:user, because neither the root permission nor the selector fully matches the command. However, using key selectors you can define a set of ACL rules that can handle this request: +@all ~app1:* %R~app2:*. The first pattern matches app1:user and the second pattern matches app2:user. Iconic.

Which type of permission a command needs is documented through valkey-key-specs(7) key specifications. The type of permission is based off the keyโ€™s logical operation flags. The insert, update, and delete flags map to the write key permission. The access flag maps to the read key permission. If the key has no logical operation flags, like EXISTS, the user still needs either key read or key write permissions to execute the command.

Note: side channels to accessing user data are ignored when evaluating whether read permissions are required to execute a command. This means some write commands that return metadata about the modified key only require write permission on the key to execute. For example:
  • LPUSH key1 data: modifies โ€œkey1โ€ but only returns metadata about it, the size of the list after the push, so the command only requires write permission on โ€œkey1โ€ to execute.
  • LPOP key2: modifies โ€œkey2โ€ but also returns data from it, the left most item in the list, so the command requires both read and write permission on โ€œkey2โ€ to execute.

If an application needs to make sure no data is accessed from a key, including side channels, itโ€™s recommended to not provide any access to the key. ๐Ÿซถ


๐Ÿ•ต๏ธโ€โ™€๏ธ How passwords are stored internally ๐Ÿ•ต๏ธโ€โ™€๏ธ

Valkey internally stores passwords hashed with SHA256. If you set a password and check the output of ACL LIST or ACL GETUSER, youโ€™ll see a long hex string that looks pseudo random. Hereโ€™s an example, because in the previous examples, for the sake of brevity, the long hex string was trimmed:

> ACL GETUSER default
1) "flags"
2) 1) "on"
3) "passwords"
4) 1) "2d9c75273d72b32df726fb545c8a4edc719f0a95a6fd993950b10c474ad9c927"
5) "commands"
6) "+@all"
7) "keys"
8) "~*"
9) "channels"
10) "&*"
11) "selectors"
12) (empty array)

Using SHA256 lets Valkey avoid storing the password in clear text while still allowing a very fast AUTH command, which is a very important feature of Valkey and is coherent with what clients expect from Valkey.

But ACL passwords are not really passwords. Theyโ€™re shared secrets between the server and the client, because the password is not an authentication token used by a human being. For instance:

  • There are no length limits โ€” the password will just be memorized in some client software. There is no human that needs to recall a password in this context.
  • The ACL password does not protect any other thing. For example, it will never be the password for some email account.
  • Often when you are able to access the hashed password itself, by having full access to the Valkey commands of a given server, or corrupting the system itself, you already have access to what the password is protecting: the Valkey instance stability and the data it contains.

For this reason, slowing down the password authentication, in order to use an algorithm that uses time and space to make password cracking hard, is a very poor choice. What we suggest instead is to generate strong passwords, so nobody will be able to crack it using a dictionary or a brute force attack even if they have the hash. To do so, thereโ€™s a special ACL command ACL GENPASS that generates passwords using the system cryptographic pseudorandom generator:

> ACL GENPASS
"dd721260bfe1b3d9601e7fbab36de6d04e2e67b0ef1c53de59d45950db0dd3cc"

The command outputs a 32-byte (256-bit) pseudorandom string converted to a 64-byte alphanumerical string. This is long enough to avoid attacks and short enough to be easy to manage, cut & paste, store, and so forth. This is what you should use in order to generate Valkey passwords. ๐Ÿ’–


๐Ÿ“ Use an external ACL file ๐Ÿ“

There are two ways to store users inside the Valkey configuration:

  1. Users can be specified directly inside the valkey.conf file.
  2. It is possible to specify an external ACL file.

The two methods are mutually incompatible, so Valkey will ask you to use one or the other. Specifying users inside valkey.conf is good for simple use cases. When there are multiple users to define, in a complex environment, we recommend you use the ACL file instead.

The format used inside valkey.conf and in the external ACL file is exactly the same, so itโ€™s trivial to switch from one to the other, and is the following:

user <username> ... acl rules ...

For instance:

user worker +@list +@connection ~jobs:* on >ffa9203c493aa99

When you want to use an external ACL file, youโ€™re required to specify the configuration directive called aclfile, like this:

aclfile /etc/valkey/users.acl

When youโ€™re just specifying a few users directly inside the valkey.conf file, you can use CONFIG REWRITE in order to store the new user configuration inside the file by rewriting it.

The external ACL file however is more powerful. You can do the following:

  • Use ACL LOAD if you modified the ACL file manually and you want Valkey to reload the new configuration. Note that this command is able to load the file only if all the users are correctly specified. Otherwise, an error is reported to the user, and the old configuration will remain valid.
  • Use ACL SAVE to save the current ACL configuration to the ACL file.

Note that CONFIG REWRITE does not also trigger ACL SAVE. When you use an ACL file, the configuration and the ACLs are handled separately. ๐Ÿ™ˆ


๐Ÿ›ก๏ธ ACL rules for Sentinel and Replicas ๐Ÿ›ก๏ธ

In case you donโ€™t want to provide Valkey replicas and Valkey Sentinel instances full access to your Valkey instances, the following is the set of commands that must be allowed in order for everything to work correctly.

For Sentinel, allow the user to access the following commands both in the primary and replica instances:

  • AUTH, CLIENT, SUBSCRIBE, SCRIPT, PUBLISH, PING, INFO, MULTI, SLAVEOF, CONFIG, CLIENT, EXEC.

Sentinel does not need to access any key in the database but does use Pub/Sub, so the ACL rule would be the following (note: AUTH is not needed since it is always allowed):

ACL SETUSER sentinel-user on >somepassword allchannels +multi +slaveof +ping +exec +subscribe +config|rewrite +role +publish +info +client|setname +client|kill +script|kill

Valkey replicas require the following commands to be allowed on the primary instance:

  • PSYNC, REPLCONF, PING

No keys need to be accessed, so this translates to the following rules:

ACL setuser replica-user on >somepassword +psync +replconf +ping

Note that you donโ€™t need to configure the replicas to allow the primary to be able to execute any set of commands. The primary is always authenticated as the root user from the point of view of replicas.


Thatโ€™s the whole tea, bestie. This page is from Valkey version 9.0.0, dated 2025-10-21, and itโ€™s the VALKEY-ACL(7) manual. Stay iconic. ๐Ÿ’…โœจ๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from