ElastiCache Serverless: SCAN Command Fails with RBAC Key Pattern Restrictions
Summary
SCAN command returns ERR internal error on ElastiCache Serverless (Valkey 7.2) when the authenticated RBAC user has an ACL key pattern restriction (~{prefix}*), even though +scan permission is explicitly granted. The same SCAN command succeeds when using an admin user with unrestricted key access (~*).
Environment
- Service: ElastiCache Serverless
- Engine: Valkey 7.2
- Region: us-east-1
- Cache Name: trifecta-cache-wsk1hn35
- User Group: trifecta-ug-wsk1hn35
Problem Description
We are using ElastiCache Serverless with RBAC for multi-tenant key isolation. Each tenant has a dedicated RBAC user with:
- Key pattern restriction:
~{tenant-prefix}*
- Explicit permissions:
+@read +@write +@connection -@dangerous +info +scan +eval +evalsha
When the tenant user executes SCAN (directly or via application), ElastiCache returns:
ERR internal error
This breaks our selective cache flush implementation which uses SCAN to find keys matching the tenant's prefix before deleting them.
RBAC User Configurations
Tenant User (SCAN fails):
UserId: site-319acc2f-staging
AccessString: on ~{site-319acc2f-staging}* -@all +@read +@write +@connection -@dangerous +info +scan +eval +evalsha
Admin User (SCAN succeeds):
UserId: trifecta-admin-wsk1hn35
AccessString: on ~* +@all
Test Results
| Command | User | ACL Key Pattern | Result |
|---|
SCAN 0 | Tenant | ~{site-319acc2f-staging}* | ❌ ERR internal error |
SCAN 0 MATCH {site-319acc2f-staging}* | Tenant | ~{site-319acc2f-staging}* | ❌ ERR internal error |
SCAN 0 | Admin | ~* | ✅ Returns cursor + keys |
GET {site-319acc2f-staging}key | Tenant | ~{site-319acc2f-staging}* | ✅ Works |
SET {site-319acc2f-staging}key value | Tenant | ~{site-319acc2f-staging}* | ✅ Works |
MGET (multiple keys) | Tenant | ~{site-319acc2f-staging}* | ✅ Works |
DBSIZE | Tenant | ~{site-319acc2f-staging}* | ✅ Works (returns count) |
INFO server | Tenant | ~{site-319acc2f-staging}* | ✅ Works |
Key Observations
- SCAN fails even with
+scan explicitly granted in the ACL
- SCAN fails even when MATCH pattern is within the allowed prefix - the restriction appears to be on the command itself, not the pattern
- DBSIZE works - this also iterates the keyspace but only returns a count, not key names
- All other commands work - GET, SET, MGET, MSET, INFO all function correctly with the key restriction
Expected Behavior
Based on AWS documentation:
- SCAN is listed as a supported command on ElastiCache Serverless
- RBAC key patterns (
~prefix*) should restrict which keys a user can access
+scan permission should allow the SCAN command
- SCAN with a MATCH pattern within the user's allowed prefix should return only matching keys
We expected SCAN to work and return only keys matching the user's ACL pattern, similar to how GET/SET only work on keys within the allowed pattern.
Actual Behavior
SCAN returns ERR internal error regardless of:
- Whether a MATCH pattern is provided
- Whether the MATCH pattern is within the user's allowed prefix
- The COUNT parameter value
Documentation Gap
AWS documentation does not mention any incompatibility between:
- SCAN command and RBAC key pattern restrictions
- ElastiCache Serverless and SCAN with restricted users
Reference: https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/SupportedCommands.html
Impact
This limitation prevents us from implementing per-tenant selective cache flush in a multi-tenant architecture. The alternatives are:
- Use unrestricted admin credentials for flush (security concern)
- Remove key restrictions from tenant users (loses RBAC isolation)
- Avoid SCAN entirely and use alternative flush strategies
Questions for AWS
- Is this behavior intentional or a bug?
- If intentional, can the documentation be updated to reflect this limitation?
- Is there a workaround that preserves both RBAC key isolation and SCAN functionality?
- Is this specific to ElastiCache Serverless, or does it also affect provisioned ElastiCache with RBAC?
Reproduction Steps
- Create ElastiCache Serverless cache with RBAC User Group
- Create user with key restriction:
on ~{prefix}* +@read +@write +@connection +scan
- Authenticate as that user
- Execute:
SCAN 0
- Observe:
ERR internal error
- Create admin user with:
on ~* +@all
- Authenticate as admin
- Execute:
SCAN 0
- Observe: Success with cursor and keys