Connector

Redis access governance — every command reviewed before it runs

Last updated

AccessFlow governs Redis through the same submit, analyse, approve, execute pipeline as a SQL database, but the model underneath is genuinely different: Redis speaks commands rather than queries, so governance is a strict allow-list rather than a parser, and row-level security has no meaning at all — which AccessFlow handles by refusing, not by ignoring.

Family
Key-value
Query language
redis-cli commands
Runs as
Engine plugin (SHA-256 pinned)
Default port
6379
Default SSL mode
DISABLE
Install
One-click from the connector catalog

How AccessFlow connects

It is an engine plugin rather than an in-process JDBC datasource: a standalone shaded JAR, pinned in the connector catalog by URL and SHA-256, downloaded on first use, hash-verified, and loaded into an isolated classloader. If the hash does not match, it does not load. In an air-gapped install the JAR can be pre-seeded into the driver cache and the runtime told never to reach the network.

One pooled client is cached per datasource. The connection is built from host and port (6379 by default), the scheme chosen by SSL mode, the optional ACL username, and the database name field used as the numeric database index. The password is AES-256-GCM encrypted at rest and decrypted only when the client is built.

What AccessFlow understands

A submission is a single redis-cli command, tokenized quote-aware. Multi-line and multi-command input is rejected — the key-value analogue of the SQL multi-statement ban. The command is then matched against a strict allow-list and classified: reads like GET, MGET, HGETALL, SCAN, TTL, LRANGE, SMEMBERS and ZRANGE are SELECT; conditional creates like SETNX are INSERT; mutators like SET, HSET, LPUSH, EXPIRE and INCR are UPDATE; removals like DEL, UNLINK, HDEL and LPOP are DELETE; and FLUSHDB is DDL.

Grants target a key prefix — the text before the first colon, so orders:2026:11 belongs to orders. Multi-key and two-key commands contribute every operand's prefix, and SCAN and KEYS derive theirs from the match pattern. A command with no derivable prefix contributes nothing, and the host treats an empty set as no tables detected, which denies rather than allows.

What it refuses

Anything outside the allow-list is refused. Beyond that, a dedicated forbidden set is rejected up front with its own message: server-side scripting (EVAL, EVALSHA, SCRIPT, FUNCTION, FCALL); blast-radius and admin commands (CONFIG, FLUSHALL, SHUTDOWN, DEBUG, MIGRATE, CLUSTER, ACL, MODULE, CLIENT, SWAPDB); replication and persistence commands; multi-command transactions; blocking reads; pub/sub; and commands that mutate connection state such as SELECT and MOVE.

Row-level security fails closed, on purpose

A row-level predicate has no meaning in a key-value store — there are no rows to filter. Rather than silently ignoring a policy, which would hand the user unfiltered access to keys an administrator believed were restricted, AccessFlow refuses the command with HTTP 422 when a policy targets a referenced key prefix. A policy targeting a prefix the command does not touch is simply not relevant and is ignored.

Field masking does work. A hash read exposes its field names as columns, so a rule on session.token redacts that field; strings, lists, sets and sorted sets expose a synthetic value column that a whole-column rule can mask.

What the rewrite actually does

Redis is the engine where the honest answer is a refusal. A key-value store has no rows to filter, so a policy cannot be applied — and pretending otherwise would hand the caller unfiltered access to keys an administrator believed were restricted:

redis-cli
# submitted, with a row-security policy on the "orders" key prefix
HGETALL orders:2026:11

# result
HTTP 422 — row-level security is not supported for Redis

# field masking, however, does apply
HGETALL session:8f21   ->   { user: "ada", token: "********" }

A policy targeting a prefix the command does not touch is simply not relevant and is ignored. It is only a policy that would have applied which turns into a refusal.

Introspection

The connection test opens a short-lived client and pings. Introspection samples keys with SCAN — never KEYS, which would block the server — groups them by prefix into pseudo-tables, and reports hash field names or a synthetic value column typed by the Redis value type. That view feeds the ER diagram and the AI analyzer's prompt context like any relational schema. There are no primary or foreign keys.