BB SKILLS / LEARN

Test Redis cache expiry and ACL boundaries before shipping

Test Redis cache expiry and ACL boundaries before shipping. Our disposable Redis fixture checked data types, TTL updates, conflicting writes, key-name visibility and connection revocation. Read the observed contracts before adapting a skill to your own application.

Choose a model for the access pattern

Redis Data Modeling and Cache Keys covers data-type choices and naming conventions. Redis ACL and Network Security covers authentication, command and key permissions, TLS and network exposure. These are official Redis instruction bundles with complete references, pinned sources and MIT notices. BB Skills adds an independent command fixture and scope notes.

Start with the reads and writes your application needs. In our fixture, incrementing a String counter twice returned 1 then 2. Updating one Hash field left another field unchanged; a Set deduplicated repeated members; a Sorted Set returned members in score order. These observations illustrate access patterns, rather than proving a memory or latency advantage. A colon-separated key convention helps organize data, but does not enforce tenant isolation by itself.

The upstream reference also discusses JSON, Vector Set and field-level expiry. Check the server version and available commands or modules before using those examples. Our recorded experiment used Redis 7.4.11 and Python 3.13.16. It did not evaluate those newer types, Java/Jedis or redis-py clients.

Make expiry an explicit write contract

Decide what should happen to expiry when a value changes. We created a String with a 30-second expiry and confirmed a positive TTL window, then replaced it with plain SET. The replacement removed expiry. Updating with KEEPTTL retained a positive TTL. Modifying a Hash field also retained the key's expiry. These are different write contracts, so adding an expiry once does not establish that every later update will keep it.

Fixture actionObserved TTL contractReview question
SET with EX 30Greater than 0 and at most 30 secondsWas expiry attached to this write?
Plain SET of the same key-1: key has no expiryShould replacement reset or preserve the policy?
SET with KEEPTTLPositive expiry window retainedDoes this operation intentionally retain the old deadline?
HSET of an existing expiring HashPositive key expiry retainedIs this key-level expiry sufficient for the model?
TTL of a missing key-2Are missing and persistent keys handled differently?

The probe checks ranges rather than assuming the next command will see exactly 30 seconds. It does not wait for expiry, test clock adjustment or simulate persistence and failover. For supported syntax and version notes, read the official SET reference and EXPIRE reference.

Check the result of a conflicting transaction

We used two independent connections for one controlled conflict. The first watched a key and queued an increment inside MULTI. The second connection incremented the watched key before EXEC. EXEC returned a null response, and the value showed only the second connection's write. A subsequent transaction without that intervening write completed and returned its results.

A queued command is not proof that EXEC committed. Application logic needs to handle an aborted transaction and choose a retry policy appropriate to its operation. This experiment is a single controlled conflict, not a concurrency stress test, durability check or Redis Cluster transaction test. The official transaction guide explains the surrounding behavior.

Test data access and key-name visibility separately

The upstream cache-reader example allows GET, MGET and SCAN for a cache key pattern. We created an equivalent role with a generated password and synthetic keys. GET in the allowed cache prefix succeeded; GET outside it, a mixed-prefix MGET, SET and FLUSHALL were denied. The denied write left the existing value unchanged.

However, a complete SCAN traversal returned a synthetic key name outside that cache prefix. The role could not read that key's value. Key-pattern permission checks and key-name discovery are different boundaries; a naming convention or read-denial result alone does not demonstrate that a tenant cannot discover other names. This is an observed command behavior, not a claim that Redis has a vulnerability.

Reader operationRecorded resultBoundary checked
GET cache:visibleSynthetic cache valueAllowed data read
GET private:probeNOPERMDenied value read
MGET with both prefixesNOPERMDenied mixed-key read
SCAN to cursor 0Included private:probeKey name visible, value still restricted
SET or FLUSHALLNOPERMDenied write and destructive command

Grant discovery commands only when needed, review their behavior for the target version and consider whether key names carry sensitive information. The fixture never used real user data. The official ACL guide and SCAN reference are the primary command documentation.

Tighten existing ACLs with deliberate resets

ACL SETUSER updates can add rules to an existing role. We temporarily granted the reader another key prefix and SET, then issued an update containing only the cache prefix and GET. The broader prefix and write permission remained usable. Repeating a short desired-looking rule list did not replace the earlier grants.

In this synthetic case, resetkeys and -@all cleared the existing key patterns and command grants before adding the intended cache-only reads. We required an OK response to that edit, then confirmed that the other prefix, SET and SCAN were denied. This is a narrow command-and-key reset, not a universal replacement of passwords, channel grants or selectors. Review the exact ACL dimensions your application uses before changing an existing user. The official ACL SETUSER reference describes the rule syntax.

Distinguish disabling a user from closing connections

Setting the reader to off prevented a new connection from authenticating. An already-authenticated reader connection continued to read its allowed cache value. The dedicated fixture administrator then used CLIENT KILL USER for this synthetic reader, and the existing connection closed. New-authentication denial and existing-session termination are separate checks.

Plan credential changes and connection termination together when responding to an access change. Review application reconnect behavior and avoid killing unrelated clients. We tested one existing reader connection in an isolated installation; no production client, failover or connection pool was involved.

Separate lab isolation from production hardening

Our runner created an internal Docker network, published no host ports, placed Redis data in tmpfs and used freshly generated passwords passed through memory and standard input. The container's 0.0.0.0 bind was confined to that internal lab network. It is not a production bind or firewall template. Protected mode remained enabled after the authenticated fixture bootstrap.

Docker Compose Patterns can help review service networks and dependencies, but the published fixture uses explicit Docker commands so its ownership and cleanup are inspectable. For a production Redis target, review TLS verification, network reachability, credentials, ACLs, persistence and backup policy separately. Our plain internal TCP probe did not test TLS, firewall rules, exposed-port scanning, command renaming or production configuration.

Reproduce the evidence and review its scope

The two skill ZIPs contain the probe, Docker runner and the same 44 named observations, with source SHA-256 values, runtime versions and image identities. These observations are shared across the two resources, not 44 independent checks per skill. Original upstream instructions and complete references remain inside each package; the primary instructions identify BB Skills additions.

Read examples/README.md before running anything. The original lab reused a cached application image solely to provide Python. For independent reproduction, select and review a Python runtime with the recorded version and adapt the runner's image references. That changes the runner hash, which a new result should record. Skill MIT licensing covers included source and fixture additions; server and runtime binary licenses are separate, and those binaries are not redistributed.

Author: BB Skills. AI assistance helped draft and review the fixture and article. The published conclusions are tied to recorded native responses; no AI client executed the full skill, and no speedup, production security certification, TLS verification or search visibility improvement was measured. Review the installation guide and diagnostic-report guide for interpreting prerequisites and scoped evidence.

Resources in this guide

Open the library →