Locking It Down with Redis ACLs: A Dev's Guide to Secure Access
Athreya aka Maneshwar

Athreya aka Maneshwar @lovestaco

About: Technical Writer | 200k+ Reads | i3 x Mint | Learning, building, improving, writing :)

Joined:
Jan 5, 2023

Locking It Down with Redis ACLs: A Dev's Guide to Secure Access

Publish Date: Jun 19
10 0

Hi there! I'm Maneshwar. Right now, I’m building LiveAPI, a first-of-its-kind tool that helps you automatically index API endpoints across all your repositories. LiveAPI makes it easier to discover, understand, and interact with APIs in large infrastructures.


Redis has long been the go-to for fast in-memory data, whether it's caching, job queues, pub/sub, or real-time analytics.

But with great power comes the need for great control.

If you've ever worried about giving too much access to too many Redis clients, it's time you got familiar with Redis ACLs (Access Control Lists).

Whether you're a backend dev, a DevOps engineer, or just someone who’s tired of redis-cli users running KEYS * in production — this blog is for you.

Why Redis ACLs?

Prior to Redis 6, Redis had only one global password. Anyone with access to Redis could do anything — flush databases, delete keys, rewrite config, and more.

That’s not ideal when you're scaling up with multiple services, teams, or environments.

Enter ACLs: user-based access control introduced in Redis 6.

With Redis ACLs, you can:

Create named users
Assign specific permissions (read-only, streams-only, pub/sub, etc.)
Control what commands and keys each user can access
Use hashed passwords and role-based restrictions

Redis ACL Essentials

Redis ACLs work by defining users in either the redis.conf or a dedicated ACL file.

Let’s break down a typical ACL entry:

user runner-8 on >mySecretPass +xadd +xread ~logs_stream
Enter fullscreen mode Exit fullscreen mode

This means:

  • runner-8 is the username
  • on → user is enabled
  • > mySecretPass → password (in plaintext)
  • +xadd +xread → only allowed to run XADD and XREAD (Redis Streams)
  • ~logs_stream → can only access key logs_stream

You can also hash passwords with SHA256:

user runner-8 on sanitize-payload #<sha256-hash> +xadd ~logs_stream
Enter fullscreen mode Exit fullscreen mode

Creating ACL Users: Manual & Automated

Option 1: Manually via redis-cli

Connect to your Redis server and run:

ACL SETUSER runner-8 on >mySecretPass +xadd +xread ~logs_stream
Enter fullscreen mode Exit fullscreen mode

To verify:

ACL LIST
Enter fullscreen mode Exit fullscreen mode

To see current user:

ACL WHOAMI
Enter fullscreen mode Exit fullscreen mode

To delete a user:

ACL DELUSER runner-8
Enter fullscreen mode Exit fullscreen mode

But this won't persist across restarts unless saved to an ACL file.


Option 2: Define ACLs in users.acl file

Create (or edit) your ACL file:

sudo nano /etc/redis/users.acl
Enter fullscreen mode Exit fullscreen mode

Add:

user default on >supersecret +@all ~*
user runner-8 on >mySecretPass +xadd +xread ~logs_stream
Enter fullscreen mode Exit fullscreen mode

Then make sure your redis.conf has this line:

aclfile /etc/redis/users.acl
Enter fullscreen mode Exit fullscreen mode

Restart Redis:

sudo systemctl restart redis
Enter fullscreen mode Exit fullscreen mode

Example: Isolating Access for Asynq Workers

Let’s say you have a Go service using Asynq for background jobs. You don’t want it touching anything except:

  • A stream named logs_stream
  • Heartbeat keys like runners:heartbeat
  • Pub/Sub channels used by Asynq

You’d write:

user runner-8 on >Masd2dnnsd +xadd +xread +xrange +xrevrange +subscribe +psubscribe +publish +unsubscribe ~logs_stream ~runners:heartbeat ~__asynq* ~asynq*
Enter fullscreen mode Exit fullscreen mode

In ACL terms:

  • +xadd/xread/... → Redis Stream commands
  • +subscribe/... → Pub/Sub permissions
  • ~key → key patterns the user can access

And then use in code:

asynq.RedisClientOpt{
  Addr: "localhost:6379",
  Username: "runner-8",
  Password: "Masd2dnnsd",
}
Enter fullscreen mode Exit fullscreen mode

Testing Access

Try running:

redis-cli -u redis://runner-8:Masd2dnnsd@localhost:6379
Enter fullscreen mode Exit fullscreen mode

Inside:

SET foo bar
# → (error) NOPERM this user has no permissions to run the 'SET' command

XADD logs_stream * message "hello"
# → OK
Enter fullscreen mode Exit fullscreen mode

Bonus: Use Ansible to Manage Redis ACLs

An example Ansible task:

- name: Configure Redis ACL file
  copy:
    dest: /etc/redis/users.acl
    content: |
      user default on >supersecret +@all ~*
      user runner-8 on >Masd2dnnsd +xadd +xread +xrange +xrevrange +subscribe +psubscribe +publish +unsubscribe ~logs_stream ~runners:heartbeat ~__asynq* ~asynq*
    owner: redis
    group: redis
    mode: "0644"

- name: Ensure Redis uses ACL file
  lineinfile:
    path: /etc/redis/redis.conf
    regexp: '^aclfile '
    line: 'aclfile /etc/redis/users.acl'

- name: Restart Redis
  systemd:
    name: redis-server
    state: restarted
Enter fullscreen mode Exit fullscreen mode

Summary

Redis ACLs give you powerful, fine-grained access control. Whether you're running job queues, microservices, or multi-tenant systems, ACLs help you enforce the principle of least privilege.

No more all-or-nothing access. Just clean, secure, permission-scoped access — Redis style.

Got Redis ACL horror stories or wins? Drop them in the comments. Or let me know if you want a prebuilt ACL policy template for your app or worker.


LiveAPI helps you get all your backend APIs documented in a few minutes.

With LiveAPI, you can generate interactive API docs that allow users to search and execute endpoints directly from the browser.

LiveAPI Demo

If you're tired of updating Swagger manually or syncing Postman collections, give it a shot.

Comments 0 total

    Add comment