SeliseBlocks.Data.Authorization 10.0.0.3-alpha

SeliseBlocks.Data.Authorization

An authorization gateway for MongoDB data access. Every read and write goes through one IDataAccessGateway that resolves the acting user, checks the entity rules, the field policy and the row ACL of the addressed resource, executes the operation against that tenant's database and audits the outcome. A denial is a DataAccessDeniedException with a DenyCode; it is never retried unrestricted.

Two packages:

Package What it is Depends on
SeliseBlocks.Data.Authorization the engine: policy, ACL, capabilities, analysis, audit MongoDB.Driver, Newtonsoft.Json
SeliseBlocks.Data.Authorization.Genesis hosting it in a Genesis Blocks service: tenant routing, the policy switch, stamping, DI the engine + Genesis framework

The engine references no product and no host framework. The Genesis package is the only one that knows about Blocks, and a different platform needs its own adapter rather than changes to the engine.

Integrating it

The host provides two framework services, which an ordinary Genesis service already has: ISecurityContextProvider (who is calling) and IBlocksMongoDbDataContextProvider (which database a tenant maps to). Then one call, plus content:

services.AddDataAccess(configuration, new DataAccessContent
{
    ResourceRegistry   = sp => /* your manifest */,
    Capabilities       = sp => /* your capability registry */,
    StandardSchemas    = sp => EntitySchemaBuilder.Default,
    IdentitySchemas    = sp => /* schemas with your role-bearing fields protected */,
    IdentityEntityKeys = new[] { "User" },
    PolicyStoreGrant   = "policy.store"
});

Everything else has a default:

  • Who the caller is. SecurityContextActorProvider reads the validated Genesis security context and uses its user, tenant and roles. A host whose effective roles live in a user document registers its own IActorProvider before this call and the default steps aside.
  • Person to user. NoPersonUserResolver resolves none, which is right for a host with no such model.
  • Default ACL settings. NoAclSettingsSource returns none, so stamping grants the acting user.
  • Control grants. Read from the JSON file at DataAccess:ControlGrants:Path when the content passes no list.
  • Where the grants live. ControlGrantStoreOptions is read from DataAccess:ControlGrants, and every value has a default, so a host that configures none still starts on the compiled list.

Nothing else has to be registered. MinimalHostRegistrationTests pins exactly this: a container holding only those two services and the content above resolves a working IDataAccessGateway, with the policy switch in either position.

Configuring it

{
  "DataAccess": {
    "Policy":        { "Enabled": true,        // false waives the rules; refused in production
                       "AllowDisabledInProduction": false },  // true lets a production deployment mean it
    "Content":       { "ManifestPath": "policy/resource-policy-manifest.json",
                       "ManifestSha256": "<pin it in staging and production>",
                       "CapabilitiesPath": "policy/capabilities.json" },
    "ControlGrants": { "Path": "policy/control-grants.json",
                       "TenantId": "",          // set it to read the grants from a database instead
                       "SeedWhenEmpty": true },
    "MaxStaleness": "00:05:00",
    "PolicyLoadTimeout": "00:00:15",
    "RevocationInterval": "00:00:00"
  }
}

DataAccess:Policy:Enabled = false waives the entity rules, the field policy and the row ACL for an authenticated actor in their own tenant, for development. It never waives authentication, tenant isolation, the control resources or the audit.

In a production environment - one whose name is empty or starts with prod - the host refuses to start with the policy off, so that no single wrong value opens every row. A deployment that genuinely intends it sets DataAccess:Policy:AllowDisabledInProduction to true as well. Two keys rather than one, and the intent is then visible in the settings file to anyone reviewing it.

Administering the control grants

With DataAccess:ControlGrants:TenantId set, the grant table lives in a collection and IControlGrantAdministration lets an administration UI read it and re-apply it without a restart:

admin.Current();   // the grants live in this process right now, as copies
admin.Apply();     // re-read the store, validate it whole, swap it in or refuse

Two rules make that safe, and neither is optional:

  • A stored row may narrow a declared grant; it may not invent one. The host's compiled list is the authority on which grants may exist, exactly as a capability catalogue is. A control grant reads a control resource with neither row ACL nor field policy, so being able to add a row would be being able to grant unfiltered read over identity, policy or secret collections by writing to a collection. Adding an authority stays a code change.
  • Applying is all or nothing. The replacement is validated and bound completely before anything is swapped, so a table with one bad row leaves the running one untouched and Applied comes back false with the reason. A half-applied authority table would fail later, somewhere unrelated.

Applying is a deliberate call rather than a background poll: an authority table that changes under a running process with nothing marking the moment is what an audit cannot reconstruct afterwards. Removing a row is how a grant is turned off, and the result lists what that left Absent.

What stays the host's

The package authorizes operations on your entities; it cannot know what they are. You supply the resource manifest (which entities exist, where they are stored, whether they carry a row ACL), the capability definitions, and the control grants. All three are files, so they are deployed and reviewed rather than compiled - pin them with *Sha256 where a deployment must not be editable.

What it gives you back

  • IDataAccessGateway - every authorized read and write.
  • IControlPlane - the grant-scoped bootstrap path a host builds its own directories on ("the users of this tenant", "the roles of this feature"). Each call names one control grant and is audited; the implementation stays internal, so nothing a consumer holds can open a database by itself.
  • IIdentityRouting - which resources the identity executor handles, so a misspelled entity key in IdentityEntityKeys is visible rather than silently routing role-bearing rows to the standard one.
  • IServiceAccess / ICapabilityScopeAccessor - entering a named capability, and observing which one is active. While the policy is disabled every operation is attributed to DataAccessPolicyOptions.DisabledCapabilityName, which the audit records.
  • IAclMaintenance - the audited way to change the ACL of an existing row. Ordinary writes may not set the ACL arrays; that is what makes them trustworthy.
  • IControlGrantAdministration - reading the live control grant table and re-applying it from the store, for an administration UI. See below.

Status

10.0.0.3-alpha. The leading 10 is the .NET version, matching SeliseBlocks.Genesis.Framework 10.0.0.x.

The test suite ships with the source: 1821 tests, all passing, covering the ACL predicate and stamping, the field and entity analysis, the policy store and snapshots, the schema builder, capabilities, the control plane and the read/write gateway. Most of them run against a real MongoDB; point SECFIX_MONGO_URI at one (the default is mongodb://localhost:27555/?directConnection=true, a single-node replica set).

dotnet test

The tooling that generates a resource manifest by scanning a codebase is not part of these packages; the manifest is an input you supply as a file.

Showing the top 20 packages that depend on SeliseBlocks.Data.Authorization.

Packages Downloads
SeliseBlocks.Data.Authorization.Genesis
Hosts SeliseBlocks.Data.Authorization inside a Genesis Blocks service: tenant database routing, the policy switch, ACL stamping, index maintenance and the dependency-injection composition root.
3
SeliseBlocks.Data.Authorization.Genesis
Hosts SeliseBlocks.Data.Authorization inside a Genesis Blocks service: tenant database routing, the policy switch, ACL stamping, index maintenance and the dependency-injection composition root.
1

.NET 10.0

Version Downloads Last updated
10.0.0.4-alpha 3 10/31/2026
10.0.0.3-alpha 1 10/31/2026
10.0.0.2-alpha 1 10/31/2026
10.0.0.1-alpha 1 10/31/2026