Skip to content

v3.0.0 — Field-level policies

Choose a tag to compare

@Sajadh92 Sajadh92 released this 14 Sep 11:32
· 139 commits to master since this release
bd65de5

DynamicWhere.ex 3.0 adds field-level policies: a layer that decides, per caller, what may be filtered, sorted, selected, grouped, aggregated and seen. Attributes carry the rules you ship; an optional store carries the rules you change at runtime.

It is entirely opt-in. A project with no policy attributes and no DwPolicy.Configure call behaves exactly as 2.1.5.

dotnet add package DynamicWhere.ex --version 3.0.0

Packages

Package What it is
DynamicWhere.ex The library, now with the policy layer, an in-memory rule store and an in-memory token vault
DynamicWhere.ex.Policies.EntityFrameworkCore New. Rules and tokens in your own database, through any EF Core provider
DynamicWhere.ex.Policies.Redis New. Rules and tokens in Redis, with changes reaching every instance through pub/sub
DynamicWhere.ex.Policies.AspNetCore New. Admin API, schema discovery, explain, simulate, health and audit

What's new

  • Access control. [DwDeny] and six named attributes across Where, Select, Order, Group, Aggregate and Segment; [DwOperators]; [DwEntity(RequirePolicy = true)].
  • Injection. [DwAlias], [DwForceWhere], [DwRequireWhere].
  • Transformation. [DwMask] with nine strategies — among them Hash, keyed HMAC-SHA256, and Tokenize, random tokens kept in a vault — plus [DwMutate], [DwDefault], [DwGeneralize], [DwTruncate] and [DwFormat]. Filtering and sorting still run against the real value in SQL; the transformation is applied to the result.
  • Precedence. Six levels, with attributes sealed by default.
  • Dynamic rules. An optional store with broad and narrow zones and three failure modes. The in-memory, Redis and EF Core stores all pass one conformance suite.
  • Admin surface. Mounts only with a named authorization policy — there is deliberately no default.
  • Configuration. The whole posture binds from IConfiguration, and an unrecognised key refuses to start.
  • Inference defences. The seven inference channels in the design's threat model are closed, including a k-anonymity floor on grouped summaries.

Before you turn it on

  • The group floor ships on, at 5. A guarded grouped summary suppresses groups of fewer than five rows. It cannot change an existing query, because only guarded queries are affected and those are new. MinGroupSize = 1 turns it off.
  • A mask does not stop sorting or filtering. Both run on the real value. Pair a mask with [DwNoOrder], and with [DwOperators] where comparisons could narrow the value down.
  • Neither Hash nor Tokenize hides equality. Both keep a column groupable and joinable, so equal values stay equal. A field that cannot accept that needs Fixed, Null or a denial.
  • Transforming values costs something. Gating is free, but rebuilding every value of a large result costs about 1.6× in time and 7× in allocations.

Compatibility

No breaking changes to the 2.x API. FilterResult<T> and SummaryResult each gain one nullable Policy property, null when a query was not guarded. Targets net6.0 and runs on .NET 6 through 10, with EF Core 6.0.22 or later.

Verified

The release workflow ran 1,660 tests on EF Core 8 and 1,184 on the EF Core 6.0.22 floor before it packed. The store and token-vault conformance suites run against real Redis and PostgreSQL.

Documentation: Policies · Use cases · Security · For AI agents

Pull request: #2