Engines and access methods
System9 does not ask you to pick a database. One governed substrate carries several engine families, and each is reachable over a protocol your existing clients already speak. The point is not the variety. The point is that the governance is the same on every one of them, so choosing a different access method never means choosing a different policy.
The engine families
| Family | What it holds | Reached by |
|---|---|---|
| Relational | Tables, views, materialized views | SQL, the PostgreSQL wire, Arrow Flight SQL, GraphQL |
| Analytical | Columnar scans over the same assets | SQL, routed by workload class |
| Lakehouse | Iceberg and Delta tables at format parity, read zero-copy over object storage | Iceberg REST catalog, Delta Sharing, SQL |
| Property graph | Labelled vertices and typed edges | GQL / openCypher, Gremlin |
| Document | Collections with filters, sort, skip, limit, distinct, bulk operations | Document API |
| Vector | Upsert, batch upsert, similarity search | Vector API, and vector SQL functions |
| Time-series | Path registration, range and latest queries, aggregation, pre-computed rollups | Time-series API, PromQL |
| Search | Full-text and faceted indexes over catalog assets | Search API |
| Structures | 34 structure types including a full CRDT family | RESP2/RESP3, so redis-cli and the standard client libraries connect directly |
| Streams | Named, workspace-scoped real-time streams | Streaming SQL, KQL, PromQL, complex event processing |
| Object | Namespaced, versioned, erasure-coded objects | S3 with SigV4, WebHDFS, SFTP, native REST and gRPC |
| Messaging | Durable subjects with consumer groups and cursors | Native pub/sub over HTTP and gRPC, MQTT 5.0, AMQP |
The rule that makes this safe
A wide protocol surface is usually a wide attack surface, because each protocol tends to arrive with its own authentication and its own idea of what a caller may see. Here there is one rule, and it is the single most load-bearing claim in the data platform:
Every access method re-enters the same authorizer, and the policy is already in the plan.
Row filters and column masks are compiled once and pushed into each engine as native predicates and projections across seven engine types, rather than being applied by a catalog service that can be bypassed by reaching the engine another way.
So when a Postgres client connects directly instead of using the console, the
credential resolves to a real directory entity with real grants, the workspace
scope binds, and the predicates are already in the query plan. When a redis-cli
session connects to the structure engine, the connection is deny-by-default until
it authenticates and every command re-enters the same engine-boundary authorizer
the HTTP surface uses.
The wire is not a bypass. That sentence is the reason the protocol list above is a feature rather than a liability.
The question to ask any platform
If someone connects a Postgres client directly to your platform instead of using your console, what enforces the policy?
On most platforms the honest answer is "the catalog, if they go through it."
Where the enforcement appears
| Path | How it is enforced |
|---|---|
| SQL and analytical queries | Predicates injected, columns projected out |
| Graph, document, key-value, search, stream, vector | Engine-native filters through per-engine adapters |
| The PostgreSQL wire and the RESP server | The wire re-enters the same engine-boundary authorizer, deny-by-default before authentication |
| Notebook and query kernels | Row and column security enforced inside the kernel |
| User-defined functions | Masks bound as functions, and the function's isolation tier is raised by the data's classification |
| ETL transforms | The same function invoker contract, with classification carried on the record |
| Object storage | Classification is a namespace property with a database constraint, enforced in the data path |
| Messaging | Subject-level grants, a per-workspace audit chain, payload encryption |
| Clean rooms | Room policy intersected most-restrictive-wins with any bound agent, function, or pipeline at execution |
| The edge | Local policy evaluation with no round trip |
Choosing an access method
A short heuristic, since the list is long:
- Your data is relational and your tool speaks SQL. Use the PostgreSQL wire. Existing BI and JDBC clients connect with no proprietary driver.
- Your tool speaks Arrow. Use Arrow Flight SQL for columnar streaming with multi-cell fan-out.
- Another engine should read your tables without a copy. Publish in Iceberg or Delta and let it read over the open catalog protocol.
- The natural shape is a counter, a queue, a set, a leaderboard, or a sketch. Use Structures and keep your Redis clients.
- The question is about relationships. Use the property graph over GQL, including the virtual graph projected over lakehouse tables with no copy.
- The question is "what does this mean". Use the vector engine, with embeddings produced by a local provider.
- The data is arriving now. Use streams, with SQL, KQL, or PromQL over them.
- It is a file, not a row. Use object storage, and let file intelligence turn it into a catalog asset.
Related
- Governed reads, what attaches to a read on any of these.
- In-engine enforcement, the enforcement plane in full.
- Interfaces & APIs, the protocol reference.
- FluxDB, the database system these engine families run on.
- The database substrate, the cell-internal stores beneath all of this.