# khive-gate
**ADR:** [ADR-018 Authorization Gate](../../docs/adr/ADR-018-authorization-gate.md)
Pluggable authorization gate for verb dispatch in the khive runtime.
## Purpose
The runtime consults a `Gate` implementation before dispatching each verb.
The default `AllowAllGate` is permissive (suitable for personal/local deployments).
For production policy enforcement, plug a Rego-backed or capability-backed implementation
into `RuntimeConfig.gate`.
## Wire shapes
### `GateRequest` (input to every gate check)
| `actor` | `ActorRef` | Caller identity (`kind` + `id`) |
| `namespace` | `Namespace` | Validated namespace from `khive-types` |
| `verb` | `String` | Verb being dispatched |
| `args` | `serde_json::Value` | Verb arguments as arbitrary JSON |
| `context` | `GateContext` | Optional session, timestamp, source |
### `GateDecision` (output)
Tagged by `"decision"` field: `"allow"` or `"deny"`.
- `Allow` carries an optional `obligations` array.
- `Deny` carries a `reason` string.
### `AuditEvent` (ADR-018 audit record)
Emitted once per gate consultation. Fields include `actor`, `namespace`, `verb`,
`decision`, `deny_reason`, `obligations`, `gate_impl`, `session_id`, and `timestamp`.
Field names are a **stable public contract** — renaming requires a new ADR.
## Quick start
```rust
use std::sync::Arc;
use khive_gate::{AllowAllGate, Gate, GateRef, GateRequest, ActorRef};
use khive_types::Namespace;
use serde_json::json;
let gate: GateRef = Arc::new(AllowAllGate);
let req = GateRequest::new(
ActorRef::anonymous(),
Namespace::local(),
"search",
json!({"query": "LoRA"}),
);
assert!(gate.check(&req).unwrap().is_allow());
```
## Implementing a custom gate
```rust
use khive_gate::{Gate, GateDecision, GateError, GateRequest};
#[derive(Debug)]
struct MyGate;
impl Gate for MyGate {
fn check(&self, req: &GateRequest) -> Result<GateDecision, GateError> {
if req.verb == "delete" {
Ok(GateDecision::deny("delete is not permitted"))
} else {
Ok(GateDecision::allow())
}
}
fn impl_name(&self) -> &'static str {
"MyGate"
}
}
```
## Obligations
An `Allow` decision may carry obligations the dispatch layer should honour:
- `Audit { tag }` — persisted as part of the audit event when an `EventStore` is wired.
- `RateLimit { window_secs, max }` — not enforced in v0; recorded only.
- `Custom { value }` — policy-specific arbitrary JSON payload.
## Known gate implementations
| `khive-gate` | Apache-2.0 | `AllowAllGate` — permissive local default |
| `khive-gate-rego` | Apache-2.0 | Rego-backed via `regorus` (ADR-018) |
| `khive-cloud` | BUSL | `LionGate<G>` — capability-witness enforcement |