I set Redis ACL I use this specifically in multi-user environments to keep commands, key prefixes, and Pub/Sub channels strictly separate. This way, I ensure Security On the server side, minimize unauthorized access and ensure that roles remain easy to manage.
Key points
- Separation number of commands, keys, and channels per user
- Server-side Control Instead of Logic in the App
- Namespaces by key prefix for clients
- ACL file for maintainability and versioning
- Audits using ACL LIST and ACL USERS
ACL Basics in Multi-User Setups
I create a separate user account for each application, team, or client and strictly define their permissions via ACL-Rules. This prevents a single global password from opening all doors and data from being accidentally overwritten. I separate permissions based on commands, key patterns, and channels, so that each account has only the necessary access and nothing more. This server-side isolation reduces the load on the application and increases the Transparency in the security model. This is especially helpful in shared instances, as it allows me to keep track of who is allowed to perform which operation in which namespace.
Permissions Models: Clearly Separate Commands, Keys, and Channels
I assign command permissions on a granular basis, such as categories like @read and @write, and remove risky groups such as @dangerous, which contain configuration or admin commands. For key spaces, I use unique prefixes such as app1:*, app2:*, or tenant_a:* so that read and write access is restricted to a specific namespace. This way, a job can use SET and GET, for example, but only operate under its own prefix. In addition, I restrict Pub/Sub channels so that events only flow into the intended streams. The result is a traceable Separation between roles, data rooms, and communication channels.
Securely Restrict Pub/Sub
For Pub/Sub, I only allow the channels that an application actually needs, and I consistently block everything else ACL-rules. This prevents a service from receiving events from other sources or publishing messages to unexpected subscribers. Especially in event-driven architectures, this control reduces the risk of data leakage or disruption to other services. I document approved channels for each user to ensure that onboarding and audits remain transparent. This way, as the system landscape grows, I maintain Control about data flows.
User and Rule Management in Practice
I create new users using `ACL SETUSER`, assign a strong password, and enable only the commands that the service needs, such as +@read and +@write while simultaneously blocking high-risk commands. I define the permitted key spaces using appropriate patterns, and I manage channels in the same way. For an overview, I use ACL USERS, and I use ACL LIST to get a quick look at the active rules. I load or save changes using ACL LOAD and ACL SAVE to ensure that the configuration and file remain in sync. This is how I maintain the Administration Concise, clear, and reproducible.
| ACL/Auth Command | Purpose | Example |
|---|---|---|
| ACL SETUSER | Create/Edit User | ACL SETUSER app1 on >securePassword +@read +@write -@dangerous ~app1:* |
| ACL LIST | Show Rules | ACL LIST |
| ACL USERS | List users | ACL USERS |
| ACL LOAD/SAVE | Load/Save ACL File | ACL SAVE; ACL LOAD |
| AUTH | Logging in to the server | AUTH app1 securePassword |
Configuration: ACL file or redis.conf?
I save simple setups directly in the redis.conf, but when there are multiple users and roles, I stick with a separate ACL file. I version this file in a secure repository, document changes thoroughly, and deploy updates in a controlled manner. This way, I separate application parameters from security logic, which reduces potential sources of error. At the same time, I harden the instance at the network level, for example by Secure Open Ports and eliminate unnecessary vulnerabilities. Taken together, this increases the Security and simplifies operation.
Namespaces and Client Isolation
I design key prefixes so that they clearly identify tenant IDs and application names, such as tenantA:app1:session:{id}. This allows me to build a clearly visible barrier around each party's data, which is further secured by ACL rules. For migration paths, I use consistent naming schemes to make blue-green or canary rollouts easier. A clear structure also helps with backups and restores because I only need to handle the relevant data segments. This combination of naming conventions and ACL rules keeps the Clients clearly separated.
Microservices and Team Roles in Everyday Life
For each service, I set up a user account that can read from and write to only its own data spaces, without access to other prefixes or administrative functions. For developer accounts, I define restrictive read or write permissions, while admin accounts remain strictly limited and are logged. Batch jobs are given only the commands they need to run—such as read, write, and TTL changes—but no administrative commands. I also restrict external integrations either by time or to test environments so that misconfigurations do not Productive-Data handling. This is how I clearly assign responsibilities without compromising security.
Limitations of ACLs and Isolation Levels
I understand ACLs correctly: They control access, but they do not isolate it Resources such as CPU, RAM, or I/O at the process level. In strict compliance scenarios, I therefore consider dedicated instances, separate clusters, or dedicated nodes. Logical separation via ACLs reduces unauthorized access but still shares the same server resources. For sensitive workloads, I plan additional isolation, such as through network segments, containers, or VM boundaries. This way, I combine access control with technical shielding for a higher level of security.
Operations: Audits, Rotation, and Logging
I regularly check permissions using `ACL LIST` and maintain a change log so that I can quickly verify what is active during audits. I rotate passwords at fixed intervals, and I carefully log login events and unusual patterns. In the event of incidents, I immediately lock out affected users, load updated rules, and automatically test critical paths. In CI/CD, I incorporate checks that flag prohibited commands or missing prefixes in configurations. This Procedure saves time and minimizes operational downtime.
Architectural Decisions: Shared or Dedicated
I'm weighing whether to have multiple customers use a shared instance or to set up separate servers, since both have their own Risks and advantages. Shared hosting saves money but requires strict ACLs, well-defined namespaces, and close monitoring. Dedicated hosting reduces cross-impact but requires more hardware and maintenance. When it comes to performance and security issues, I prefer comparisons such as Shared vs. Dedicated I evaluate them and conduct load testing. In the end, I make my decision based on data access, compliance requirements, and Budget.
Cluster or Standalone—Which Is Best for ACLs?
I use ACLs in both standalone instances and clusters, but I make sure the rules are consistent across all nodes. In clusters, I check how keys are distributed across slots to ensure that prefixes and permissions continue to apply appropriately. For high availability, I require that failover does not Fracture generated in the permissions chain and that the ACL file is identical everywhere. I test migration paths in advance to ensure that replica switches or upgrades do not create gaps. Anyone evaluating the architecture can refer to comparisons such as Cluster vs. Standalone use this as a guide and then roll out the ACL strategy accordingly.
Planning and Bootstrap: Getting Off to a Solid Start
I start with a clean Bootstrap installation. The built-in „default“ user is not granted extensive privileges: I either disable it completely or, by default, revoke all commands, keys, and channels from it. This prevents accidental operations without user isolation. For operational tasks, I deliberately define separate admin accounts with multi-factor authentication at the management level (e.g., bastion host/TLS client certificates) and strict ACLs.
# Secure Startup in the ACL File
user default off
user admin on >StrongAdminPassword +@admin -@dangerous allkeys allchannels
I generate strong passwords on the server side so that they never end up in logs or shell history. For fast, secure tokens, I use a generator on the server and rotate them regularly. For modern clients, I prefer to authenticate via HELLO using a one-step username/password process, which explicitly specifies the protocol version and avoids edge cases.
Patterns and Pitfalls with Key and Channel ACLs
When it comes to key patterns, I work exclusively with permission lists. I start by resetkeys and then add specific ~ patterns, such as ~tenantA:* and ~tenantA:app1:* for more finely defined scopes. Overlapping prefixes are a critical issue: If a user has ~tenantA:* and should not see areas such as tenantA:archiv:*, then I plan the namespaces so that sensitive subsets are prefixed independently (e.g., tenantA:priv:*), which I simply do not grant access to. Similar rules apply to channels: I set resetchannels and grant access only to &tenantA:* and exactly those channels required for keyspace notifications, if any.
# Strict keys and channels
ACL SETUSER tenantA:app1 on >Pass +@read +@write -@dangerous \
resetkeys ~tenantA:app1:* \
resetchannels &tenantA:app1:*
I note that commands such as RENAME, MIGRATE, or DUMP/RESTORE could write across prefix boundaries. Such commands remain blocked in production service accounts. Hash fields, list elements, or sorted set members are not separate keys—the ACL applies at the key level, not within the data structure. Therefore, a well-defined key prefix scheme is sufficient to cover these structures as well.
Deliberately Manage Command Categories
I only enable what I really need. For standard CRUD workloads, +@read and +@write are often sufficient. I always block categories with increased risk: @admin and @dangerous are off-limits to application users. In multi-tenant setups, I avoid using scripting functions (EVAL, FUNCTION) whenever possible. For Pub/Sub services, I decouple permissions so that write commands on keys aren’t automatically allowed. In practice, I start with minimal permissions and, when necessary, selectively allow individual commands (+COMMAND) rather than opening up entire categories.
Rotation and Zero-Downtime Changes
I'm planning to rotate passwords without downtime. Redis allows multiple active passwords per user. The process is simple: First, set a new password in addition to the existing one; then, update the clients; finally, remove the old one with resetpass Remove. I use the same principle for incremental changes to permissions: When in doubt, I temporarily switch to dry runs and test users before making changes to production accounts.
# Rotation Process
ACL SETUSER app1 >NewPassword # Set new password as well
# Update clients ...
ACL SETUSER app1 resetpass >NewPassword # Old password removed, new one remains
Delve Deeper into Testing, Debugging, and Audits
I test changes before they go live. Using a dry run, I check whether a user should be allowed to execute a command on a specific key or channel without actually executing it. I track unauthorized access attempts and rule violations in a dedicated ACL log and configure appropriate retention and routing to my central log infrastructure. To ensure transparency, I also use the category lists to understand which commands are associated with each category.
# Simulate permissions
ACL DRYRUN app1 GET otherprefix:key
# Check current user identity
ACL WHOAMI
# View/reset failed access attempts
ACL LOG
ACL LOG RESET
# Display commands by category
ACL CAT @write
For audits, in addition to the ACL LIST/USERS file, I also keep snapshots of the ACL file in version control. Every change is assigned a ticket or change request and goes through a merge process that requires a reviewer. This way, I can always track who expanded or restricted which permissions and when.
Scripting, Functions, and Secure Execution
Lua scripts and server-side functions are powerful—but they can also serve as a potential escape route from isolation if they’re granted too broad access. In shared environments, I disable EVAL/EVALSHA and function management by default and allow them only in clearly defined admin contexts. If scripting is necessary, I carefully verify that the scripts access only permitted key prefixes, since ACLs also apply to calls made from scripts. This reduces the risk of indirectly accessing unauthorized areas.
Replication, High Availability, and Consistency of ACLs
In replicated setups, I separate application users from replication users. For replication, I set up a dedicated technical account that is granted only the commands necessary for SYNC/PSYNC/REPLCONF and related commands. I keep the ACL file synchronized across all nodes—through manual maintenance via configuration management, or in managed clusters using the mechanisms provided there. After making changes, I save the rules centrally and deploy them to new nodes in a controlled manner to ensure that a failover does not result in a breach of permissions.
In clusters, I also check whether the key prefixes are still properly aligned with slot boundaries. This is less of an ACL issue and more of a design consideration for even load distribution and simpler permission management („one prefix, one data space, many slots“). During a failover, I ensure that replication users and admin accounts are already available on the target node so that the switchover remains transparent.
Client Changes, Migrations, and Backups
When renaming prefixes or tenant IDs, I factor in the ACL implications in advance. If a tenant migrates from tenantA: to tenantA2:, I temporarily allow both patterns and plan a clear transition phase. I ensure that migration jobs themselves use a strictly limited user account that only reads from and writes to the necessary prefixes. For backups, I note that the ACL file is separate from the RDB/AOF—so I back it up separately as part of the configuration. For partial restores, precise prefixes are helpful because they allow me to selectively extract only the relevant key spaces.
Client Integration and Secure Protocols
On the client side, I consistently use username/password authentication instead of relying on a global „requirepass“ setting. For modern clients, I use the HELLO handshake to negotiate the protocol version and authentication in a single step. In production environments, I rely on TLS encryption to ensure that login credentials and data paths remain secure. I also verify that clients do not log usernames in plain text or that logs are redacted accordingly.
# Example: Single-Step Authentication
HELLO 3 AUTH app1 securePassword
CI/CD Automation and Configuration Templates
I model ACLs as code. Roles and users are created from templates that I populate with variables (prefix, channels, categories) for each environment. Validations run in the pipeline: linters check that no @dangerous/@admin commands end up in service accounts, tests run DRYRUNs against representative keys, and a smoke test container briefly starts up against an isolated Redis instance to verify AUTH, GET/SET, and Pub/Sub end-to-end. Changes are not rolled out until all checks pass, and in the event of a rollback, the previous ACL file is immediately available.
Operational Details: Visibility and Cleanup
In everyday work, small tools can make a big difference. With ACL WHOAMI, I can quickly check which account a client is actually using—which is especially valuable in complex toolchains. I regularly clean up „zombie“ accounts: Deactivated services lose their users („off“), passwords are removed („resetpass“), and key and channel permissions are deleted („resetkeys,“ „resetchannels“). I adhere to naming conventions for users (such as team_service_env), which speeds up audits and incident response.
Briefly summarized
I am planning ACLs From the very beginning, I create one user per service and strictly limit that user’s commands, key prefixes, and channels. For maintainable setups, I use a separate ACL file, deploy changes in a controlled manner, and document every step. Namespaces with clear prefixes secure tenant isolation, while audits, rotation, and logging ensure reliable operation. For sensitive scenarios, I also incorporate architectural separation so that access control and technical isolation work together. This transforms a shared Redis instance into a manageable, safe A platform for many user groups.


