Three questions, three layers.
Every guarded call passes through each layer in order. Any one of them can say no, and none of them defaults to yes.
keygate-policy
Do we permit this action at all, right now?
keygate-core
Does this holder still hold the capability?
circuit-breaker
Has this resource exceeded its budget in this window?
Four contracts, each with one job.
Kept separate on purpose: an incident response is one deny rule, not a bulk revocation, and deleting the rule restores exactly the state before it.
keygate-core
The capability registry. Issue, renew, revoke and check time-bound grants, with a two-step admin handover and a freeze switch.
keygate-policy
Allow and deny rules per resource and action, in front of a registry. Deny takes an action out of service without touching hundreds of grants.
keygate-circuit-breaker
Rolling-window budgets that latch closed on a breach and stay closed until an explicit reset. One exploit cannot keep draining in small steps.
keygate-multisig
m-of-n administration. Relays any encoded call once quorum approves, so the registry's admin key is never held by one person.
Built around how Soroban actually behaves.
Every rule below was verified against the real Soroban host in CI, not just the mocked one.
- A breach is a value, not an error. A failed call loses its own writes, so the breaker reports
Outcome::Breachedand keeps the latch. - No self-re-entry. A contract cannot call itself, so owner rotation is applied inside the multisig's
execute. - Lazy windows, lazy expiry. No cron job: windows roll forward on first use, so an idle resource costs nothing.
Missing means no.
An unconfigured resource, a missing grant or a paused registry rejects. The server mirrors this: if it can't prove yes, it answers no.
Tripping is sticky.
Time passing and raising the limit do not reopen a tripped breaker. Only an admin reset does.
Admin through quorum.
Route every admin action through the multisig, so freezing issuance or repointing a policy takes m signatures.
Contracts, server and SDK.
Contracts hold capabilities on-chain. The server mirrors them from contract events and answers queries. The client builds the calls and checks server decisions before trusting them.
keygate-contracts
Registry, policy, latching circuit breaker and multisig relay, as a Soroban workspace with release wasm built in CI.
↗keygate-server
A read-only decision server. Mirrors capabilities from Soroban events and answers authorisation queries, failing closed.
↗keygate-client
The TypeScript SDK: build contract calls, sign authorisations, decode contract errors, and verify a server decision.
Help build it.
Keygate is open source and part of the Drips Wave program. Pick up any issue labelled good first issue or help wanted in the repos above.