Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,21 @@ GITHUB_WEBHOOK_SECRET=
# Set to true to enable verbose debug logging (git commands, file lists, API calls).
# DEBUG_MODE=true

# Required when any repo in config/layne.json has claude.enabled: true.
# ── AI scanners (optional) ────────────────────────────────────────────────────

# Claude scanner — required when any repo has claude.enabled: true.
# Also used by Pi Agent when provider is "anthropic".
# ANTHROPIC_API_KEY=

# Pi Agent scanner — add the key for whichever provider you configure in layne.json.
# Full credential list: https://github.com/badlogic/pi-mono/tree/main/packages/ai#environment-variables-nodejs-only
# OPENAI_API_KEY=
# GEMINI_API_KEY=
# MISTRAL_API_KEY=
# AZURE_OPENAI_API_KEY=
# AWS_ACCESS_KEY_ID=
# AWS_SECRET_ACCESS_KEY=

# ── Notifications ─────────────────────────────────────────────────────────────

# Global Rocket.Chat incoming webhook URL.
Expand Down
4 changes: 2 additions & 2 deletions website/docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ Overrides are keyed by `"owner/repo"`. A repository with no entry - or whose ent
|---|---|
| Semgrep | Enabled - `semgrep scan --config auto --json <files>` |
| Trufflehog | Enabled - `trufflehog filesystem --json --no-update <files>` |
| Claude | Disabled - must opt in per repo |
| Pi Agent | Disabled - must opt in per repo |
| Claude | Disabled - must opt in per repo; requires `ANTHROPIC_API_KEY` |
| Pi Agent | Disabled - must opt in per repo; requires a configured `provider` and the corresponding provider credentials in the environment |

