<p align="center">
<img src="./assets/banner.jpg" alt="OpenLatch — the execution control layer for enterprise AI agents" width="600" />
</p>
<h3 align="center">Greater control should enable greater autonomy.<br /><em>Dare to Let Go.</em></h3>
<p align="center">
<a href="https://github.com/OpenLatch/openlatch-client/actions/workflows/pr-checks.yml"><img src="https://github.com/OpenLatch/openlatch-client/actions/workflows/pr-checks.yml/badge.svg" alt="PR Checks" /></a>
<a href="https://www.npmjs.com/package/@openlatch/client"><img src="https://img.shields.io/npm/v/@openlatch/client.svg" alt="npm" /></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-blue.svg" alt="License" /></a>
<a href="https://openlatch.slack.com"><img src="https://img.shields.io/badge/Slack-join%20us-4A154B?logo=slack&logoColor=white" alt="Slack" /></a>
</p>
<p align="center">
<a href="https://openlatch.ai">Website</a> ·
<a href="https://openlatch.ai/docs/">Docs</a> ·
<a href="https://app.openlatch.ai">Dashboard</a> ·
<a href="https://openlatch.slack.com">Slack</a>
</p>
---
**[OpenLatch](https://openlatch.ai) is the execution control layer for enterprise AI agents.** It turns human intent into **Agent Intent Policies** across each agent's **Autonomy Zone** — security, safety, compliance, economics and quality — and makes a deterministic decision on every covered action before it executes: allow, ask, block or optimize.
This repository is its open-source **capture-and-enforce adapter**: the node that runs inside a coding agent's own execution path, evaluates every covered action against that agent's Autonomy Zone before it runs, and is what gives an agent the control level **Enforced**.
It plugs into the agent's native lifecycle hooks, decides locally and in-process, and forwards what it saw to the platform afterwards. The agent never waits on the network, and the verdict never depends on it.
## Quick start
```bash
npx @openlatch/client init # installs the client, detects your agents, wires their hooks
openlatch auth login # links this machine to your OpenLatch account (opens the browser)
claude # use your agent as usual — every tool call is now covered
```
`openlatch status` shows what is captured and enforced on this host. The [dashboard](https://app.openlatch.ai) shows the events and the verdicts. Full walkthrough: [Getting started](https://openlatch.ai/docs/getting-started/).
The installer runs on Node.js. macOS, Windows and Linux are supported.
## How it works
```
┌─────────────────────────────────────────────────────────────────┐
│ Developer's machine │
│ │
│ ┌──────────┐ hook event ┌──────────────────────────────┐ │
│ │ Coding │──────────────▶│ OpenLatch client │ │
│ │ agent │ │ (127.0.0.1) │ │
│ │ │ │ │ │
│ │ │ │ 1. Wrap in envelope │ │
│ │ │ │ 2. Evaluate resident │ │
│ │ │ │ policy in-process │ │
│ │ │ ◀─ verdict ──│ 3. Redact credentials │ │
│ └──────────┘ │ 4. Write local audit log │ │
│ │ 5. Batch → forward │────┼──▶ OpenLatch platform
│ │ ◀── policy bundle │◀───┼── (policies, analysis,
│ └──────────────────────────────┘ │ dashboard)
└─────────────────────────────────────────────────────────────────┘
```
- **Inside the agent, not a proxy in front of it.** The decision point is the agent's own hook lifecycle, so it sees the *action* rather than the traffic. Model calls additionally pass through a loopback listener, so cost and token usage are measured on the same host.
- **Local-authoritative.** The resident policy bundle is the authority, not a cache of one. Evaluation reads an in-memory handle and returns.
- **Fail-static, not fail-open.** A resident bundle keeps enforcing offline, forever. A failed refresh keeps the last known good.
- **Privacy-first.** Credentials are redacted locally before anything leaves the machine.
## What a verdict does
The verdict vocabulary is **Allow, Ask, Block or Optimize**. What this client can express today is narrower than the vocabulary, and this is the honest map of it. A verdict is deterministic because an explicit policy produced it.
| **Allow** | `allow`, `approve` | The action proceeds. `approve` is a user-confirmed allow |
| **Ask** | No wire variant — an `allow` / `approve` carrying `context` | Rendered to Claude Code as `permissionDecision: "ask"`, the alert as its reason. It **allows and flags**; it does not hold the agent waiting on a human. It prevents recurrence, not the first occurrence |
| **Block** | `deny` — the only action a `kind=command` rule may take | Reaches the agent as a native deny at `pre_tool_use`, naming the rule that produced it |
| **Optimize** | `kind=request` rules: `prefix_reorder`, `history_trim`, `prompt_edit` | **Measurement only.** Out of the box the boundary observes, reports what a transform *would* have saved, and forwards the original bytes |
Each rule runs in Monitor (record the match, allow the action) or Enforce (apply the verdict). Most restrictive wins across matching rules.
## Supported agents
| **Claude Code** | **Enforced** | macOS, Windows and Linux, across its 12 lifecycle hook events. Verdicts are delivered in the agent's own hook-output shape |
| Cursor · Windsurf · GitHub Copilot · Codex CLI · Gemini CLI · Cline · OpenClaw | Recognised | Their events store and attribute correctly; `init` cannot install their hooks yet |
Making an agent **Enforced** is a hook binding plus a verdict translator. Both are contributions we welcome — see [Contributing](#contributing).
## Behind a corporate proxy
`init` finds the route on its own: it probes what is already configured, then walks the OS's own proxy settings (Windows, macOS, GNOME), and only asks if none of them reach the platform. Kerberos/Negotiate uses the logged-on identity; a TLS-inspecting proxy needs only its root CA in `ca_bundle`. Proxy credentials go to the OS keychain, never to a file.
```bash
openlatch init --proxy http://proxy.corp:8080 --ca-bundle /etc/ssl/corp-root.pem
openlatch proxy test # walks the chain hop by hop and names the failing one
```
The hosts to open, every `[proxy]` key and every `OL-122x` code: [docs/egress.md](docs/egress.md).
## Configuration
`openlatch init` writes `~/.openlatch/config.toml`, and every key has an `OPENLATCH_*` environment variable that overrides it. Precedence is CLI flags → environment → `config.toml` → defaults. The full list is in [docs/configuration.md](docs/configuration.md).
## Documentation
| [openlatch.ai/docs](https://openlatch.ai/docs/) | Installation, getting started, how it works, FAQ, privacy |
| [docs/configuration.md](docs/configuration.md) | Environment variables, `config.toml`, what the daemon writes into the agent's config |
| [docs/egress.md](docs/egress.md) | Proxies, the hosts to open, Kerberos, troubleshooting codes |
| [docs/cli.md](docs/cli.md) | Command reference, health reports, exit codes |
| [docs/evaluate-protocol.md](docs/evaluate-protocol.md) | Evaluation process frames, caller-owned session state, errors and diagnostics |
| [CHANGELOG.md](CHANGELOG.md) | What changed in each release |
## Contributing
```bash
git clone https://github.com/OpenLatch/openlatch-client && cd openlatch-client
cargo build # Rust 1.88+, no other prerequisites
cargo test
```
Never run a development build against your own install: `openlatch init` rewires every live agent session on the host. The [Contributing Guide](.github/CONTRIBUTING.md) covers the sandbox that prevents it, the checks CI runs, Conventional Commits and the PR process; [AGENTS.md](AGENTS.md) states what the client does and what it deliberately does not.
Pick a [good first issue](https://github.com/OpenLatch/openlatch-client/labels/good%20first%20issue), or join us on [Slack](https://openlatch.slack.com).
## Security
- Report vulnerabilities to **security@openlatch.ai**; private vulnerability reporting is enabled on this repository
- Releases are built with SLSA provenance via GitHub Actions
- Full policy: [SECURITY.md](SECURITY.md)
## License
This client is licensed under [Apache-2.0](LICENSE). The OpenLatch platform — policy authoring, analysis and the dashboard — is a commercial product; see [openlatch.ai](https://openlatch.ai).