Cassandra access governance — every CQL statement reviewed before it runs
Last updated
AccessFlow governs Apache Cassandra through the same submit, analyse, approve, execute pipeline as a SQL database. The interesting part is row-level security: CQL can only filter on key columns without ALLOW FILTERING, and a governance proxy must never silently inject that — so the splice is key-aware and refuses anything it cannot express safely.
- Family
- Wide-column
- Query language
- CQL
- Runs as
- Engine plugin (SHA-256 pinned)
- Default port
9042- 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 native session is cached per datasource; the driver pools and load-balances internally. The contact point comes from host and port (9042 by default), and a local datacenter is a required field — the driver's default load-balancing policy mandates it, so it is a real part of the datasource rather than an optional tuning knob. The database name field selects the session's default keyspace.
SSL defaults to disabled, reflecting the common in-cluster deployment; enabling it encrypts without certificate verification, and the verifying modes use the JVM trust store.
What AccessFlow understands
A single CQL statement per submission, tokenized quote- and comment-aware. SELECT is a read; INSERT is an insert, including a lightweight transaction with IF NOT EXISTS; UPDATE is an update, including the conditional form; DELETE is a delete; and creating, altering or dropping a table, keyspace, index, type or materialized view — plus TRUNCATE — is DDL.
Grants target every referenced table, whether written bare and resolved against the datasource keyspace or fully qualified.
What it refuses
Two constructs fail closed with their own HTTP 422 messages. BEGIN … BATCH is refused as the CQL multi-statement carrier — a batch bundles operations that would need to be reviewed and audited as one. Creating or dropping a function or aggregate is refused as server-side code, the CQL counterpart of the ban every other engine has on running arbitrary logic inside the database.
Row-level security is key-aware, and fails closed
CQL can only filter on partition and clustering key columns unless a query carries ALLOW FILTERING — and a proxy that silently added that to satisfy a policy would turn a targeted read into a full cluster scan. AccessFlow does not add it.
Instead the applier resolves the target table's real key columns from live cluster metadata and splices a policy in only when its column is a key column and its operator is one CQL's WHERE can express — equality, IN, or a range comparison. Values are bound as named parameters, never concatenated.
A policy on a non-key column, an operator CQL has no form for (there is no not-equals or not-in), or an empty value list is refused with HTTP 422 rather than executed unfiltered. An INSERT into a policied table is rejected outright, Cassandra inserts being upserts. Masking is applied after fetch by the shared masker.
What the rewrite actually does
This is where Cassandra differs from every other SQL-shaped engine. A policy on a key column splices cleanly; a policy on anything else is refused rather than made to work with ALLOW FILTERING:
-- submitted SELECT id, email FROM orders WHERE tenant_id = 'acme'; -- executed — region is a clustering key, so it splices SELECT id, email FROM orders WHERE tenant_id = 'acme' AND region = :af_rls_1; -- but a policy on a non-key column, e.g. orders.owner_email HTTP 422 — row-level security cannot be expressed for this statement
The alternative would be injecting ALLOW FILTERING to make the predicate legal, which would silently convert a targeted read into a full cluster scan. A governance proxy should not change the cost profile of your queries to satisfy its own policy engine.
Introspection
The connection test runs a trivial read against the local system table. Introspection reads the driver's cluster metadata, surfacing every non-system keyspace as a schema and its tables as tables, with partition and clustering columns flagged as the primary key — the same key-column source the row-security applier uses, so what you see in the ER diagram is exactly what the policy engine can act on. Wide-column schemas have no foreign keys.