khive-gate 0.5.0

Pluggable authorization gate trait + default AllowAllGate impl for khive verb dispatch.
Documentation

khive-gate

Pluggable authorization gate trait for khive verb dispatch, with a permissive default implementation.

The runtime consults a [Gate] before dispatching each verb. This crate defines the trait, the wire types the gate sees and returns, and AllowAllGate — the permissive default installed in RuntimeConfig when no other gate is configured.

Usage

use khive_gate::{ActorRef, AllowAllGate, Gate, GateRequest};
use khive_types::Namespace;
use serde_json::json;

let gate = AllowAllGate;
let req = GateRequest::new(
    ActorRef::anonymous(),
    Namespace::local(),
    "search",
    json!({ "kind": "entity", "query": "LoRA" }),
);
let decision = gate.check(&req).unwrap();
assert!(decision.is_allow());

GateRequest::try_new / ActorRef::try_new / GateDecision::try_deny return Result and reject empty verb, actor.kind, actor.id, or deny reason fields; the panicking new / deny variants call the same validation and expect() the result. Obligation::rate_limit / try_rate_limit validate window_secs and max are both non-zero.

Contract

  • Gate::check(&GateRequest) -> Result<GateDecision, GateError> is the only method a backend must implement. Gate::impl_name() defaults to the type name and is surfaced in audit events so multiple gate implementations (including wrappers) are distinguishable without inspecting the type.
  • GateDecision::Allow { obligations } carries zero or more Obligation values (Audit, RateLimit, Custom) the runtime records on dispatch. GateDecision::Deny { reason } aborts dispatch — deny is authoritative and requires a non-empty reason.
  • AuditEvent::from_check builds the structured audit record (actor, namespace, verb, decision, obligations, gate_impl, session_id) emitted once per gate consultation. Its JSON projection is a stable public contract — field names don't change without a new ADR.
  • All wire types (ActorRef, GateRequest, GateDecision, Obligation) validate their invariants both at construction (try_new / try_* constructors) and at deserialization (custom Deserialize via a private TryFrom<Raw*> shape), so a policy engine handing back malformed JSON fails the same way a caller building the struct directly would.

Where this sits

khive-gate sits below khive-runtime, which holds the RuntimeConfig.gate: GateRef field consulted before every verb dispatch and defaults it to AllowAllGate. It has no dependency on any other khive crate beyond khive-types.

  • khive-gate (Apache-2.0) — this crate; the trait, wire types, and permissive default.
  • khive-gate-rego (Apache-2.0) — the OSS reference Rego backend (RegoGate), installed in place of AllowAllGate when a deployment needs real policy enforcement.

Governed by ADR-018.

License

Apache-2.0.