Skip to main content

Crate corium_authz

Crate corium_authz 

Source
Expand description

Self-hosted relationship-based authorization (ReBAC) over a Corium database.

corium-protocol’s Authorizer seam was built so a deployment could point authorization at an external policy service. This crate is the answer for deployments that would rather not run one: Corium’s own data model — entities, reference attributes, immutable history — is a good fit for the tuple shape ReBAC needs, so the policy lives in an ordinary Corium database and the check is a bounded in-memory graph walk over a compiled snapshot of it.

Check(subject, action, object, database, at_authz_t)
  action  -> required relation(s)          (permission map)
  subject --relation/derived--> object     (tuples + rewrites)
  optional binding -> ViewFilter           (bindings + views)

§The pieces

  • schema — the reserved attributes of the authz database, and the EDN an operator installs to create one.
  • model — the policy vocabulary: objects, tuples, permissions, rewrites, views, bindings. Relation names are data, not Rust enums.
  • policy::Policy — an immutable compiled snapshot keyed by the authz database’s basis t, with the indexes a check needs.
  • eval — the bounded, cycle-safe relationship search.
  • subject — how a request Principal becomes the subjects the search starts from.
  • source::PolicySource — where snapshots come from; each surface supplies the database value it already holds.
  • SystemDbAuthorizer — the Authorizer itself: snapshot caching, consistency, result caching, fail-closed behaviour, break-glass, audit.
  • bootstrap — building an authz database in process, and the EDN an operator’s grant/revoke sends to a real one.

§Fail closed

Every failure that leaves the authorizer without a policy — a missing authz database, an unreadable snapshot, a policy that does not compile — denies. The one exception is an explicit BreakGlass configuration for operator recovery, and it is audited at warn every time it grants. A snapshot that stops compiling never replaces the last good one either: the process keeps deciding from the policy it already has.

§Example

use std::sync::Arc;

use corium_authz::{SystemDbAuthorizer, bootstrap, source::MemoryPolicySource};
use corium_protocol::authz::{Access, Action, Authorizer, Decision, Principal};

let db = bootstrap::policy_db(r#"
[{:db/id "read" :authz.permission/object-type "database"
  :authz.permission/action "read" :authz.permission/relation ["viewer"]}
 {:db/id "t1" :authz.tuple/subject "group:eng#member"
  :authz.tuple/relation "viewer" :authz.tuple/object "database:music"}
 {:db/id "t2" :authz.tuple/subject "user:alice"
  :authz.tuple/relation "member" :authz.tuple/object "group:eng"}]
"#).expect("policy compiles");

let authorizer = SystemDbAuthorizer::new(Arc::new(MemoryPolicySource::new("authz", db)));
let alice = Principal::new("oidc", "alice");
let bob = Principal::new("oidc", "bob");

assert!(matches!(
    authorizer.authorize(&alice, &Access::on(Action::Query, "music")).await,
    Decision::Allow
));
assert!(matches!(
    authorizer.authorize(&bob, &Access::on(Action::Query, "music")).await,
    Decision::Deny(_)
));

Re-exports§

pub use authorizer::AuthzConfig;
pub use authorizer::AuthzDecision;
pub use authorizer::BreakGlass;
pub use authorizer::Consistency;
pub use authorizer::RefreshError;
pub use authorizer::SystemDbAuthorizer;
pub use eval::Denial;
pub use eval::Limits;
pub use eval::Match;
pub use eval::Outcome;
pub use model::ObjectRef;
pub use model::SubjectRef;
pub use policy::Policy;
pub use policy::PolicyError;
pub use policy::PolicyStats;
pub use schema::DEFAULT_AUTHZ_DB;
pub use source::MemoryPolicySource;
pub use source::PolicySource;
pub use source::SourceError;
pub use subject::SubjectMapping;

Modules§

audit
Audit events for authorization decisions.
authorizer
SystemDbAuthorizer: the Authorizer that answers from Corium’s own authorization database.
bootstrap
Building and editing an authorization database.
eval
The bounded relationship search that answers one check.
model
The policy vocabulary: object references, relationship tuples, permission maps, rewrite rules, and view bindings.
policy
Compiling a snapshot of the authz database into an immutable policy value.
schema
The reserved schema of the authorization system database.
source
Where a compiled policy comes from: a snapshot of the authz database.
subject
Mapping a request Principal onto the subjects a check searches from.
view
ViewFilter implementations built from policy data, and the conservative rule for combining the filters of several successful authorization paths.