Metadata-Version: 2.4
Name: kyvvu-claude
Version: 0.1.0
Summary: Kyvvu compliance integration for Claude Code — policy enforcement via hooks
Author-email: "Kyvvu B.V." <info@kyvvu.com>
License: Copyright 2026 Kyvvu B.V.
        
        Licensed under the Apache License, Version 2.0 (the "License");
        you may not use this file except in compliance with the License.
        You may obtain a copy of the License at
        
        http://www.apache.org/licenses/LICENSE-2.0
        
        Unless required by applicable law or agreed to in writing, software
        distributed under the License is distributed on an "AS IS" BASIS,
        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        See the License for the specific language governing permissions and
        limitations under the License.
        
        This license applies only to the contents of the kyvvu-claude/ directory
        of the Kyvvu monorepo. Other directories in this monorepo are governed
        by their own LICENSE files.
        
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: kyvvu-engine<1.0.0,>=0.6.0
Requires-Dist: httpx>=0.27
Requires-Dist: typer>=0.12
Requires-Dist: rich>=13
Provides-Extra: dev
Requires-Dist: pytest>=7.4.0; extra == "dev"
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Dynamic: license-file

# kyvvu-claude

Kyvvu compliance integration for Claude Code. Evaluates every tool call against [Kyvvu](https://kyvvu.com) policies before execution via Claude Code's native hook system, and logs all tool calls as an immutable audit trail.

## Installation

```bash
pip install kyvvu-claude
```

Requires Python 3.10+ and macOS or Linux.

## Getting started

### 1. Create a Kyvvu account

Sign up at [platform.kyvvu.com](https://platform.kyvvu.com) and create an API key from your organization settings. The API key starts with `KvKey-`.

### 2. Initialize kyvvu-claude

```bash
kyvvu-claude init
```

This interactive wizard will:
- Connect to the Kyvvu API (defaults to `https://platform.kyvvu.com`)
- Register your Claude Code instance as a Kyvvu agent
- Fetch policies assigned to your agent
- Install hooks into Claude Code's `~/.claude/settings.json`

### 3. Start using Claude Code

That's it. All Claude Code tool calls are now monitored. Open the [Kyvvu dashboard](https://platform.kyvvu.com) to see your agent's behavioral traces.

### 4. (Optional) Assign policies

In the Kyvvu dashboard, assign a manifest to your Claude Code agent. We recommend starting with the **Claude Code Safety** manifest (`manifests/developer/claude-code-safety.yaml`) which protects against:

- Credential exfiltration (blocks Bash after reading `.env`, `.pem`, `.key` files)
- Destructive commands (`git push --force`, `rm -rf /`, `git reset --hard`)
- Scope escape (writes to `/etc`, `~/.ssh`, `~/.aws`)
- Runaway loops (max 50 Bash calls, max 10 consecutive)
- PII in commands (SSN, credit card patterns)

## How it works

kyvvu-claude uses Claude Code's [hook system](https://docs.claude.ai/en/docs/hooks). Each hook invocation is a fresh process that reads JSON from stdin and writes JSON to stdout.

```
Claude Code                          kyvvu-claude
    |                                     |
    +-- SessionStart --stdin JSON--->  Register task, fetch policies from API
    |                                  Return status message
    |
    +-- PreToolUse ----stdin JSON--->  Map tool -> Kyvvu Behavior
    |                                  Evaluate policies (local, <50ms)
    |                                  Block or allow
    |
    +-- PostToolUse ---stdin JSON--->  Record completed step in session history
    |                                  (for path-dependent rules)
    |
    +-- SessionEnd ----stdin JSON--->  Flush audit trail to API
                                       Clean up session
```

Policy evaluation is fully local via [kyvvu-engine](https://pypi.org/project/kyvvu-engine/) — no network I/O on the hot path. Policies are fetched from the API at session start and cached on disk.

LLM calls are captured from Claude Code's session transcript (model name, token usage, proposed tools) and included in the behavioral trace.

## Enforcement behavior

When a policy blocks a tool call, kyvvu-claude returns `permissionDecision: "deny"` to Claude Code. This **denies the specific tool call** but **does not stop the agent**. Claude Code treats it like a permission denial — the model continues reasoning and may try alternative approaches.

This is intentional and consistent with Claude Code's hook design:

- The blocked step is recorded in the audit trail with `output.status = "blocked"`
- The policy name and severity are logged locally in `~/.kyvvu-claude/session.log`
- An incident is reported to the Kyvvu API
- The model receives the block reason and adapts

**Tainted-path policies** (credential exfiltration guard) are permanent within a session: after reading a secret file (`.env`, `.pem`, `.key`, etc.), ALL subsequent Bash commands and file reads outside the project are blocked. Use `/clear` in Claude Code to start a new session and reset the taint.

## Tool mapping

| Claude Code Tool | Step Type       | Verb  | Properties                        |
|-----------------|-----------------|-------|-----------------------------------|
| Bash            | step.exec       | -     | exec.command                      |
| Read            | step.resource   | GET   | target.host (file path)           |
| Write           | step.resource   | POST  | target.host (file path)           |
| Edit            | step.resource   | PATCH | target.host (file path)           |
| Glob            | step.resource   | GET   | target.host, target.pattern       |
| Grep            | step.resource   | GET   | target.host, target.pattern       |
| WebFetch        | step.resource   | GET   | target.host (URL)                 |
| WebSearch       | step.resource   | GET   | target.host (query)               |
| Agent           | step.self       | POST  | target.description                |
| NotebookEdit    | step.resource   | PATCH | target.host (notebook path)       |
| mcp__*          | step.resource   | *     | target.mcp_server, target.mcp_tool|
| (unknown)       | step.unknown    | -     | tool_input.*                      |

Files matching secret patterns (`.env`, `.pem`, `.key`, `.secret`, `.credentials`, `.pgpass`, `.netrc`) are automatically classified with `data.classification: secret` for tainted-path policies.

## Configuration

Stored at `~/.kyvvu-claude/config.json`:

| Field                          | Default                       | Description                                                      |
|-------------------------------|-------------------------------|------------------------------------------------------------------|
| api_url                       | https://platform.kyvvu.com    | Kyvvu API URL (policy fetch + agent registration)                |
| log_location                  | (empty = same as api_url)     | WHERE logs go. `stdout` = local. `none` = disabled. Can be a URL or file path. |
| log_format                    | kv                            | HOW logs are formatted: `kv` (Kyvvu API), `json`, or `otlp`     |
| api_key                       | (required)                    | API key from your Kyvvu organization (KvKey-...)                 |
| agent_id                      | (auto)                        | Assigned at registration                                         |
| enforce                       | false                         | `true` = block violations, `false` = monitor-only (log but allow) |
| environment                   | development                   | `development`, `staging`, or `production`                        |
| risk_classification           | limited                       | EU AI Act tier: `high`, `limited`, or `minimal`                  |
| flush_threshold               | 100                           | Flush logs after N steps (0 = only at session end)               |
| log_full_content              | false                         | Include full tool input/output in logs                           |

## Compatibility

kyvvu-claude uses Claude Code's hook system. It works with:

- **Claude Code CLI** (`claude` command)
- **VS Code extension** (Claude Code in VS Code)
- **JetBrains plugin** (Claude Code in IntelliJ/PyCharm)
- **GitHub Actions** (`anthropics/claude-code-action`) — reads `.claude/settings.json` from repo

**Not supported: Claude Desktop** (macOS/Windows app). Claude Desktop uses MCP servers instead of hooks. Hooks are runtime-invoked (the infrastructure calls them unconditionally on every tool use). MCP tools are model-invoked, so compliance enforcement cannot be guaranteed.

## CLI commands

| Command | Description |
|---------|-------------|
| `kyvvu-claude init` | Interactive setup: API connection, agent registration, hook installation |
| `kyvvu-claude install-hooks` | Install hooks into `~/.claude/settings.json` (also offered during init) |
| `kyvvu-claude uninstall-hooks` | Remove kyvvu-claude hooks from Claude Code settings |
| `kyvvu-claude status` | Show current configuration, policy count, active sessions |
| `kyvvu-claude policies` | Display cached policies as a table |
| `kyvvu-claude refresh` | Force policy refresh from the API |

## Known limitations

- **Tool blocks deny the tool call but do not stop the session** — Claude Code continues reasoning and may try alternatives. This is consistent with how Claude Code handles permission denials.
- **LLM calls are observed, not blocked** — captured from the session transcript (model name, token usage) but cannot be intercepted pre-flight since no hook fires before model inference.
- **LLM call capture may miss very short sessions** — the transcript is written asynchronously by Claude Code; in sessions under ~10 seconds, LLM calls may not appear in the trace.
- **Does not work with Claude Desktop** — only Claude Code CLI, IDE extensions, and GitHub Actions.
- **macOS and Linux only** — uses `fcntl.flock` for session file locking (no Windows support).

## Uninstalling

```bash
kyvvu-claude uninstall-hooks
pip uninstall kyvvu-claude
rm -rf ~/.kyvvu-claude
```
