Data plane

Access control that compiles to native where it can.

The AccessModel is an AST — ReadFilter, InsertCheck, UpdateTargetFilter, UpdateResultCheck, DeleteFilter, FieldRules, RelationshipRules, Bypass. Vadyl reads provider SecurityCapabilities, compiles to native RLS where supported, falls back to runtime predicate evaluation where not. The policy is the same. The outcome is the same. The execution path is whatever the provider permits.

One AST, three enforcement modes

Native, runtime, hybrid. Vadyl picks per facet.

Native enforcement

PostgreSQL row-level security, SQL Server security predicates, native session context. Vadyl compiles row filters into the provider's enforcement layer — zero runtime cost on the read path.

Runtime enforcement

MongoDB, Redis, providers without native RLS — Vadyl injects the resolved predicate into the query AST before it reaches the provider. SecurityPredicateResolver replaces scope-dependent nodes with concrete literals upstream.

Hybrid mode

Some facets land natively (read filters), others stay runtime (field masking with redaction). AccessPlanBuilder reduces capabilities + AccessModel into per-facet enforcement modes.

Field masks

Omit / Null / Redacted. FieldProjectionBuilder applies post-evaluation. Combined with CanRead via OR(CanRead, NOT(MaskWhen)) — masking only when read is denied AND mask condition holds.

Relationship rules

Cross-relation invariants. The order's customer must be read-allowed before the order is read. Cascading access checks across relation expansion, capability-aware.

Bypass auditing

FullBypass / ReadBypass / WriteBypass conditions are typed. Every bypass invocation lands in AccessEnforcementDiagnostics.Bypasses — auditable, reviewable, alarmable.

Auth-aware predicates

Resolve before render. Document providers get the same semantics.

HasRole, HasClaim, InContextSet, ContextValue, AuthStrengthAtLeast, AuthenticatedVia, SubjectTypeIs, SessionAgeLt — auth-aware BoolExpr nodes. SecurityPredicateResolver walks the tree and replaces scope-dependent nodes with concrete BoolLiteral / Literal before the predicate reaches a renderer that can't handle them natively.

Anti-pattern #45 codified: scope-dependent BoolExpr nodes never reach a document or KV provider unresolved. The runtime predicate resolver handles the gap so MongoDB / Redis / Cassandra get the same semantics PostgreSQL gets natively.

6
AccessModel facets

Read / Insert / UpdateTarget / UpdateResult / Delete / Field

Per-facet
Enforcement mode

Native / Runtime / Hybrid / Inactive

Audit
Every bypass

Typed, surfaced, alarmable

Same
Outcome

Across every storage model

Express access policy once.

Vadyl picks the enforcement mode per provider, per facet. The policy is the same across Postgres, Mongo, Redis, Neo4j, Cassandra. Your code does not branch.