Configure ACL Security

Time: 10-15 minutes
Prerequisites:

  • Redis Cloud database already created
  • redisctl configured with Cloud credentials
  • Basic understanding of Redis ACL commands

What are ACLs?

Access Control Lists (ACLs) allow you to create users with specific permissions, limiting which commands they can run and which keys they can access. This is essential for:

  • Multi-tenant applications
  • Restricting administrative access
  • Compliance requirements
  • Defense in depth security

Quick Command

Create a read-only user for your application:

# Create Redis rule
redisctl cloud acl create-redis-rule \
  --subscription YOUR_SUB_ID \
  --data '{"name": "readonly-rule", "rule": "+@read ~*"}' \
  --wait

# Create role with the rule
redisctl cloud acl create-role \
  --subscription YOUR_SUB_ID \
  --data '{"name": "readonly-role", "redis_rules": [{"rule_name": "readonly-rule"}]}' \
  --wait

# Create user with the role
redisctl cloud acl create-acl-user \
  --subscription YOUR_SUB_ID \
  --data '{"name": "app-reader", "role": "readonly-role", "password": "SecurePass123!"}' \
  --wait

Step-by-Step Guide

Understanding the ACL Hierarchy

Redis Cloud uses a three-level ACL system:

  1. Redis Rules - Define command and key access patterns (Redis ACL syntax)
  2. Roles - Group multiple Redis rules together
  3. Users - Assigned one role and a password

1. List Existing ACL Components

# View current Redis rules
redisctl cloud acl list-redis-rules --subscription 42 -o table

# View current roles
redisctl cloud acl list-roles --subscription 42 -o table

# View current users
redisctl cloud acl list-acl-users --subscription 42 -o table

2. Create Redis ACL Rules

Redis rules use standard Redis ACL syntax.

Common Rule Patterns

Read-only access:

redisctl cloud acl create-redis-rule \
  --subscription 42 \
  --data '{
    "name": "readonly",
    "rule": "+@read ~*"
  }' \
  --wait

Write-only to specific keys:

redisctl cloud acl create-redis-rule \
  --subscription 42 \
  --data '{
    "name": "write-metrics",
    "rule": "+set +del ~metrics:*"
  }' \
  --wait

Full access except dangerous commands:

redisctl cloud acl create-redis-rule \
  --subscription 42 \
  --data '{
    "name": "safe-admin",
    "rule": "+@all -@dangerous ~*"
  }' \
  --wait

Access to specific key prefix:

redisctl cloud acl create-redis-rule \
  --subscription 42 \
  --data '{
    "name": "user-sessions",
    "rule": "+@all ~session:*"
  }' \
  --wait

3. Create ACL Roles

Roles combine one or more Redis rules:

# Simple role with one rule
redisctl cloud acl create-role \
  --subscription 42 \
  --data '{
    "name": "readonly-role",
    "redis_rules": [
      {"rule_name": "readonly"}
    ]
  }' \
  --wait

# Complex role with multiple rules
redisctl cloud acl create-role \
  --subscription 42 \
  --data '{
    "name": "app-worker",
    "redis_rules": [
      {"rule_name": "readonly"},
      {"rule_name": "write-metrics"}
    ]
  }' \
  --wait

4. Create ACL Users

Users are assigned a role and password:

redisctl cloud acl create-acl-user \
  --subscription 42 \
  --data '{
    "name": "app-reader",
    "role": "readonly-role",
    "password": "SecureReadOnlyPass123!"
  }' \
  --wait

What you should see:

{
  "taskId": "abc123...",
  "status": "processing"
}
...
ACL user created successfully!
{
  "id": 456,
  "name": "app-reader",
  "role": "readonly-role",
  "status": "active"
}

5. Assign Users to Databases

After creating users, assign them to specific databases:

# Get database ID
redisctl cloud database list \
  --subscription 42 \
  -q '[].{id: database_id, name: name}'

# Update database with ACL users
redisctl cloud database update \
  --subscription 42 \
  --database-id 12345 \
  --data '{
    "security": {
      "users": ["app-reader", "app-writer"]
    }
  }' \
  --wait

6. Test ACL User

Connect to your database with the new user:

# Get database endpoint
redisctl cloud database get \
  --subscription 42 \
  --database-id 12345 \
  -q '{endpoint: public_endpoint, port: port}'

# Test connection
redis-cli -h redis-12345.cloud.redislabs.com \
  -p 12345 \
  --user app-reader \
  --pass SecureReadOnlyPass123! \
  PING

# Test permissions (should succeed)
redis-cli --user app-reader --pass SecureReadOnlyPass123! \
  -h redis-12345.cloud.redislabs.com -p 12345 \
  GET mykey

# Test restricted command (should fail)
redis-cli --user app-reader --pass SecureReadOnlyPass123! \
  -h redis-12345.cloud.redislabs.com -p 12345 \
  SET mykey value
# Error: NOPERM this user has no permissions to run the 'set' command

Common ACL Patterns

Application Access Pattern

Separate users for read, write, and admin operations:

# Read-only for queries
redisctl cloud acl create-redis-rule --subscription 42 \
  --data '{"name": "app-read", "rule": "+@read +@connection ~*"}' --wait

# Write access for updates
redisctl cloud acl create-redis-rule --subscription 42 \
  --data '{"name": "app-write", "rule": "+@write +@read +@connection ~*"}' --wait

# Admin for maintenance
redisctl cloud acl create-redis-rule --subscription 42 \
  --data '{"name": "app-admin", "rule": "+@all ~*"}' --wait

# Create roles and users
redisctl cloud acl create-role --subscription 42 \
  --data '{"name": "reader", "redis_rules": [{"rule_name": "app-read"}]}' --wait

