Skip to content
Open
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
19 changes: 19 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# Example environment variables for local development
# Copy this file to .env and fill in the real values. DO NOT commit .env.

# GitHub Copilot token (example placeholder)
GITHUB_COPILOT_TOKEN=your_token_here

# Other env vars used by this project can go here as placeholders
# e.g. API_KEY=your_api_key_here
# Shannon Environment Configuration
# Copy this file to .env and fill in your credentials

Expand Down Expand Up @@ -26,8 +34,19 @@ ANTHROPIC_API_KEY=your-api-key-here
# OPENROUTER_API_KEY=sk-or-your-openrouter-key
# ROUTER_DEFAULT=openrouter,google/gemini-3-flash-preview

# =============================================================================
# OPTION 3: GitHub Copilot (uses your Copilot subscription)
# =============================================================================
# Enable Copilot mode by running: ./shannon start ... COPILOT=true
# Requires a GitHub token with Copilot access (PAT or OAuth token)

# GITHUB_TOKEN=ghp_your-github-token
# COPILOT_MODEL=gpt-4o # Options: claude-sonnet-4, gpt-4o, gemini-2.5-pro

# =============================================================================
# Available Models
# =============================================================================
# Anthropic (direct): claude-sonnet-4-5-20250929 (default)
# OpenAI: gpt-5.2, gpt-5-mini
# OpenRouter: google/gemini-3-flash-preview
# Copilot: claude-sonnet-4, gpt-4o, gemini-2.5-pro
4 changes: 3 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ body:
options:
- CLAUDE_CODE_OAUTH_TOKEN
- ANTHROPIC_API_KEY
- GITHUB_TOKEN (Copilot mode)
validations:
required: true

Expand All @@ -119,7 +120,8 @@ body:
label: Are you using any experimental models or providers other than default Anthropic models?
options:
- "No"
- "Yes"
- "Yes (Router mode)"
- "Yes (Copilot mode)"
validations:
required: true

Expand Down
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"snyk.advanced.autoSelectOrganization": true
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This repo-level VS Code setting enables Snyk to auto-select an organization, which is typically a per-developer preference and can produce surprising behavior for other contributors (e.g., scanning against the wrong org or prompting unexpected auth). Consider removing this file from the repo, moving it to documentation, or scoping it to a project-specific setting that all contributors actually need (and/or adding .vscode/ to .gitignore if editor settings aren’t meant to be versioned).

Suggested change
"snyk.advanced.autoSelectOrganization": true

Copilot uses AI. Check for mistakes.
}
12 changes: 8 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ AI-powered penetration testing agent for defensive security analysis. Automates

## Commands

**Prerequisites:** Docker, Anthropic API key in `.env`
**Prerequisites:** Docker, Anthropic API key in `.env` (or GitHub Copilot subscription for Copilot mode)

```bash
# Setup
cp .env.example .env && edit .env # Set ANTHROPIC_API_KEY
cp .env.example .env && edit .env # Set ANTHROPIC_API_KEY or GITHUB_TOKEN

# Prepare repo (REPO is a folder name inside ./repos/, not an absolute path)
git clone https://github.com/org/repo.git ./repos/my-repo
Expand All @@ -17,6 +17,7 @@ git clone https://github.com/org/repo.git ./repos/my-repo
# Run
./shannon start URL=<url> REPO=my-repo
./shannon start URL=<url> REPO=my-repo CONFIG=./configs/my-config.yaml
./shannon start URL=<url> REPO=my-repo COPILOT=true # GitHub Copilot mode

# Workspaces & Resume
./shannon start URL=<url> REPO=my-repo WORKSPACE=my-audit # New named workspace
Expand All @@ -36,7 +37,7 @@ git clone https://github.com/org/repo.git ./repos/my-repo
npm run build
```

