diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..19138440 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,40 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## What This Repo Is + +Timeplus product documentation built with [Docusaurus v3](https://docusaurus.io/). Content lives in `docs/` as Markdown/MDX files. The site is deployed to docs.timeplus.com via Netlify. English is the only active locale (i18n scaffolding exists for Chinese but is disabled). + +## Commands + +```bash +yarn start # Dev server at http://localhost:3030 (with polling) +yarn build # Build to build/ directory +yarn run spellcheck # Spell check docs +yarn run rest-doc # Regenerate REST API docs from swagger.yaml via redocly +yarn run llmstxt # Regenerate static/llms.txt and static/llms-full.txt +``` + +**Tools (run from repo root with bun):** +```bash +bun tools/list-pages.ts # Show nav tree from sidebars.js + doc titles +bun tools/missing.js # Docs files not referenced in sidebars.js +bun tools/list-functions.ts # List all function names from functions_for_*.md +sh tools/autogenerate-downloads.sh # Regenerate release-downloads.md from S3 +``` + +## Architecture + +**Content:** All docs are in `docs/` as `.md` or `.mdx` files. File names map to URL slugs. Mermaid diagrams are supported natively. + +**Navigation:** `sidebars.js` defines the complete sidebar hierarchy. When adding a new doc, you must add an entry to `sidebars.js` or it will appear in `bun tools/missing.js` output. URL redirects for renamed/moved pages are configured in the `plugin-client-redirects` section of `docusaurus.config.js`. + +**Sidebar structure (top-level categories):** +- OVERVIEW → GET STARTED → CONNECT DATA IN → TRANSFORM DATA → STORE & SERVE DATA → SEND DATA OUT → SQL REFERENCE → TIMEPLUS PROTON (OSS) → INTEGRATIONS → DEPLOYMENT → TROUBLESHOOTING → RELEASES + +**Custom components:** `src/components/` contains reusable JSX components (Grid, Quickstart, TimeplusWatermarkVisualization). The `src/theme/DocSidebarItem/` override customizes sidebar rendering. + +**REST API docs:** Generated from `swagger.yaml` via `redocly` into `static/rest.html`. The source `swagger.yaml` is generated by the Neutron service (`make gen_api_doc`) — not stored in this repo. + +**Spellchecker config:** `tools/spellchecker/config.yml` (custom word lists for Timeplus-specific terms). diff --git a/docs/agentguard-installation.md b/docs/agentguard-installation.md new file mode 100644 index 00000000..4afb82e2 --- /dev/null +++ b/docs/agentguard-installation.md @@ -0,0 +1,428 @@ +# AgentGuard Installation Guide + +This guide walks through a complete AgentGuard setup from scratch: + +1. [Prerequisites](#1-prerequisites) +2. [Install and run Timeplus](#2-install-and-run-timeplus) +3. [Create a Timeplus user for AgentGuard](#3-create-a-timeplus-user-for-agentguard) +4. [Install and run AgentGuard](#4-install-and-run-agentguard) +5. [Connect OpenClaw](#5-connect-openclaw) +6. [Connect Claude Code](#6-connect-claude-code) +7. [Verify everything is working](#7-verify-everything-is-working) + +--- + +## 1. Prerequisites + +| Requirement | Minimum version | Notes | +|---|---|---| +| Docker | 24+ | Optional — only needed for Docker-based Timeplus or AgentGuard | +| Timeplus Enterprise | **3.2.1+** | Required — earlier versions are not supported | +| Node.js | 18+ | Required for agent plugins | +| Go | 1.23+ | Only if building AgentGuard from source | +| Claude Code CLI | any | Only for Claude Code integration | +| OpenClaw | 2026.4.0+ | Only for OpenClaw integration | + +--- + +## 2. Install and run Timeplus + +AgentGuard requires [Timeplus Enterprise](https://timeplus.com) **3.2.1 or later**. Follow the official installation guide for your preferred deployment method: + +- **Binary (Linux / macOS):** [docs.timeplus.com/bare-metal-install](https://docs.timeplus.com/bare-metal-install) +- **Docker / Docker Compose:** same page, Docker Install section + +Once Timeplus is running, the following ports must be reachable by AgentGuard and the agent plugins: + +| Port | Service | Purpose | +|---|---|---| +| `3218` | Timeplus | HTTP query API — used by AgentGuard | +| `8463` | Timeplus | Native TCP protocol — used by AgentGuard | +| `4317` | Timeplus | OTLP gRPC — agent OTel telemetry | +| `4318` | Timeplus | OTLP HTTP — agent OTel telemetry | +| `8000` | Timeplus | Web console | + +Wait for Timeplus to be ready before continuing: + +```bash +until curl -sf http://localhost:3218/ping > /dev/null 2>&1; do + echo "Waiting for Timeplus..."; sleep 5 +done +echo "Timeplus is ready" +``` + +> **Docker Compose shortcut:** to run Timeplus and AgentGuard together in one step, skip to [section 4C](#option-c--docker-compose-recommended-for-new-installs). + +--- + +## 3. Create a Timeplus user for AgentGuard + +AgentGuard connects to Timeplus using dedicated credentials. Skip this section if you are using the default `default` user with no password (acceptable for local dev). + +### Via Timeplus web console + +1. Open [http://localhost:8000](http://localhost:8000) in your browser. +2. Log in with the default admin credentials (set during first-run setup). +3. Navigate to **Settings → Users → Add User**. +4. Create a user — for example: + - **Username:** `User` + - **Password:** `Password` + - **Role:** Admin (AgentGuard needs DDL permissions to create streams and views on startup) +5. Click **Save**. + +--- + +## 4. Install and run AgentGuard + +### Option A — Shell script installer (recommended) + +The installer downloads the correct binary for your platform from S3, installs it to `/usr/local/bin`, and guides you through Timeplus Enterprise connection configuration interactively. + +```bash +# Install latest +curl -fsSL https://agentguard.s3.us-west-1.amazonaws.com/install.sh | sh + +# Install a specific version +curl -fsSL https://agentguard.s3.us-west-1.amazonaws.com/install.sh | sh -s -- --version v1.2.3 +``` + +Supported platforms: macOS (Apple Silicon / Intel), Linux (x86-64 / ARM64). + +The script will: +1. Download the correct binary and install it to `/usr/local/bin/agentguard` +2. Prompt for your Timeplus Enterprise connection settings and write `~/.agentguard/config.yaml` +3. Optionally set up AgentGuard as a background service (launchd on macOS, systemd on Linux) + +After installation, start AgentGuard manually with: +```bash +agentguard +``` + +Or use the service that was configured during installation. + +Open [http://localhost:8080](http://localhost:8080). + +AgentGuard creates all required Timeplus streams and materialized views on first startup. This is non-fatal — the server starts even if Timeplus is temporarily unavailable. + +> **Non-interactive install:** If you pipe the script through `sh` without a terminal (e.g. in CI), configuration prompts are skipped. Edit `~/.agentguard/config.yaml` manually afterwards. + +### Option B — Docker Compose (recommended for new installs) + +This starts Timeplus and AgentGuard together with the correct networking. Save the following as `docker-compose.yaml` and run it: + +```yaml +services: + timeplus: + image: timeplus/timeplus-enterprise:3.2.1 + platform: linux/amd64 + container_name: timeplus + ports: + - "3218:3218" # HTTP query API (used by AgentGuard) + - "8123:8123" # HTTP query API normal + - "8463:8463" # Native TCP protocol + - "4317:4317" # OTLP gRPC (agent OTel telemetry) + - "4318:4318" # OTLP HTTP (agent OTel telemetry) + - "8000:8000" # Timeplus Enterprise web console + volumes: + - timeplus-data:/timeplus/data/ + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/localhost/3218' 2>/dev/null || exit 1"] + interval: 5s + timeout: 3s + retries: 10 + start_period: 30s + + agentguard: + image: timeplus/agentguard:latest + container_name: agentguard + ports: + - "8080:8080" + environment: + TIMEPLUS_HOST: timeplus + TIMEPLUS_PORT: 3218 + TIMEPLUS_NATIVE_PORT: 8463 + TIMEPLUS_USER: "proton" + TIMEPLUS_PASSWORD: "timeplus@t+" + SERVER_PORT: 8080 + # Timeplus calls this URL for alert webhooks; use the Docker service name. + AGENTGUARD_URL: "http://agentguard:8080" + depends_on: + timeplus: + condition: service_healthy + restart: unless-stopped + +volumes: + timeplus-data: +``` + +```bash +docker compose up -d +``` + +Open [http://localhost:8080](http://localhost:8080). + +- AgentGuard waits for Timeplus to pass its health check before starting. +- `AGENTGUARD_URL=http://agentguard:8080` ensures Timeplus Enterprise can call back AgentGuard for alert webhooks using the Docker service name. +- Change `TIMEPLUS_USER` / `TIMEPLUS_PASSWORD` if you created a different user in step 3. + +To stop and remove volumes: +```bash +docker compose down -v +``` + +### Option C — Docker image (standalone) + +```bash +docker run -d \ + --name agentguard \ + -p 8080:8080 \ + -e TIMEPLUS_HOST= \ + -e TIMEPLUS_USER=proton \ + -e TIMEPLUS_PASSWORD="timeplus@t+" \ + -e AGENTGUARD_URL=http://:8080 \ + --restart unless-stopped \ + timeplus/agentguard:latest +``` + +Replace `` with the hostname or IP where Timeplus is running (use `host.docker.internal` on macOS/Windows when Timeplus runs on the host machine). + +Replace `` with the address Timeplus will use to call back AgentGuard for alert webhooks — see [Alert UDF webhook](#alert-udf-webhook) below. + +### Alert UDF webhook + +AgentGuard creates a Timeplus Python UDF (`notify_agentguard_udf`) at startup. When a security rule fires, Timeplus calls this UDF, which HTTP-POSTs the alert back to AgentGuard at: + +``` +/api/alerts/webhook +``` + +This is a **Timeplus → AgentGuard** call, so `AGENTGUARD_URL` must be the address where AgentGuard is reachable _from Timeplus's network perspective_: + +| Deployment | `AGENTGUARD_URL` | +|---|---| +| Both on host | `http://localhost:8080` _(default)_ | +| Docker Compose | `http://agentguard:8080` _(pre-configured)_ | +| AgentGuard in Docker, Timeplus on host | `http://host.docker.internal:8080` | +| Remote / cloud | `http://:8080` | + +--- + +## 5. Connect OpenClaw + +### 5a. Install the plugin + +```bash +npm install @timeplus/agentguard-openclaw-plugin +``` + +### 5b. Configure the plugin + +Add the plugin to your `openclaw.json`: + +```json +{ + "plugins": { + "entries": { + "agentguard": { + "enabled": true, + "config": { + "timeplusUrl": "http://localhost:3218", + "deploymentId": "my-team", + "deploymentName": "My Team", + "stream": "agentguard_hook_events", + "flushMs": 2000, + "batchSize": 50, + "username": "proton", + "password": "timeplus@t+" + } + } + } + } +} +``` + +Or set environment variables before starting OpenClaw: + +```bash +export AGENTGUARD_TIMEPLUS_URL=http://localhost:3218 +export AGENTGUARD_DEPLOYMENT_ID=my-team +export AGENTGUARD_DEPLOYMENT_NAME="My Team" +export AGENTGUARD_USERNAME=proton +export AGENTGUARD_PASSWORD="timeplus@t+" +``` + +> **Docker (OpenClaw in container, Timeplus on host):** Use `http://host.docker.internal:3218` instead of `localhost`. + +### 5c. OTel diagnostics + +To export LLM traces, metrics, and logs from OpenClaw to Timeplus, add the `diagnostics-otel` section to `openclaw.json`: + +```json +{ + "diagnostics": { + "enabled": true, + "otel": { + "enabled": true, + "endpoint": "http://localhost:4318", + "traces": true, + "metrics": true, + "logs": true, + "serviceName": "openclaw", + "sampleRate": 1, + "flushIntervalMs": 3000 + } + }, + "plugins": { + "entries": { + "diagnostics-otel": { "enabled": true } + } + } +} +``` + +> **Docker:** Use `http://host.docker.internal:4318` for the endpoint. + +### 5d. Docker-based setup (this repo) + +If running OpenClaw via Docker using the Makefile in `agents/openclaw/`: + +```bash +cd agents/openclaw + +make workspace # one-time: create .openclaw/ with correct permissions +make init # one-time: run the OpenClaw onboarding wizard +make configure # inject AgentGuard plugin config into openclaw.json +make deploy-plugin # build plugin + start container +make url # print the dashboard URL with auth token +``` + +`make configure` automates steps 5b and 5c above for the Docker environment. + +--- + +## 6. Connect Claude Code + +### 6a. Install the plugin globally + +```bash +npm install -g @timeplus/agentguard-claudecode-plugin +``` + +This installs the `agentguard-hook` command on your `PATH`. + +### 6b. Set environment variables + +Add these to your shell profile (`~/.zshrc` or `~/.bashrc`) **before** launching Claude Code: + +```bash +export AGENTGUARD_AGENT_ID="your-hostname" # identifies this machine +export AGENTGUARD_DEPLOYMENT_ID="local" +export AGENTGUARD_DEPLOYMENT_NAME="Local Dev" +export AGENTGUARD_TIMEPLUS_URL="http://localhost:3218" +export AGENTGUARD_USERNAME="proton" +export AGENTGUARD_PASSWORD="timeplus@t+" +``` + +Then reload your shell: + +```bash +source ~/.zshrc # or ~/.bashrc +``` + +### 6c. Register hooks in Claude Code + +Merge the following into `~/.claude/settings.json`. If the file does not exist, create it. + +```json +{ + "hooks": { + "SessionStart": [{"matcher":"*","hooks":[{"type":"command","command":"agentguard-hook","async":true}]}], + "SessionEnd": [{"matcher":"*","hooks":[{"type":"command","command":"agentguard-hook","async":true}]}], + "UserPromptSubmit": [{"matcher":"*","hooks":[{"type":"command","command":"agentguard-hook","async":true}]}], + "PreToolUse": [{"matcher":"*","hooks":[{"type":"command","command":"agentguard-hook","async":true}]}], + "PostToolUse": [{"matcher":"*","hooks":[{"type":"command","command":"agentguard-hook","async":true}]}], + "PostToolUseFailure": [{"matcher":"*","hooks":[{"type":"command","command":"agentguard-hook","async":true}]}], + "SubagentStart": [{"matcher":"*","hooks":[{"type":"command","command":"agentguard-hook","async":true}]}], + "SubagentStop": [{"matcher":"*","hooks":[{"type":"command","command":"agentguard-hook","async":true}]}], + "Stop": [{"matcher":"*","hooks":[{"type":"command","command":"agentguard-hook","async":true}]}], + "PermissionDenied": [{"matcher":"*","hooks":[{"type":"command","command":"agentguard-hook","async":true}]}] + } +} +``` + +> **Merge, do not replace.** If you already have a `settings.json`, add only the `hooks` key. Existing keys are unaffected. + +### 6d. OTel telemetry + +Add the following `env` block to `~/.claude/settings.json` (merge with any existing `env` keys) to capture LLM token usage, cost, and latency from Claude Code: + +```json +{ + "env": { + "CLAUDE_CODE_ENABLE_TELEMETRY": "1", + "CLAUDE_CODE_ENHANCED_TELEMETRY_BETA": "1", + "OTEL_METRICS_EXPORTER": "otlp", + "OTEL_LOGS_EXPORTER": "otlp", + "OTEL_TRACES_EXPORTER": "otlp", + "OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf", + "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4318", + "OTEL_METRIC_EXPORT_INTERVAL": "10000", + "OTEL_LOGS_EXPORT_INTERVAL": "5000", + "OTEL_LOG_TOOL_DETAILS": "1" + } +} +``` + +> **Protocol note:** Claude Code requires `http/protobuf`. Do not use `grpc`. + +--- + +## 7. Verify everything is working + +### Check Timeplus is reachable + +```bash +curl -s http://localhost:3218/ping +# expected: "Ok." +``` + +### Check AgentGuard started cleanly + +```bash +# Binary / local +./backend/server 2>&1 | grep -E "timeplus|AgentGuard" + +# Docker Compose +docker logs agentguard 2>&1 | grep -E "timeplus|AgentGuard" +``` + +Look for lines like: +``` +AgentGuard starting on :8080 +Proton endpoint: localhost:3218 (native: 8463) +AgentGuard webhook URL: http://localhost:8080 +timeplus: UDF notify_agentguard_udf created/updated (webhook: http://localhost:8080) +``` + +### Check Claude Code hook events are arriving + +Start a Claude Code session, run a tool call, then query Timeplus: + +```bash +curl -s -X POST http://localhost:3218/proton/v1/query \ + -H 'Content-Type: application/json' \ + -d '{"query":"SELECT hook_name, agent_id, event_time FROM table(agentguard_hook_events) WHERE agent_type='"'"'claudecode'"'"' ORDER BY event_time DESC LIMIT 5"}' +``` + +### Check OpenClaw hook events are arriving + +```bash +curl -s -X POST http://localhost:3218/proton/v1/query \ + -H 'Content-Type: application/json' \ + -d '{"query":"SELECT hook_name, agent_id, event_time FROM table(agentguard_hook_events) WHERE agent_type='"'"'openclaw'"'"' ORDER BY event_time DESC LIMIT 5"}' +``` + +### Open the dashboard + +Navigate to [http://localhost:8080/onboarding](http://localhost:8080/onboarding) for the guided setup wizard, or go straight to [http://localhost:8080/dashboard](http://localhost:8080/dashboard) to see live agent activity. diff --git a/docs/agentguard-introduction.md b/docs/agentguard-introduction.md new file mode 100644 index 00000000..7aa4b5c2 --- /dev/null +++ b/docs/agentguard-introduction.md @@ -0,0 +1,106 @@ +# Introducing AgentGuard + +As AI coding agents take on more complex, longer-running tasks — writing code, executing shell commands, installing packages, calling external APIs — the need for visibility and control grows with them. **AgentGuard** is a real-time security monitoring and governance platform built specifically for AI agent fleets. + +--- + +## The Problem + +AI agents are powerful. They can autonomously browse files, run commands, make HTTP calls, and install dependencies. That autonomy is exactly what makes them useful — and exactly what makes them a new attack surface. + +Without visibility into what your agents are doing, you are flying blind: + +- A prompt injection in a web page could redirect your agent to exfiltrate source code. +- An agent reading a database result could inadvertently expose credentials in its response. +- A dependency install step could pull in a malicious or unexpected package. +- Agents accumulating LLM token usage across a fleet can burn through budgets without warning. + +AgentGuard addresses all of this with a streaming telemetry pipeline, agent-agnostic threat detection rules, and a live security dashboard. + +--- + +## What AgentGuard Does + +AgentGuard sits alongside your agent fleet and continuously monitors every hook event — tool calls, LLM interactions, session boundaries — as they happen. It normalizes events from different agent frameworks into a unified schema, applies streaming SQL detection rules, and surfaces threats, metrics, and costs in real time. + +**Key capabilities:** + +| Capability | What you get | +|---|---| +| **Live threat feed** | Instant alerts when a detection rule fires, with severity, agent identity, and the raw event payload | +| **Agent fleet overview** | All active agents with event counts, session counts, token usage, and last-seen timestamps | +| **Session & run traces** | Per-session waterfall view of every LLM call and tool invocation, with timing | +| **Cost governance** | Daily spend trends, per-model token breakdown, configurable pricing, MTD forecast | +| **Rule packs** | Install, enable/disable, and upgrade versioned detection rules without restarting | +| **SQL console** | Ad-hoc streaming SQL directly against the underlying event streams | +| **Onboarding wizard** | Step-by-step setup for connecting a new agent in under five minutes | + +--- + +## Supported Agents + +AgentGuard currently supports two agent frameworks: + +- **[OpenClaw](https://github.com/timeplus-io/openclaw)** — An open-source AI coding agent framework. AgentGuard installs a hook plugin that captures every lifecycle event and posts it to Timeplus. +- **[Claude Code](https://claude.ai/code)** — Anthropic's official CLI for Claude. AgentGuard installs hook handlers into `~/.claude/settings.json` and optionally configures OpenTelemetry export for full LLM token and latency metrics. + +Both agent types share the same detection rules, cost accounting, and dashboard — no agent-specific configuration needed after setup. + +--- + +## How It Works + +``` + Agent (OpenClaw / Claude Code) + ┌──────────────────────────────┐ + │ AgentGuard hook plugin │ ─── hook events ──► Timeplus :3218 + │ OTel plugin (Claude Code) │ ─── OTLP/HTTP ─────► Timeplus :4318 + └──────────────────────────────┘ + + Timeplus (streaming SQL engine) + ┌──────────────────────────────────────────────────────────────────────────┐ + │ agentguard_hook_events ──► CIM normalizer MVs │ + │ └─► agentguard_cim_event │ + │ └─► rule MVs │ + │ └─► agentguard_security_events │ + │ └─► threats + alerts │ + └──────────────────────────────────────────────────────────────────────────┘ + + AgentGuard Backend (Go/Gin :8080) + └── REST API + SSE notifications + embedded React SPA +``` + +Hook events flow from agent plugins directly into Timeplus. Two **CIM (Common Information Model)** materialized views normalize heterogeneous events from OpenClaw and Claude Code into a single unified schema (`agentguard_cim_event`). Detection rules query this normalized stream — so the same SQL detects threats from any supported agent without modification. + +When a rule matches, it writes to `agentguard_security_events`. A threat deduplication pipeline groups matches by `(agent, session, rule)` and maintains their lifecycle status (`open → acknowledged → cleared`). A noise-suppression filter ensures you only get alerted when a threat is new or has re-opened after being cleared. + +The AgentGuard backend exposes a REST API that queries Timeplus for all dashboard data. A Server-Sent Events stream pushes live alert notifications to all connected browser clients as detections arrive. + +--- + +## Built-in Security Rules + +AgentGuard ships with four detection rules out of the box. Rules are disabled by default and must be explicitly activated. + +| Rule | Severity | What it detects | +|---|---|---| +| **Prompt Injection Shield** | Critical | Jailbreak attempts and instruction-override patterns in user messages and LLM prompts | +| **DLP Sentinel** | Critical | Sensitive data (API keys, secrets, SSNs, AWS credentials, GitHub tokens) appearing in tool results or LLM responses | +| **Privilege Guard** | Warning | Dangerous tool calls: shell execution, `sudo`, `rm -rf`, `/etc/passwd` access | +| **Supply Chain Watch** | Warning | Package install commands (`npm install`, `pip install`, `brew install`, etc.) | + +All rules are written in standard streaming SQL and can be inspected, customized, or replaced from the **Rule Packs** page. Custom rules can be added through the same interface. + +--- + +## Tech Stack + +| Layer | Technology | +|---|---| +| Streaming database | [Timeplus](https://timeplus.com) (streaming SQL, materialized views, mutable streams, alerts) | +| Backend | Go 1.23, Gin, Cobra, Viper | +| Frontend | React 18, Vite, React Router v6, Tailwind CSS, Recharts | +| Agent telemetry | OpenTelemetry OTLP/HTTP (logs, traces, metrics) | +| Hook events | Custom HTTP ingest → Timeplus stream | + + diff --git a/sidebars.js b/sidebars.js index 6a070361..9dd315c1 100644 --- a/sidebars.js +++ b/sidebars.js @@ -871,6 +871,22 @@ const sidebars = { }, ], }, + { + type: "category", + label: "AGENTGUARD", + items: [ + { + type: "doc", + id: "agentguard-introduction", + label: "Introduction", + }, + { + type: "doc", + id: "agentguard-installation", + label: "Installation", + }, + ], + }, { type: "category", label: "DEPLOYMENT",