redisctl cloud acl create-role --subscription 42 \
  --data '{"name": "writer", "redis_rules": [{"rule_name": "app-write"}]}' --wait

redisctl cloud acl create-role --subscription 42 \
  --data '{"name": "admin", "redis_rules": [{"rule_name": "app-admin"}]}' --wait

Multi-Tenant Pattern

Isolate tenants by key prefix:

# Tenant A access
redisctl cloud acl create-redis-rule --subscription 42 \
  --data '{"name": "tenant-a", "rule": "+@all ~tenant:a:*"}' --wait

# Tenant B access
redisctl cloud acl create-redis-rule --subscription 42 \
  --data '{"name": "tenant-b", "rule": "+@all ~tenant:b:*"}' --wait

# Create roles and users
redisctl cloud acl create-role --subscription 42 \
  --data '{"name": "tenant-a-role", "redis_rules": [{"rule_name": "tenant-a"}]}' --wait

redisctl cloud acl create-acl-user --subscription 42 \
  --data '{"name": "tenant-a-user", "role": "tenant-a-role", "password": "TenantAPass123!"}' --wait

Using Configuration Files

For complex ACL setups:

cat > acl-setup.json << 'EOF'
{
  "rules": [
    {
      "name": "readonly",
      "rule": "+@read ~*"
    },
    {
      "name": "write-cache",
      "rule": "+set +get +del +expire ~cache:*"
    }
  ],
  "roles": [
    {
      "name": "cache-worker",
      "redis_rules": [
        {"rule_name": "readonly"},
        {"rule_name": "write-cache"}
      ]
    }
  ],
  "users": [
    {
      "name": "worker-1",
      "role": "cache-worker",
      "password": "Worker1Pass!"
    }
  ]
}
EOF

# Create rules - using jq to extract JSON objects from array
for rule in $(jq -c '.rules[]' acl-setup.json); do
  redisctl cloud acl create-redis-rule \
    --subscription 42 \
    --data "$rule" \
    --wait
done

# Create roles
for role in $(jq -c '.roles[]' acl-setup.json); do
  redisctl cloud acl create-role \
    --subscription 42 \
    --data "$role" \
    --wait
done

# Create users
for user in $(jq -c '.users[]' acl-setup.json); do
  redisctl cloud acl create-acl-user \
    --subscription 42 \
    --data "$user" \
    --wait
done

Redis ACL Syntax Reference

Common patterns in Redis ACL rules:

Command categories:

  • +@read - All read commands
  • +@write - All write commands
  • +@admin - Administrative commands
  • +@dangerous - Dangerous commands (FLUSHDB, KEYS, etc.)
  • +@all - All commands
  • -@dangerous - Deny dangerous commands

Specific commands:

  • +get - Allow GET command
  • +set - Allow SET command
  • -flushdb - Deny FLUSHDB

Key patterns:

  • ~* - All keys
  • ~cache:* - Keys starting with "cache:"
  • ~user:* - Keys starting with "user:"
  • ~* ~-secret:* - All keys except those starting with "secret:"

Managing ACLs

View ACL Details

# Get specific user details
redisctl cloud acl get-acl-user \
  --subscription 42 \
  --user-id 456 \
  -o json

# List all users with their roles
redisctl cloud acl list-acl-users \
  --subscription 42 \
  -o json \
  -q '[].{name: name, role: role, id: id}'

Update ACL Rules

# Update existing rule
redisctl cloud acl update-redis-rule \
  --subscription 42 \
  --rule-id 789 \
  --data '{
    "name": "readonly",
    "rule": "+@read +@connection ~*"
  }' \
  --wait

Update User Password

redisctl cloud acl update-acl-user \
  --subscription 42 \
  --user-id 456 \
  --data '{
    "password": "NewSecurePass456!"
  }' \
  --wait

Delete ACL Components

# Delete user
redisctl cloud acl delete-acl-user \
  --subscription 42 \
  --user-id 456 \
  --wait

# Delete role
redisctl cloud acl delete-role \
  --subscription 42 \
  --role-id 321 \
  --wait

# Delete Redis rule
redisctl cloud acl delete-redis-rule \
  --subscription 42 \
  --rule-id 789 \
  --wait

Common Issues

Cannot Create User with Reserved Name

Error: User name 'default' is reserved

Solution: Avoid reserved names: default, admin. Use descriptive application-specific names.

ACL Rule Syntax Error

Error: Invalid ACL rule syntax

Solution: Test your ACL rule locally first:

redis-cli ACL SETUSER testuser "+@read ~*"
redis-cli ACL GETUSER testuser
redis-cli ACL DELUSER testuser

User Cannot Connect

Troubleshooting:

  1. Verify user is assigned to the database
  2. Check password is correct
  3. Ensure user status is "active"
  4. Test with default user first to isolate ACL vs. network issues

Permission Denied

Error: NOPERM this user has no permissions to run the 'set' command

Solution: Review and update the user's role and rules:

# Check user's role
redisctl cloud acl get-acl-user --subscription 42 --user-id 456 -q 'role'

# Check role's rules
redisctl cloud acl list-roles --subscription 42 -q '[?name==`readonly-role`]'

Best Practices

  1. Principle of Least Privilege: Give users only the permissions they need
  2. Use Key Prefixes: Design your key naming to support ACLs (e.g., user:123:profile)
  3. Separate Credentials: Different users for read vs. write operations
  4. Rotate Passwords: Regularly update user passwords
  5. Test Before Production: Verify ACL rules in a test database first
  6. Document Rules: Keep track of what each rule and role does

Next Steps

  • Setup VPC Peering - Private network connectivity
  • Configure TLS/SSL - Encryption in transit
  • Backup and Restore - Protect your data
  • Monitor Performance - Track database metrics

See Also