See the individual scanner pages for full configuration options:
- [Semgrep](scanners/semgrep.md)
Expand Down
3 changes: 2 additions & 1 deletion website/docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,8 @@ Go to your repository → **Settings → Secrets and variables → Actions** and
| `GH_WEBHOOK_SECRET` | Webhook HMAC secret (maps to `GITHUB_WEBHOOK_SECRET` in `.env`) |
| `DOMAIN` | Domain name for TLS (e.g. `layne.example.com`) |
| `LETSENCRYPT_EMAIL` | Email for Let's Encrypt expiry notifications |
| `ANTHROPIC_API_KEY` | Anthropic API key for Claude scanning (required when any repo has `claude.enabled: true`) |
| `ANTHROPIC_API_KEY` | Anthropic API key - required when any repo has `claude.enabled: true`, or when Pi Agent uses `provider: "anthropic"` |
| *(provider key)* | Pi Agent provider credentials - add the variable for whichever provider you configure (e.g. `OPENAI_API_KEY`, `GEMINI_API_KEY`, `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY`). See [Pi Agent - Provider credentials](scanners/pi-agent.md#provider-credentials) for the full list |
| `ROCKETCHAT_WEBHOOK_URL` | Global Rocket.Chat incoming webhook URL (required when `$global.notifications.rocketchat.webhookUrl` is `"$ROCKETCHAT_WEBHOOK_URL"`) |

**Optional GitHub Actions variables** (Settings → Secrets and variables → Actions → Variables):
Expand Down
5 changes: 4 additions & 1 deletion website/docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ Everything runs on your own infrastructure. No third-party CI service, no SaaS s
│ │─▶│ SEMGREP │──┼─▶│ REPORTER ││
│ │ └────────────┘ │ └──────────┘│
│ │ ┌────────────┐ │ │
│ └─▶│ CLAUDE │──┘ │
│ ├─▶│ CLAUDE │──┤ │
│ │ └────────────┘ │ │
│ │ ┌────────────┐ │ │
│ └─▶│ PI AGENT │──┘ │
│ └────────────┘ │
└──────────────────────────────────────────────────────────────────────────────────────────┘
```
Expand Down
3 changes: 2 additions & 1 deletion website/docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
| `DOMAIN` | No* | (none) | Domain name for TLS and the Rocket.Chat logo URL (e.g. `layne.example.com`). Required by the Docker Compose TLS setup - not validated at runtime by the app. |
| `LETSENCRYPT_EMAIL` | No* | (none) | Email for Let's Encrypt expiry notifications. Required by the Docker Compose TLS setup - not validated at runtime by the app. |
| `PORT` | No | `3000` | Port for the webhook server |
| `ANTHROPIC_API_KEY` | No | (none) | Required when any repo has `claude.enabled: true` |
| `ANTHROPIC_API_KEY` | No | (none) | Required when any repo has `claude.enabled: true`, or when Pi Agent is configured with `provider: "anthropic"` |
| *(provider key)* | No | (none) | Pi Agent provider credentials. The required variable depends on the configured `provider`. See [pi-ai documentation](https://github.com/badlogic/pi-mono/tree/main/packages/ai#environment-variables-nodejs-only) for the full list |
| `DEBUG_MODE` | No | off | Set to `true` or `1` to enable verbose debug logging |
| `METRICS_ENABLED` | No | `false` | Set to `true` to enable Prometheus metrics endpoints |
| `METRICS_PORT` | No | `9091` | Port for the worker Prometheus metrics server |
Expand Down
6 changes: 3 additions & 3 deletions website/docs/scanners/claude.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Claude

The Claude scanner uses Anthropic's Claude LLM to detect **malicious intent** in changed code by default - reverse shells, backdoors, obfuscated payloads, and supply-chain attacks. Default Claude settings are just a blueprint. You should definitely adapt your system prompt or use a skill instead of the default prompt.
The Claude scanner uses Anthropic's Claude LLM to analyze changed code. By default it looks for **malicious intent** - reverse shells, backdoors, obfuscated payloads, and supply-chain attacks. That is a starting point, not a fixed ruleset. Security engineers implementing Layne should adapt the system prompt (or build a skill) to reflect their threat model and use cases - the scanner is a framework for AI-assisted code review, not a prescribed detector.

Unlike Semgrep and Trufflehog, the Claude scanner **sends code to Anthropic's API**. It is disabled by default and must be opted in per repo. It requires `ANTHROPIC_API_KEY` to be set in the environment.

Expand All @@ -11,15 +11,15 @@ The Claude scanner is experimental. It may produce inconsistent results, miss fi

## What it detects

Claude, as it's configured by default, looks specifically for confirmed malicious patterns with high confidence:
With the built-in prompt, Claude looks specifically for confirmed malicious patterns with high confidence:

- Reverse shells and command-and-control callbacks
- Backdoors and authentication bypasses
- Credential and secret exfiltration
- Obfuscated payloads (base64/hex encoded, eval chains)
- Supply-chain attacks (package typosquatting, postinstall hooks, dependency confusion)

Claude does **not** report style issues, bugs, or theoretical vulnerabilities. The built-in prompt instructs it to omit any finding it cannot validate with a verbatim evidence snippet from the file.
The built-in prompt instructs Claude to omit anything it cannot validate with a verbatim evidence snippet, and to ignore style issues, bugs, and theoretical vulnerabilities. Replace it with a custom `prompt` or a skill to scan for different threat classes or apply domain-specific rules.


## Data privacy
Expand Down
42 changes: 26 additions & 16 deletions website/docs/scanners/pi-agent.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Pi Agent

The Pi Agent scanner uses an autonomous AI agent to detect **malicious intent** in changed code - reverse shells, backdoors, obfuscated payloads, credential exfiltration, and supply-chain attacks.
The Pi Agent scanner uses an autonomous AI agent to analyze changed code. By default it looks for **malicious intent** - reverse shells, backdoors, obfuscated payloads, credential exfiltration, and supply-chain attacks. That is the starting point, not a constraint. Security engineers implementing Layne should adapt or replace the system prompt to match their threat model and use cases.

Pi Agent **sends code to an external AI provider's API**. It is disabled by default and must be opted in per repo. A `provider` must be configured explicitly - omitting it disables Pi Agent even when `enabled: true` is set.
Pi Agent was added alongside the Claude scanner because its SDK natively supports multiple AI providers. You can route through Anthropic's API, Amazon Bedrock (useful for accessing cheaper or private models), OpenAI, Google, Mistral, and others - without changing any Layne code.

Pi Agent **sends code to an external AI provider's API**. It is disabled by default and must be opted in per repo. A `provider` must be configured explicitly - omitting it disables Pi Agent even when `enabled: true` is set. The provider must also be configured with the correct credentials in the environment - see [Provider credentials](#provider-credentials) below.

:::warning Experimental
Pi Agent is an experimental scanner. It may produce inconsistent results, miss findings, or behave unexpectedly across runs. Do not rely on it as your sole security gate.
Expand All @@ -11,7 +13,7 @@ Pi Agent is an experimental scanner. It may produce inconsistent results, miss f

## What it detects

Pi Agent looks specifically for confirmed malicious patterns with high confidence:
With the built-in prompt, Pi Agent looks specifically for confirmed malicious patterns with high confidence:

- Reverse shells and command-and-control callbacks
- Backdoors and authentication bypasses
Expand All @@ -20,7 +22,7 @@ Pi Agent looks specifically for confirmed malicious patterns with high confidenc
- Supply-chain attacks (postinstall hooks, URL dependencies with hostile execution, dependency confusion)
- Covert execution (dangerous dynamic execution where the surrounding logic is clearly hostile)

Pi Agent does **not** report style issues, bugs, or theoretical vulnerabilities. The built-in prompt instructs it to omit any finding it cannot validate with a verbatim evidence snippet from the file.
The built-in prompt instructs Pi Agent to omit anything it cannot validate with a verbatim evidence snippet, and to ignore style issues, bugs, and theoretical vulnerabilities. Replace the prompt entirely with a custom `prompt` to scan for different threat classes or apply domain-specific rules.


## Data privacy
Expand Down Expand Up @@ -66,7 +68,7 @@ Because the agent drives its own investigation path, the same code may produce f
|---|---|---|---|
| `enabled` | boolean | `false` | Must be `true` to enable Pi Agent scanning for this repo |
| `provider` | string | (none) | **Required.** AI provider to use. Omitting this disables Pi Agent even if `enabled: true`. Supported values: `anthropic`, `openai`, `azure-openai-responses`, `google`, `google-gemini-cli`, `google-vertex`, `mistral`, `amazon-bedrock` |
| `model` | string | `claude-opus-4-6` | Model ID to use. Must be a valid model ID for the configured provider |
| `model` | string | `claude-opus-4-6` | Model ID to use. Must be a valid model ID for the configured provider. **Bedrock uses provider-prefixed IDs** (e.g. `anthropic.claude-opus-4-6-v1`) - the default `claude-opus-4-6` will not resolve and the scan will be silently skipped |
| `thinkingLevel` | string | `"medium"` | Depth of reasoning: `"low"`, `"medium"`, or `"high"`. `"high"` enables extended thinking |
| `timeoutMinutes` | number | `3` | Hard timeout for the agent session in minutes. Partial findings are returned if the timeout fires |
| `prompt` | string | built-in | Custom system prompt. Replaces the default prompt entirely |
Expand Down Expand Up @@ -97,20 +99,13 @@ The most effective cost control is the `workflow_run` or `workflow_job` trigger,
Use `thinkingLevel: "low"` for fast, cheap scans on low-risk repositories. Use `"high"` when you need deeper analysis of obfuscated or complex code.


## Pi Agent vs Claude scanner
## Provider credentials

Both scanners detect malicious intent. The difference is in how they investigate:
Each provider reads credentials from environment variables. The worker logs a warning and skips Pi Agent if credentials are missing rather than failing the scan.

| | Claude | Pi Agent |
|---|---|---|
| Approach | Single batch API call | Full agent session with file tools |
| Can follow imports | No | Yes |
| Can search across files | No | Yes |
| Deterministic | Yes | No |
| Default model | Haiku (cheap) | Opus (expensive) |
| Timeout | No (single call) | Yes (default 3 min) |
For the complete list of required environment variables per provider - including providers with complex auth like Azure OpenAI, Vertex AI, and Amazon Bedrock - see the [pi-ai documentation](https://github.com/badlogic/pi-mono/tree/main/packages/ai#environment-variables-nodejs-only).

Use Pi Agent when deeper cross-file investigation is valuable and the cost and non-determinism tradeoffs are acceptable. Use Claude when you want faster, cheaper, deterministic scanning with a simpler configuration surface.
Add the relevant variable(s) to your `.env` file and to your production secrets store.


## Examples
Expand Down Expand Up @@ -156,6 +151,21 @@ Use Pi Agent when deeper cross-file investigation is valuable and the cost and n
}
```

**Use Amazon Bedrock:**
```json
{
"acme/backend": {
"piAgent": {
"enabled": true,
"provider": "amazon-bedrock",
"model": "anthropic.claude-opus-4-6-v1"
}
}
}
```

Bedrock model IDs use a provider-prefixed format. Cross-region inference profile variants are also available (`us.anthropic.claude-opus-4-6-v1`, `eu.anthropic.claude-opus-4-6-v1`). The region defaults to `us-east-1` unless `AWS_REGION` or `AWS_DEFAULT_REGION` is set. See the [pi-ai documentation](https://github.com/badlogic/pi-mono/tree/main/packages/ai#environment-variables-nodejs-only) for the full list of available Bedrock models and credential options.

**Use a custom system prompt for domain-specific analysis:**
```json
{
Expand Down
Loading