This exact action, this exact record.
B5 is the layer the platform is named for. Authorization is activity-based, data-aware, and convention-driven — an explicit permit is required for this exact action on this exact record, with implied permissions derived by convention rather than hand-maintained. Nothing reaches your business logic without a data-element-level decision behind it.
1. Why authorize at the record
Most authorization stops at the endpoint: can this role call this route? That leaves the hardest question — can this caller touch this object? — to scattered, hand-written checks that drift and get forgotten. B5 pushes the decision down to the record, so the permit covers the exact action and the exact data, not merely the door the request came through.
2. The ADA model
B5’s model is activity-based, data-aware, convention-driven. Activity-based: permits are expressed over actions, not just resources. Data-aware: the decision sees the specific record and its relationships, so ownership and scope are part of the check. Convention-driven: the mapping from action to required permit follows a consistent convention, so coverage is systematic rather than dependent on a developer remembering to add a guard.
Because the convention is uniform, an unguarded action is a visible defect, not a silent hole — the deny-by-default default means “no permit defined” resolves to “denied.”
3. Implied permissions by convention
Hand-maintaining a permission per action does not scale and invites gaps. B5 derives implied permissions from the activity and data convention, so common cases are covered automatically and only genuine exceptions need explicit policy. The externalization path — an AuthZEN PEP to OpenFGA or Cedar/Cerbos — preserves these semantics while moving the decision to a dedicated engine.
4. The calling convention
Actions declare the permit they require; the pipeline enforces it against the specific record.
// B5 — data-element-level, activity-based authorization
[Permission("account:transact", Scope.Record)]
public async Task<Result> Transfer(TransferRequest req) {
// reached only with an explicit permit for THIS account record
}5. What an attacker actually gets
An authenticated caller probing for objects they do not own is denied per data element, not merely per route — the classic IDOR/BOLA pattern has nowhere to land. An action shipped without a defined permit is denied by default rather than left open. The deepest, most valuable operations are exactly the ones with the tightest, data-aware checks.
6. Where this lands in an audit
B5 is the evidence for least-privilege authorization and object-level access control (OWASP API1/API5; NIST CSF PR.AA; SOC 2 CC6.1, CC6.3; ISO 27001 A.5.15, A.8.3). It is the clearest demonstration of Never Trust: every data element, every action, an explicit permit.
Next: Co-Hosted, One Host — legacy and new under one contract →