# KnowMyAgents — install (pilot kit) See every AI agent touching your systems, without changing a single agent. This kit runs KMA's data plane on your machine from prebuilt images — no source code, no compilers. Works on macOS (Intel & Apple Silicon), Windows, and Linux. **You need:** Docker (Desktop on Mac/Windows), and an account on [console.knowmyagents.com](https://console.knowmyagents.com) (your KMA contact sets up your organization and invites you). ## Install (~10 minutes) **1. Get this folder** — your KMA contact sends it to you (three small files). **2. Get your two values** — sign in to the console → **Settings**: copy your *tenant ID*, and mint a *registration token* (shown once — copy it right away). Your machine will generate its own key and redeem the token; the key never leaves your machine. **3. Configure** — copy `.env.example` to `.env`, paste the two values, and replace the three `change-me` tokens with any long random strings. (Doors — the tools and model APIs KMA stands in front of — are added from the console, not here.) **4. Start** ``` docker compose up -d --wait ``` First run pulls the images. Then one security step: the console now shows this machine as a **pending registration** — approve it (Settings → Registrations). That approval is the "second lock": a stolen token alone can never attach a gateway to your organization. Sync starts by itself once approved. Your agents point at the **gateway** on `http://localhost:8129`; behind it, the **engine** (the doorman that checks rules and logs) runs inside, reachable only through the gateway — nothing on your machine can skip the door. **5. Start one program through KMA** — in the console, open **Programs → Add a program**: pick this machine, pick how the program runs (Docker Compose, `docker run`, on this machine, Kubernetes), name it, save. The console hands you what to run — a `kma.yml` overlay next to the program's own docker-compose.yml, a `docker run` line, a `kma run -- ` line, or a Kubernetes patch. **Nothing is added to the program itself.** Every place the program reaches then appears on the **Doors** page by itself, under the program's name, and the agents inside it show as anonymous **shadows** until you issue them passports (below) — the *same* door starts presenting each passport on that agent's calls, no re-pointing, no restart. A tool the program used to start as a local process? `kma tool -- ` runs it through KMA instead (see *Local tools* below). **6. Look at it** — two windows, deliberately different: - **Your local viewer — [http://localhost:8085](http://localhost:8085):** the full-detail record. Every call, complete envelopes, straight from the tamper-evident log on your machine. This detail never leaves your network. - **The cloud console — console.knowmyagents.com:** your whole fleet at a glance (inventory, shadow agents, policies, budgets) — fed by metadata only. Optional — ask Claude about your agents from inside Claude Code (inventory, activity, budgets, "why was that call denied?"). Read-only by design: ``` claude mcp add kma -- docker run -i --rm --network kma-net \ -e KMA_LOG_URL=http://kma-log:8084 \ -e KMA_PASSPORT_URL=http://kma-passport:8081 \ -e KMA_TENANT= \ ghcr.io/primethoughts/kma-mcp:0.9.6 ``` ### Ports (and what happens when one is taken) KMA publishes four host ports, every one overridable in `.env`: `KMA_VIEWER_PORT` (8085), `KMA_LOG_PORT` (8084, loopback-only), `KMA_PASSPORT_PORT` (8081, loopback-only), `KMA_GATEWAY_PORT` (8129, loopback-only; set `KMA_GATEWAY_BIND=0.0.0.0` or this machine's private IP in `.env` to let agents on other machines or in Kubernetes reach the door — only on a private network or behind a firewall). The one-line installer probes all four before starting anything: a port that is already taken (8081 is a popular one) automatically moves to the next free port, is recorded in `.env`, and is announced — with the name of the Docker container holding it, when there is one. To choose your own, preset the variable before installing (e.g. `KMA_PASSPORT_PORT=9081 curl -fsSL https://knowmyagents.com/install.sh | sh`) or edit `.env` and `docker compose up -d` again. ## Optional: client sensors on this machine (~2 minutes) The gateway meters what flows **through** it. The client sensors add what happens *beside* it: Claude Code sessions on this laptop, cloud sessions (via an account-synced plugin), and Claude Cowork activity. The one-line installer (`install.sh` / `install.ps1`) does not ask about them; run it with `KMA_SENSORS=1` in front and it downloads the `kma` CLI (checksum-verified against the release), mints a *scoped* enrollment token (sensors never hold your admin token), and walks you through per-item consent for every host-level write. To set it up later, or on a laptop that only runs sensors against a KMA stack elsewhere: ``` kma sensor init --hub http://127.0.0.1:8084 ``` (For a stack on another machine, use its public ingest endpoint as `--hub` and an enrollment token minted there.) `kma sensor status` shows what's installed; `kma sensor uninstall` removes it all. The viewer's **Status** page shows each sensor announce itself. Non-interactive installs: `KMA_SENSORS=1` (auto-yes) or `KMA_SENSORS=0` (skip) before running the installer. ## Level up: from shadow to NAMED (~3 minutes) Everything above shows your agents as anonymous "shadow" sessions. To turn a row into a **named, verified agent** with lineage: Your program already goes through the door from step 5. Each agent inside it shows up as its own unknown on the console's **Shadow** page — named from what the program already sends (the provider's identity field, Anthropic `metadata.user_id` / OpenAI `user`), or, with no change at all, by its instructions (its persona). Press **Issue passport** on a row and that agent alone gets a passport, filed under `./passport/agents//` on this machine; the private key is generated here and kept in the passport wallet, never leaving your machine. The door presents the passport only on that agent's calls — inside inspected calls through the exit too — from the next call on, no restart. Watch the console inventory: the shadow row becomes a **named agent**, and the **Family tree** view shows which program it belongs to. (`mint.sh` still mints a machine-wide passport by hand for a machine with no console reach; the console is the normal way.) ## What works in this version — honestly - ✅ Live inventory, activity, shadow agents, missions & budgets (view/edit) - ✅ Policies: write → simulate against real traffic → publish → **enforce** - ✅ Everything is recorded to a hash-chained local log; the full detail is yours alone (local viewer) — only metadata leaves your machine - ⚠️ Four console actions — *approve identity, revoke, panic, budget edit* — need the console to reach **into** your network, which this connected setup doesn't allow yet. They fail safe (recorded, honestly marked failed). The equivalent CLI operations work locally; console versions are on the roadmap. - ⚠️ The passport issuer key is stored in a local Docker volume (pilot-grade). Production deployments bind a real KMS. ## Everyday commands ``` docker compose ps # status docker compose logs kma-engine # doorman logs docker compose down # stop (your data survives — named volumes) ``` > ⚠️ **Danger — irreversible.** `docker compose down -v` also **erases the named > volumes** — the ONLY copy of your signing key and your entire audit log. There > is no undo. To just stop the stack, use `docker compose down` (above). Before > ever removing volumes, run `./backup.sh`. ## Local tools: tools your program starts itself Some tools are not on the network: a program starts an MCP server as a local process and talks to it over pipes. A program started with KMA's overlay, `kma run` or the Kubernetes patch has **KMA's stand-ins first on its PATH** (`npx`, `npm`, `node`, `bun`, `deno`, `uvx`, `uv`, `pipx`, `python`, `python3`). When the program says "run npx", KMA's stand-in runs the real one and sits on the pipe: every question the agent asks the tool is named, ruled on and recorded, and the tool appears on the console's Doors page the moment the program starts it. **Nothing in the program changes. Any language.** If KMA cannot be reached the tool runs as before, unwatched, and the program's log says so once. - The overlay sets PATH to `/kma-bin` plus the standard folders. An image that adds folders of its own (a virtual environment such as `/app/.venv/bin`) lists them on the Programs page when downloading the overlay; otherwise its own commands are not found at start. - Not seen: a tool the program starts by its **full path** (`/usr/bin/npx`) rather than by name. For that case, or for a program that does not go through KMA at all, run the tool on the KMA machine instead and point the program at its address: ``` kma tool files -- npx -y @modelcontextprotocol/server-filesystem /data ``` The program then reaches it at `http://files.tools.kma/mcp`. `kma tool` reads `PASSPORT_ADMIN_TOKEN` from the kit folder's `.env` (`~/kma` by default; `--kit` to point elsewhere); on Linux add `--bind 0.0.0.0`. ## Update, back up, restore Your keys and audit log live in three **named Docker volumes** on this one machine, and your agents' passports in the kit folder's `./passport`. They survive restarts and upgrades, but they are the *only* copy — so **back them up**. Two paired scripts do the safe thing for you (`.sh` for macOS/Linux, `.ps1` for Windows). ### Update to a new version — `update` Simplest: run the install command again. It notices KMA is already installed and updates it instead of starting over (set `KMA_FRESH=1` to force a fresh install — that makes a new machine identity you must approve again): ``` curl -fsSL https://knowmyagents.com/install.sh | sh # macOS/Linux irm https://knowmyagents.com/install.ps1 | iex # Windows ``` Or, from your kit folder (the one with `.env`, usually `~/kma`): ``` curl -fsSL https://knowmyagents.com/kit/update.sh | sh # macOS/Linux irm https://knowmyagents.com/kit/update.ps1 | iex # Windows ``` or, with the scripts already in the folder, `./update.sh` / `.\update.ps1` (add a version to pin one: `./update.sh 0.9.6`). What it does, in order: finds the latest released version; downloads that version's `docker-compose.yml` and helper scripts over the old ones (the kit's shape changes between versions — new services, new settings — so new images on an old compose file would not start; the old compose is kept as `docker-compose.yml.bak-`); adds any `.env` setting the new version expects but yours lacks, keeping your secrets, tokens and ports byte for byte; runs `docker compose pull` + `docker compose up -d --remove-orphans`; then health-checks the doorman and reports *old → new*. **Your data is kept.** The audit log and database, the issuer key, the machine's console registration and the passports live in named Docker volumes and `./passport`; the update never passes `-v` and never removes a volume. The console keeps the same machine — no re-approval, no re-issuing. DB migrations are forward-only and run on boot. Works from any older version, including the earliest kits. ### Back up the three volumes and the passports — `backup` ``` ./backup.sh # macOS/Linux: one archive in ./backups ./backup.sh --pause # briefly stop Postgres for a cold, fully consistent DB copy .\backup.ps1 # Windows (or .\backup.ps1 -Pause / -Out D:\safe) ``` Produces **one** timestamped archive (`backups/kma-backup-YYYYMMDDTHHMMSSZ.tar.gz`) containing all three volumes — `kma-shared` (machine private key + `kma.yaml`), `kma-passport-kms` (issuer signing key), and `kma-pgdata` (the tamper-evident audit log) — plus a manifest. It works **without stopping the stack**; a raw volume copy preserves Postgres's on-disk hash chain, so `verify` still passes after a restore. - **Consistency:** a hot snapshot of the database is *crash-consistent* — Postgres replays its write-ahead log on next start, exactly as it would after a power cut, and the audit chain stays intact. For a belt-and-braces **cold** copy, add `--pause` / `-Pause`: it stops just Postgres for the few seconds of the copy, then restarts it (the rest of the stack auto-recovers). - **⚠️ The archive contains PRIVATE KEYS.** Anyone holding it can impersonate this deployment. Store it encrypted and off this machine. Keep several dated copies. ### Restore onto a fresh (or rolled-back) machine — `restore` ``` ./restore.sh ./backups/kma-backup-…​.tar.gz # macOS/Linux .\restore.ps1 .\backups\kma-backup-…​.tar.gz # Windows ``` This is **destructive** — it overwrites the three volumes with the archive's contents, so it asks you to type `restore` to confirm (`--yes` / `-Yes` to skip). It stops the stack (containers only, no `-v`), recreates the volumes, and copies each tree back preserving ownership (Postgres keeps its uid, so the hash chain verifies). Then bring it back up: ``` docker compose up -d --wait ``` ### The same three, as `kma` commands The `kma` command (in every release, for macOS, Windows and Linux) does the same three things with one signed, versioned entry point — the scripts stay for machines without it: ``` kma backup # one archive in /backups (--pause for a cold copy, --out for elsewhere) kma restore # asks you to type "restore" (--yes to skip) kma update [version] # the latest by default ``` Run them from the kit folder, or point them at it with `--kit ~/kma`. ## Disk & log retention The audit log records **everything** and keeps the record — that's the point, and it's what makes shadow detection work. What it does not keep forever is the *detail* of every record: the console's **Settings → Record retention** sets, per kind of record, how many days the details are kept. After that the details are replaced by a marker (when, under which clock); the record itself — time, kind, agent, usage and hashes — stays, and every proof still verifies. Each machine prunes its own log once an hour and writes the run on the record. - Until you decide, the recommended clocks apply: calls 90 days, handshakes 30 days, sensor readings 30 days; decisions, approvals, revocations, spending and administration are kept. - **0 days** means *metadata only*: the details are never stored at all (the high-sensitivity mode). Empty means kept forever. - **Watch the disk anyway.** `docker system df -v` shows volume sizes (`kma-pgdata` is the log); alert if the host disk heads past ~80%. ## If something goes wrong - `setup-enroll` failing usually means a wrong/consumed registration — mint a fresh one in the console and re-run `docker compose up -d`. - Port 8129 or 5432 busy: stop whatever holds it, or edit the ports in `docker-compose.yml`. - Anything else: send `docker compose logs --tail 100` to your KMA contact.