**Options:** `CONFIG=<file>` (YAML config), `OUTPUT=<path>` (default: `./audit-logs/`), `WORKSPACE=<name>` (named workspace; auto-resumes if exists), `PIPELINE_TESTING=true` (minimal prompts, 10s retries), `REBUILD=true` (force Docker rebuild), `ROUTER=true` (multi-model routing via [claude-code-router](https://github.com/musistudio/claude-code-router))
**Options:** `CONFIG=<file>` (YAML config), `OUTPUT=<path>` (default: `./audit-logs/`), `WORKSPACE=<name>` (named workspace; auto-resumes if exists), `PIPELINE_TESTING=true` (minimal prompts, 10s retries), `REBUILD=true` (force Docker rebuild), `ROUTER=true` (multi-model routing via [claude-code-router](https://github.com/musistudio/claude-code-router)), `COPILOT=true` (GitHub Copilot models via `GITHUB_TOKEN`), `COPILOT_MODEL=<model>` (default: `gpt-4o`; options: `claude-sonnet-4`, `gpt-4o`, `gemini-2.5-pro`)

## Architecture

Expand Down Expand Up @@ -70,6 +71,7 @@ Durable workflow orchestration with crash recovery, queryable progress, intellig
- **Configuration** — YAML configs in `configs/` with JSON Schema validation (`config-schema.json`). Supports auth settings, MFA/TOTP, and per-app testing parameters
- **Prompts** — Per-phase templates in `prompts/` with variable substitution (`{{TARGET_URL}}`, `{{CONFIG_CONTEXT}}`). Shared partials in `prompts/shared/` via `src/services/prompt-manager.ts`
- **SDK Integration** — Uses `@anthropic-ai/claude-agent-sdk` with `maxTurns: 10_000` and `bypassPermissions` mode. Playwright MCP for browser automation, TOTP generation via MCP tool. Login flow template at `prompts/shared/login-instructions.txt` supports form, SSO, API, and basic auth
- **Copilot Integration** — `copilot-proxy/` handles GitHub token exchange (`api.github.com/copilot_internal/v2/token`) and proxies requests to `api.githubcopilot.com`. Runs as Docker service (profile: `copilot`). Flow: Claude Agent SDK → `ANTHROPIC_BASE_URL` → claude-code-router → copilot-proxy → GitHub Copilot API
- **Audit System** — Crash-safe append-only logging in `audit-logs/{hostname}_{sessionId}/`. Tracks session metrics, per-agent logs, prompts, and deliverables. WorkflowLogger (`audit/workflow-logger.ts`) provides unified human-readable per-workflow logs, backed by LogStream (`audit/log-stream.ts`) shared stream primitive
- **Deliverables** — Saved to `deliverables/` in the target repo via the `save_deliverable` MCP tool
- **Workspaces & Resume** — Named workspaces via `WORKSPACE=<name>` or auto-named from URL+timestamp. Resume passes `--workspace` to the Temporal client (`src/temporal/client.ts`), which loads `session.json` to detect completed agents. `loadResumeState()` in `src/temporal/activities.ts` validates deliverable existence, restores git checkpoints, and cleans up incomplete deliverables. Workspace listing via `src/temporal/workspaces.ts`
Expand Down Expand Up @@ -146,7 +148,7 @@ Comments must be **timeless** — no references to this conversation, refactorin

**Core Logic:** `src/session-manager.ts`, `src/ai/claude-executor.ts`, `src/config-parser.ts`, `src/services/`, `src/audit/`

**Config:** `shannon` (CLI), `docker-compose.yml`, `configs/`, `prompts/`
**Config:** `shannon` (CLI), `docker-compose.yml`, `configs/`, `prompts/`, `copilot-proxy/`

## Troubleshooting

Expand All @@ -157,3 +159,5 @@ Comments must be **timeless** — no references to this conversation, refactorin
- **Local apps unreachable** — Use `host.docker.internal` instead of `localhost`
- **Missing tools** — Use `PIPELINE_TESTING=true` to skip nmap/subfinder/whatweb (graceful degradation)
- **Container permissions** — On Linux, may need `sudo` for docker commands
- **Copilot auth failure** — Verify `GITHUB_TOKEN` has Copilot access. Check `docker compose --profile copilot logs copilot-proxy` for token exchange errors
- **Copilot model errors** — Not all models may be available in your Copilot subscription. Try `COPILOT_MODEL=gpt-4o` as default
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,29 @@ ROUTER_DEFAULT=openai,gpt-5.2 # provider,model format
./shannon start URL=https://example.com REPO=repo-name ROUTER=true
```

#### GitHub Copilot (Experimental)

Shannon can also use GitHub Copilot models via an internal proxy and the router. This is experimental and requires a GitHub token with Copilot access. To enable:

1. Add `GITHUB_TOKEN` (and optionally `COPILOT_MODEL`) to your `.env` (see `.env.example`).

```bash
# Example .env entries
GITHUB_TOKEN=ghp_your-github-token
COPILOT_MODEL=gpt-4o # Options: claude-sonnet-4, gpt-4o, gemini-2.5-pro
```

2. Start Shannon with Copilot enabled (the CLI will start the `copilot-proxy` and router automatically):

```bash
./shannon start URL=https://your-app.com REPO=your-repo COPILOT=true
```

Notes:
- Copilot mode auto-enables the internal router and `copilot-proxy` service.
- The `copilot-proxy` exchanges your long-lived `GITHUB_TOKEN` for short-lived Copilot session tokens and auto-refreshes them.
- This mode is experimental; do not run against production systems.

#### Experimental Models

| Provider | Models |
Expand Down
9 changes: 9 additions & 0 deletions configs/router-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@
"transformer": {
"use": ["openrouter"]
}
},
{
"name": "copilot",
"api_base_url": "http://copilot-proxy:8787/v1/chat/completions",
"api_key": "copilot-proxy-passthrough",
"models": ["claude-sonnet-4", "gpt-4o", "gemini-2.5-pro"],
"transformer": {
"use": [["maxcompletiontokens", { "max_completion_tokens": 16384 }]]
}
}
],
"Router": {
Expand Down
5 changes: 5 additions & 0 deletions copilot-proxy/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM node:20-slim
WORKDIR /app
COPY package.json index.js ./
EXPOSE 8787
CMD ["node", "index.js"]
50 changes: 50 additions & 0 deletions copilot-proxy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# copilot-proxy

Lightweight proxy used by Shannon to enable GitHub Copilot model access.

What it does

- Exchanges a long-lived `GITHUB_TOKEN` (PAT or OAuth token) for a short-lived Copilot session token via GitHub's internal Copilot token endpoint.
- Caches and auto-refreshes the session token.
- Accepts OpenAI-compatible requests on port `8787` and forwards them to `https://api.githubcopilot.com/chat/completions` with the Copilot Bearer token injected.

Usage

1. Add `GITHUB_TOKEN` to your `.env` (see project `.env.example`).

2. Start Shannon with Copilot enabled (recommended):

```bash
# From project root
./shannon start URL=https://your-app.com REPO=your-repo COPILOT=true
```

Or start the proxy manually via Docker Compose profile `copilot`:

```bash
# Start only the copilot proxy
docker compose up -d --profile copilot copilot-proxy

# Check health
curl http://localhost:8787/health
```

Local development

You can run the proxy directly for development:

```bash
cd copilot-proxy
export GITHUB_TOKEN=ghp_xxx
node index.js
```

Security

- Keep `GITHUB_TOKEN` secret. Do not commit it to source control.
- Tokens exchanged by the proxy are short-lived; the proxy refreshes them automatically.

Notes

- This proxy is intentionally minimal and intended for local / CI use within controlled networks only.
- Copilot integration is experimental and unsupported by Keygraph.
Loading