diff --git a/CLAUDE.md b/CLAUDE.md index bb3471f..652ff33 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -9,19 +9,21 @@ This is a **Claude Code skills repository**. Skills are reusable tools that exte ## Skill Structure Each skill follows this convention: -- **`/SKILL.md`** — Required. Contains YAML frontmatter (`name`, `description`) and usage documentation. This is the entry point Claude Code reads when invoking the skill. -- **`/scripts/`** — Implementation scripts (bash). Scripts use `set -euo pipefail` and the `die()` pattern for error handling. +- **`/SKILL.md`** — Required. YAML frontmatter (`name`, `description`, …) MUST start on line 1. This is the entry point Claude Code reads when invoking the skill. +- **`/CLAUDE.md`** — Optional. Maintainer / implementation notes kept out of the user-facing SKILL.md to reduce per-invocation token cost. +- **`/scripts/`** — Optional. Implementation scripts (typically bash). Scripts use `set -euo pipefail` and the `die()` pattern for error handling. Invoke scripts via `bash scripts/.sh` so they work even when the executable bit did not survive deployment — but also `chmod +x` them on commit. +- **`/references/`** — Optional. Supporting files such as YAML templates or long-form reference documentation. ## Current Skills -- **`github-app-token`** — Documents how to generate short-lived GitHub App installation access tokens. Requires `GITHUB_APP_ID`, `GITHUB_APP_INSTALLATION_ID`, and `GITHUB_APP_PEM_FILE` env vars. Inline commands only — no bundled scripts. -- **`playwright-ephemeral`** — Provisions ephemeral Playwright MCP browser sessions as Kubernetes Jobs for E2E testing. Creates a Job + Service pair in a dedicated namespace, waits for readiness, and returns the MCP endpoint URL. Requires `kubectl` and appropriate RBAC. -- **`shannon`** — Autonomous AI pentester for web apps and APIs. Wraps the Docker-based Shannon pentester as a `/shannon` slash command. Requires `docker`, `git`, and an AI API key (`ANTHROPIC_API_KEY` or equivalent). +- **`github-app-token`** — Generates a short-lived GitHub App installation access token, writes it to `.gh-token` under `$GH_CONFIG_DIR` (preferred) or `$AGENT_HOME` (fallback), and authenticates the `gh` CLI. Requires `GITHUB_APP_ID`, `GITHUB_APP_INSTALLATION_ID`, and one of `GITHUB_APP_PEM` (inline PEM) or `GITHUB_APP_PEM_FILE` (path). Depends on `openssl`, `curl`, `jq`, `gh`. +- **`minimax-image-generation`** — Generates images from MiniMax's `image-01` model via `/v1/image_generation`. Requires `MINIMAX_API_KEY`; `MINIMAX_API_BASE_URL` is optional. Depends on `curl`, `jq`, `base64`. ## Key Patterns -- Scripts are pure bash with no external dependencies beyond standard Unix tools (`openssl`, `curl`, `jq`, `kubectl`, `docker`). -- The `die()` function prints errors to stderr and exits non-zero. +- Standard Unix tools only (`openssl`, `curl`, `jq`, `base64`). Any skill-specific runtime requirement (e.g. `gh`) is declared in that skill's `SKILL.md`. +- `die()` prints errors to stderr and exits non-zero. +- Scripts validate required env vars up front and fail loudly rather than defaulting to `mktemp`/`/tmp` for anything secret. ## No Build/Test/Lint System diff --git a/README.md b/README.md new file mode 100644 index 0000000..46d3e82 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# Skills + +A collection of Claude Code skills — reusable tools that extend Claude Code's capabilities. Each skill lives in its own top-level directory and ships a `SKILL.md` (the entry point Claude Code reads when invoking the skill) plus any supporting scripts or references. + +## Available skills + +| Skill | What it does | +|---|---| +| [`github-app-token`](./github-app-token) | Generate a short-lived GitHub App installation access token and authenticate the `gh` CLI with it. | +| [`minimax-image-generation`](./minimax-image-generation) | Generate images from MiniMax's `image-01` model via the `/v1/image_generation` endpoint. | + +## Skill layout + +``` +/ +├── SKILL.md # Required. YAML frontmatter (name, description) + usage docs. +├── CLAUDE.md # Optional. Maintainer / implementation notes. +└── scripts/ # Optional. Bash or other implementation scripts. +``` + +Scripts use `set -euo pipefail` and a shared `die()` pattern for error handling. Scripts are invoked via `bash scripts/.sh` (not `./scripts/.sh`) so that they work even when the executable bit did not survive deployment. + +## No build / test / lint tooling + +There is no centralized build, test, or lint system. Each skill is self-contained and pulls in only standard Unix tools as declared in its `SKILL.md`. + +## Contributing + +- New skills get a new top-level directory with at minimum a `SKILL.md` that starts with YAML frontmatter on line 1. +- Keep `SKILL.md` focused on decision flow + user-facing usage. Move implementation details, API references, and rarely-needed tables into `CLAUDE.md` or a `references/` subdirectory to keep per-invocation token cost low. +- Add a row to the table above. diff --git a/github-app-token/SKILL.md b/github-app-token/SKILL.md index 553f726..8e07432 100644 --- a/github-app-token/SKILL.md +++ b/github-app-token/SKILL.md @@ -24,6 +24,6 @@ Generate a short-lived GitHub App installation token and authenticate `gh`. bash github-app-token/scripts/generate-token.sh ``` -The script validates env vars, generates a JWT, exchanges it for an installation token, writes the token to `$AGENT_HOME/.gh-token`, and runs `gh auth login`. On success it prints a confirmation line. On failure it exits non-zero with a descriptive error. +The script validates env vars, generates a JWT, exchanges it for an installation token, writes the token to `.gh-token` inside `$GH_CONFIG_DIR` (preferred) or `$AGENT_HOME` (fallback), and runs `gh auth login`. If neither `GH_CONFIG_DIR` nor `AGENT_HOME` is set the script exits non-zero rather than silently writing the token to a default location. On success it prints a confirmation line. On failure it exits non-zero with a descriptive error. Requires `openssl`, `curl`, `jq`, and `gh`. diff --git a/github-app-token/scripts/generate-token.sh b/github-app-token/scripts/generate-token.sh index d039c09..68b21d1 100755 --- a/github-app-token/scripts/generate-token.sh +++ b/github-app-token/scripts/generate-token.sh @@ -49,9 +49,20 @@ RESPONSE=$(curl -sf -X POST \ TOKEN=$(echo "$RESPONSE" | jq -r '.token // empty') [[ -z "$TOKEN" ]] && die "No token in GitHub response: $RESPONSE" -# --- Write token to file --- -GH_TOKEN_FILE="${AGENT_HOME:+${AGENT_HOME}/.gh-token}" -GH_TOKEN_FILE="${GH_TOKEN_FILE:-$(mktemp)}" +# --- Resolve token file location --- +# Prefer GH_CONFIG_DIR (so the token lives alongside the per-agent gh config), +# fall back to AGENT_HOME, fail loudly if neither is set rather than silently +# writing to /tmp and leaking the token. +if [[ -n "${GH_CONFIG_DIR:-}" ]]; then + GH_TOKEN_DIR="$GH_CONFIG_DIR" +elif [[ -n "${AGENT_HOME:-}" ]]; then + GH_TOKEN_DIR="$AGENT_HOME" +else + die "Neither GH_CONFIG_DIR nor AGENT_HOME is set — refusing to write the token to a default location" +fi + +mkdir -p "$GH_TOKEN_DIR" +GH_TOKEN_FILE="$GH_TOKEN_DIR/.gh-token" printf '%s' "$TOKEN" > "$GH_TOKEN_FILE" chmod 600 "$GH_TOKEN_FILE" diff --git a/minimax-image-generation/CLAUDE.md b/minimax-image-generation/CLAUDE.md index 619cc33..16ba8ea 100644 --- a/minimax-image-generation/CLAUDE.md +++ b/minimax-image-generation/CLAUDE.md @@ -1,62 +1,32 @@ # MiniMax Image Generation — Implementation Notes +User-facing docs (aspect ratios, usage, env vars) live in `SKILL.md`. This file is for maintenance notes only. + ## API Reference - **Endpoint**: `POST /v1/image_generation` - **Base URL**: `https://api.minimax.io` (international) or `https://api.minimaxi.com` (China) - **Auth**: `Authorization: Bearer ` - **Model**: `image-01` -- **Response**: JSON with `data.image_base64[]` array - -## Example API Call - -```bash -curl -X POST "https://api.minimax.io/v1/image_generation" \ - -H "Authorization: Bearer ${MINIMAX_API_KEY}" \ - -H "Content-Type: application/json" \ - -d '{ - "model": "image-01", - "prompt": "men Dressing in white t shirt, full-body stand front view image :25, outdoor", - "aspect_ratio": "16:9", - "num_images": 1, - "response_format": "base64" - }' -``` +- **Response**: JSON with `data.image_base64[]` array; errors surface in `base_resp.status_code` / `base_resp.status_msg`. ## Response Format ```json { - "data": { - "image_base64": [""] - }, + "data": { "image_base64": [""] }, "model": "image-01", - "request_id": "" + "request_id": "", + "base_resp": { "status_code": 0, "status_msg": "success" } } ``` -## Aspect Ratios - -| Ratio | Dimensions | Use Case | -|-------|-----------|----------| -| `16:9` | 1920×1080 | Desktop wallpaper, banners | -| `1:1` | 1024×1024 | Social media, profile images | -| `9:16` | 1080×1920 | Mobile wallpaper, stories | -| `4:3` | 1024×768 | Presentations | -| `3:4` | 768×1024 | Posters, portraits | - -## Dependencies - -- `curl` — HTTP requests -- `jq` — JSON parsing -- `base64` — Decode image data (coreutils) - -All three are standard Unix tools. No Python or Node required. - ## File Structure ``` minimax-image-generation/ -├── SKILL.md # Skill definition + user-facing docs -└── CLAUDE.md # These implementation notes +├── SKILL.md # Skill definition + user-facing docs +├── CLAUDE.md # These implementation notes +└── scripts/ + └── generate.sh # Generate images (invoke via `bash scripts/generate.sh …`) ``` diff --git a/minimax-image-generation/SKILL.md b/minimax-image-generation/SKILL.md index 6144238..ff9112d 100644 --- a/minimax-image-generation/SKILL.md +++ b/minimax-image-generation/SKILL.md @@ -1,16 +1,3 @@ -# MiniMax Image Generation Skill - -Claude Code skill for generating images via the MiniMax API. -Wraps the MiniMax `/v1/image_generation` endpoint as a `/minimax-image-generation` slash command. - -## Structure -- `SKILL.md` — skill definition + usage documentation -- `CLAUDE.md` — implementation notes - -## Rules -- Set `MINIMAX_API_KEY` env var before use -- Images are written to disk as `output-0.jpeg`, `output-1.jpeg`, etc. - --- name: minimax-image-generation version: "1.0.0" @@ -48,57 +35,31 @@ metadata: ```bash export MINIMAX_API_KEY="your-minimax-api-key" -/minimax-image-generation "a cat wearing a spacesuit, cinematic photography" +bash minimax-image-generation/scripts/generate.sh "a cat wearing a spacesuit, cinematic photography" ``` ---- +Always invoke the script via `bash scripts/generate.sh …` (or `bash minimax-image-generation/scripts/generate.sh …` when running from the repo root). Do **not** rely on the executable bit — invoking through `bash` is the supported entry point, and works even when the file permissions were not preserved during deployment. ## Parse User Intent Extract from the user's input: -1. **PROMPT**: The image description (required) -2. **ASPECT_RATIO**: `16:9` (default), `1:1`, `9:16`, `4:3`, `3:4` +1. **PROMPT**: The image description (required, positional argument) +2. **ASPECT_RATIO**: `16:9` (default), `1:1`, `9:16`, `4:3`, `3:4` — via `--aspect-ratio=` +3. **COUNT**: number of images to generate (default `1`) — via `--count=` +4. **OUTPUT_PREFIX**: filename stem (default `output`) — via `--output=` ---- - -## API Call Example +## Script Usage ```bash -# Verify credentials -if [ -z "${MINIMAX_API_KEY:-}" ]; then - echo "ERROR: MINIMAX_API_KEY is not set." - exit 1 -fi - -API_BASE_URL="${MINIMAX_API_BASE_URL:-https://api.minimax.io}" -PROMPT="" -ASPECT_RATIO="16:9" - -# Call the API -response=$(curl -s -X POST "${API_BASE_URL}/v1/image_generation" \ - -H "Authorization: Bearer ${MINIMAX_API_KEY}" \ - -H "Content-Type: application/json" \ - -d "{ - \"model\": \"image-01\", - \"prompt\": \"${PROMPT}\", - \"aspect_ratio\": \"${ASPECT_RATIO}\", - \"response_format\": \"base64\" - }") - -# Decode and save -images=$(echo "$response" | jq -r '.data.image_base64[]') -idx=0 -for image_b64 in $images; do - echo "$image_b64" | base64 -d > "output-${idx}.jpeg" - echo "Saved: output-${idx}.jpeg" - idx=$((idx + 1)) -done +bash minimax-image-generation/scripts/generate.sh \ + "a sunset over the ocean, cinematic" \ + --aspect-ratio=16:9 \ + --count=1 \ + --output=sunset ``` -**Replace `` with the user's image description.** - ---- +The script writes `-0.jpeg`, `-1.jpeg`, … to the current working directory. On failure it exits non-zero with a descriptive error. ## Aspect Ratio Guide @@ -110,28 +71,13 @@ done | `4:3` | Standard — presentations, blog images | | `3:4` | Portrait standard — posters, portraits | ---- - -## Configuration Reference - -### Environment Variables +## Environment Variables | Variable | Required | Description | |----------|----------|-------------| | `MINIMAX_API_KEY` | Yes | Your MiniMax API key | | `MINIMAX_API_BASE_URL` | No | API base URL (default: `https://api.minimax.io`) | -### API Parameters - -| Parameter | Type | Default | Description | -|-----------|------|---------|-------------| -| `model` | string | `image-01` | Model to use | -| `prompt` | string | required | Image description | -| `aspect_ratio` | string | `16:9` | Image aspect ratio | -| `response_format` | string | `base64` | Output format | - ---- - ## Example Output ``` diff --git a/minimax-image-generation/scripts/generate.sh b/minimax-image-generation/scripts/generate.sh new file mode 100755 index 0000000..09026ff --- /dev/null +++ b/minimax-image-generation/scripts/generate.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash +# generate.sh — Generate images via MiniMax /v1/image_generation. +# Usage: bash scripts/generate.sh "" [--aspect-ratio=16:9] [--count=1] [--output=output] +set -euo pipefail + +die() { echo "ERROR: $*" >&2; exit 1; } + +# --- Dependencies --- +for cmd in curl jq base64; do + command -v "$cmd" >/dev/null 2>&1 || die "Required command not found: $cmd" +done + +# --- Credentials --- +[[ -z "${MINIMAX_API_KEY:-}" ]] && die "MINIMAX_API_KEY is not set" +API_BASE_URL="${MINIMAX_API_BASE_URL:-https://api.minimax.io}" + +# --- Parse args --- +PROMPT="" +ASPECT_RATIO="16:9" +COUNT=1 +OUTPUT_PREFIX="output" + +for arg in "$@"; do + case "$arg" in + --aspect-ratio=*) ASPECT_RATIO="${arg#*=}" ;; + --count=*) COUNT="${arg#*=}" ;; + --output=*) OUTPUT_PREFIX="${arg#*=}" ;; + --*) die "Unknown flag: $arg" ;; + *) if [[ -z "$PROMPT" ]]; then PROMPT="$arg"; else die "Unexpected positional argument: $arg"; fi ;; + esac +done + +[[ -z "$PROMPT" ]] && die "Usage: bash scripts/generate.sh \"\" [--aspect-ratio=16:9] [--count=1] [--output=output]" + +case "$ASPECT_RATIO" in + 16:9|1:1|9:16|4:3|3:4) ;; + *) die "Unsupported aspect ratio: $ASPECT_RATIO (valid: 16:9, 1:1, 9:16, 4:3, 3:4)" ;; +esac + +if ! [[ "$COUNT" =~ ^[0-9]+$ ]] || (( COUNT < 1 )); then + die "Invalid --count: $COUNT (must be a positive integer)" +fi + +echo "🎨 MiniMax Image Generation" >&2 +echo "├─ Prompt: \"$PROMPT\"" >&2 +echo "├─ Aspect ratio: $ASPECT_RATIO" >&2 +echo "├─ Count: $COUNT" >&2 +echo "└─ Model: image-01" >&2 +echo "" >&2 + +# --- Build JSON payload safely (jq handles escaping) --- +PAYLOAD=$(jq -n \ + --arg prompt "$PROMPT" \ + --arg ratio "$ASPECT_RATIO" \ + --argjson n "$COUNT" \ + '{model:"image-01", prompt:$prompt, aspect_ratio:$ratio, num_images:$n, response_format:"base64"}') + +# --- Call API --- +RESPONSE=$(curl -sS -X POST "${API_BASE_URL}/v1/image_generation" \ + -H "Authorization: Bearer ${MINIMAX_API_KEY}" \ + -H "Content-Type: application/json" \ + -d "$PAYLOAD") || die "MiniMax API request failed" + +# --- Check for API error --- +ERR=$(echo "$RESPONSE" | jq -r '.base_resp.status_msg // empty') +CODE=$(echo "$RESPONSE" | jq -r '.base_resp.status_code // 0') +if [[ "$CODE" != "0" && -n "$ERR" ]]; then + die "MiniMax API error (code=$CODE): $ERR" +fi + +# --- Decode and save --- +COUNT_SAVED=0 +while IFS= read -r image_b64; do + [[ -z "$image_b64" ]] && continue + OUT="${OUTPUT_PREFIX}-${COUNT_SAVED}.jpeg" + echo "$image_b64" | base64 -d > "$OUT" || die "Failed to decode image $COUNT_SAVED" + echo "Saved: $OUT" >&2 + COUNT_SAVED=$((COUNT_SAVED + 1)) +done < <(echo "$RESPONSE" | jq -r '.data.image_base64[]?') + +(( COUNT_SAVED == 0 )) && die "No images returned: $RESPONSE" + +echo "Done." >&2 diff --git a/shannon/CLAUDE.md b/shannon/CLAUDE.md deleted file mode 100644 index 8981c4a..0000000 --- a/shannon/CLAUDE.md +++ /dev/null @@ -1,19 +0,0 @@ -# Shannon Skill - -Claude Code skill for autonomous AI pentesting via Shannon. -Wraps the Docker-based Shannon pentester as a `/shannon` slash command. - -## Structure -- `SKILL.md` — skill definition (deployed to ~/.claude/skills/shannon/) -- `scripts/setup-shannon.sh` — installer/updater for Shannon -- `scripts/sync.sh` — deploy to ~/.claude, ~/.agents, ~/.codex - -## Commands -```bash -bash scripts/sync.sh # Deploy to all skill locations -``` - -## Rules -- ALWAYS confirm authorization before running pentests -- NEVER target production systems -- After edits: run `bash scripts/sync.sh` to deploy diff --git a/shannon/SKILL.md b/shannon/SKILL.md deleted file mode 100644 index c37b669..0000000 --- a/shannon/SKILL.md +++ /dev/null @@ -1,536 +0,0 @@ ---- -name: shannon -version: "1.0.0" -description: "Autonomous AI pentester for web apps and APIs. Run white-box security assessments with Shannon — analyzes source code, identifies attack vectors, and executes real exploits to prove vulnerabilities. Triggered by 'shannon', 'pentest', 'security audit', 'vuln scan'." -argument-hint: 'shannon http://localhost:3000 myapp, shannon --workspace=audit1 http://staging.example.com myrepo' -allowed-tools: Bash, Read, Write, AskUserQuestion, WebSearch -homepage: https://github.com/KeygraphHQ/shannon -repository: https://github.com/KeygraphHQ/shannon -author: KeygraphHQ -license: AGPL-3.0 -user-invocable: true -metadata: - openclaw: - emoji: "🔐" - category: "security" - requires: - env: - - ANTHROPIC_API_KEY - optionalEnv: - - ANTHROPIC_AUTH_TOKEN - - ANTHROPIC_BASE_URL - - ANTHROPIC_MODEL - - ANTHROPIC_SMALL_FAST_MODEL - - CLAUDE_CODE_OAUTH_TOKEN - - CLAUDE_CODE_USE_BEDROCK - - CLAUDE_CODE_USE_VERTEX - - AWS_REGION - - AWS_ACCESS_KEY_ID - - AWS_SECRET_ACCESS_KEY - bins: - - docker - - git - primaryEnv: ANTHROPIC_API_KEY - files: - - "scripts/*" - tags: - - security - - pentesting - - pentest - - vulnerability - - exploit - - owasp - - xss - - sqli - - ssrf - - authentication - - authorization - - white-box - - appsec ---- - -# Shannon: Autonomous AI Pentester for Web Apps & APIs - -> **Permissions overview:** This skill orchestrates Shannon, a Docker-based pentesting tool that actively executes attacks against a target application. It clones/updates the Shannon repo locally, runs Docker containers, and reads pentest reports. **Shannon performs real exploits — only run against apps you own or have explicit written authorization to test.** Never run against production systems. - -Shannon analyzes your source code, identifies attack vectors, and executes real exploits to prove vulnerabilities before they reach production. 96.15% exploit success rate on the XBOW security benchmark. Covers OWASP Top 10: Injection, XSS, SSRF, Broken Auth, Broken AuthZ, and more. - ---- - -## CRITICAL: Safety Checks (ALWAYS run first) - -Before doing ANYTHING, you MUST confirm: - -1. **Authorization**: Ask the user — "Do you have explicit authorization to pentest this target?" If they say no or are unsure, STOP and explain they need written permission from the system owner. -2. **Environment**: Confirm the target is a local, staging, or sandboxed environment — NEVER production. -3. **Scope**: Clarify what they want tested (full pentest vs specific category). - -``` -⚠️ Shannon executes REAL ATTACKS with mutative effects. -├─ Only run on systems you OWN or have WRITTEN AUTHORIZATION to test -├─ Never target production environments -├─ Results require human review — LLM output may contain hallucinations -└─ You are responsible for complying with all applicable laws -``` - -Display this warning BEFORE every pentest run. If the user has already confirmed authorization in this session, a brief reminder suffices. - ---- - -## Parse User Intent - -Extract from the user's input: - -1. **TARGET_URL**: The URL to pentest (e.g., `http://localhost:3000`, `http://staging.example.com`) -2. **REPO_NAME**: The source code folder name (placed in `./repos/` inside Shannon) -3. **SCOPE**: Full pentest (default) or specific categories (injection, xss, ssrf, auth, authz) -4. **WORKSPACE**: Named workspace for resume capability (optional) -5. **CONFIG**: Custom YAML config path (optional, for auth flows, focus/avoid rules) - -Common invocation patterns: -- `/shannon http://localhost:3000 myapp` → Full pentest of local app -- `/shannon --workspace=audit1 http://staging.example.com backend-api` → Named workspace for resuming -- `/shannon --scope=xss,injection http://localhost:8080 frontend` → Targeted categories -- `/shannon status` → Check running pentests -- `/shannon results` → Show latest report -- `/shannon stop` → Stop running pentest - -Display parsed intent: -``` -🔐 Shannon Pentest -├─ Target: {TARGET_URL} -├─ Source: repos/{REPO_NAME} -├─ Scope: {SCOPE or "Full (all 5 OWASP categories)"} -├─ Workspace: {WORKSPACE or "auto-generated"} -└─ Config: {CONFIG or "default"} - -Estimated runtime: 1–1.5 hours │ Estimated cost: ~$50 (Claude Sonnet) -``` - ---- - -## Step 0: Ensure Shannon is Installed - -Check if Shannon is cloned locally: - -```bash -SHANNON_HOME="${SHANNON_HOME:-$HOME/shannon}" - -if [ -d "$SHANNON_HOME" ] && [ -f "$SHANNON_HOME/shannon" ]; then - echo "Shannon found at $SHANNON_HOME" - cd "$SHANNON_HOME" && git pull --ff-only 2>/dev/null || true -else - echo "Shannon not found. Cloning..." - git clone https://github.com/KeygraphHQ/shannon.git "$SHANNON_HOME" -fi - -# Verify Docker is available -if command -v docker &>/dev/null; then - echo "Docker: $(docker --version)" -else - echo "ERROR: Docker is required. Install Docker Desktop: https://docker.com/products/docker-desktop" - exit 1 -fi -``` - -If Shannon is not installed, clone it and inform the user. If Docker is missing, stop and tell them to install it. - -**SHANNON_HOME** defaults to `~/shannon`. Users can override with `SHANNON_HOME` env var. - ---- - -## Step 1: Prepare Source Code - -Shannon needs the target's source code in `$SHANNON_HOME/repos/{REPO_NAME}/`. - -Ask the user where their source code is: - -```bash -# If user provides a local path -REPO_PATH="/path/to/their/source" -REPO_NAME="myapp" - -# Create symlink or copy into Shannon's repos directory -mkdir -p "$SHANNON_HOME/repos" -if [ ! -d "$SHANNON_HOME/repos/$REPO_NAME" ]; then - ln -s "$(realpath "$REPO_PATH")" "$SHANNON_HOME/repos/$REPO_NAME" - echo "Linked $REPO_PATH → repos/$REPO_NAME" -fi -``` - -If the user provides a GitHub URL instead: -```bash -cd "$SHANNON_HOME/repos" -git clone "$GITHUB_URL" "$REPO_NAME" -``` - ---- - -## Step 2: Configure Authentication (if needed) - -If the target requires login, help the user create a YAML config: - -```yaml -# $SHANNON_HOME/configs/target-config.yaml -authentication: - type: form # "form" or "sso" - login_url: "http://localhost:3000/login" - credentials: - username: "admin" - password: "password123" - flow: "Navigate to login page, enter username and password, click Sign In" - success_condition: - url_contains: "/dashboard" - -rules: - avoid: - - "/logout" - - "/admin/delete" - focus: - - "/api/" - - "/auth/" - -pipeline: - max_concurrent_pipelines: 5 # 1-5, default 5 -``` - -**Only create a config if the target requires authentication or has specific scope rules.** For open/unauthenticated targets, no config is needed. - ---- - -## Step 3: Verify API Credentials - -Check that AI provider credentials are available: - -```bash -cd "$SHANNON_HOME" - -# Check for AI provider credentials -if [ -n "${ANTHROPIC_API_KEY:-}" ]; then - echo "✅ ANTHROPIC_API_KEY is set" -elif [ -n "${ANTHROPIC_AUTH_TOKEN:-}" ] && [ -n "${ANTHROPIC_BASE_URL:-}" ]; then - echo "✅ MiniMax mode: ANTHROPIC_AUTH_TOKEN + ANTHROPIC_BASE_URL are set" - echo " Base URL: $ANTHROPIC_BASE_URL" - echo " Model: ${ANTHROPIC_MODEL:-MiniMax-M2.7}" -elif [ -n "${CLAUDE_CODE_OAUTH_TOKEN:-}" ]; then - echo "✅ CLAUDE_CODE_OAUTH_TOKEN is set" -elif [ "${CLAUDE_CODE_USE_BEDROCK:-}" = "1" ]; then - echo "✅ AWS Bedrock mode enabled" -elif [ "${CLAUDE_CODE_USE_VERTEX:-}" = "1" ]; then - echo "✅ Google Vertex AI mode enabled" -else - echo "❌ No AI credentials found." - echo "Set one of: ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN+ANTHROPIC_BASE_URL (MiniMax), CLAUDE_CODE_OAUTH_TOKEN, or enable Bedrock/Vertex" - exit 1 -fi -``` - -If no credentials are found, explain the options: -- **Direct API** (recommended): `export ANTHROPIC_API_KEY=sk-ant-...` -- **MiniMax**: Set `ANTHROPIC_AUTH_TOKEN` and `ANTHROPIC_BASE_URL` (see MiniMax section below) -- **OAuth**: `export CLAUDE_CODE_OAUTH_TOKEN=...` -- **AWS Bedrock**: `export CLAUDE_CODE_USE_BEDROCK=1` + AWS credentials -- **Google Vertex**: `export CLAUDE_CODE_USE_VERTEX=1` + service account in `./credentials/` - -Also recommend: `export CLAUDE_CODE_MAX_OUTPUT_TOKENS=64000` - ---- - -## Step 4: Launch the Pentest - -**CRITICAL: Confirm with the user before launching.** Display the full command and wait for approval. - -```bash -cd "$SHANNON_HOME" - -# Build the command -CMD="./shannon start URL={TARGET_URL} REPO={REPO_NAME}" - -# Add optional flags -# CONFIG=configs/target-config.yaml (if auth config exists) -# WORKSPACE={WORKSPACE} (if user specified) -# OUTPUT=./audit-logs/ (default) - -echo "Ready to launch:" -echo " $CMD" -echo "" -echo "This will start Docker containers and begin the pentest." -echo "Runtime: ~1-1.5 hours │ Cost: ~\$50 (Claude Sonnet)" -``` - -After user confirms, run in background: -```bash -cd "$SHANNON_HOME" && ./shannon start URL={TARGET_URL} REPO={REPO_NAME} {EXTRA_FLAGS} -``` - -Use `run_in_background: true` with a timeout of 600000ms (10 minutes for initial setup). The pentest itself runs in Docker and will continue independently. - ---- - -## Step 5: Monitor Progress - -While the pentest runs, the user can check status: - -```bash -cd "$SHANNON_HOME" - -# List active workspaces -./shannon workspaces - -# View logs for a specific workflow -./shannon logs ID={workflow-id} -``` - -Explain the 5-phase pipeline: -``` -Shannon Pipeline (5 phases, parallel where possible): -├─ Phase 1: Pre-Recon — Source code analysis + external scans (Nmap, Subfinder, WhatWeb) -├─ Phase 2: Recon — Live attack surface mapping via browser automation -├─ Phase 3: Vulnerability Analysis — 5 parallel agents (Injection, XSS, SSRF, Auth, AuthZ) -├─ Phase 4: Exploitation — Dedicated agents execute real attacks to validate findings -└─ Phase 5: Reporting — Executive summary with reproducible PoCs -``` - ---- - -## Step 6: Read and Interpret Results - -Reports are saved to `$SHANNON_HOME/audit-logs/{hostname}_{sessionId}/`. - -```bash -cd "$SHANNON_HOME" - -# Find the latest report -LATEST=$(ls -td audit-logs/*/ 2>/dev/null | head -1) -if [ -n "$LATEST" ]; then - echo "Latest report: $LATEST" - # Find the main report file - find "$LATEST" -name "*.md" -type f | head -5 -fi -``` - -Read the report and present a summary: - -``` -🔐 Shannon Pentest Report: {TARGET} -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - -🔴 Critical: {N} vulnerabilities -🟠 High: {N} vulnerabilities -🟡 Medium: {N} vulnerabilities -🔵 Low: {N} vulnerabilities - -Top Findings: -1. [CRITICAL] {Vuln type} — {location} — PoC: {brief description} -2. [HIGH] {Vuln type} — {location} — PoC: {brief description} -3. ... - -Each finding includes a reproducible proof-of-concept exploit. -``` - -**IMPORTANT: Shannon's "no exploit, no report" policy means every finding has a working PoC.** But remind the user that LLM-generated content requires human review. - ---- - -## Utility Commands - -### Check status -```bash -cd "$SHANNON_HOME" && ./shannon workspaces -``` - -### View logs -```bash -cd "$SHANNON_HOME" && ./shannon logs ID={workflow-id} -``` - -### Stop pentest -```bash -cd "$SHANNON_HOME" && ./shannon stop -``` - -### Stop and clean up all data -```bash -# DESTRUCTIVE — confirm with user first -cd "$SHANNON_HOME" && ./shannon stop CLEAN=true -``` - -### Resume a previous workspace -```bash -cd "$SHANNON_HOME" && ./shannon start URL={URL} REPO={REPO} WORKSPACE={name} -``` - ---- - -## Targeting Local Apps - -If the user's app runs on localhost, explain: -``` -Shannon runs inside Docker. To reach your local app: -├─ Use http://host.docker.internal:{PORT} instead of http://localhost:{PORT} -├─ macOS/Windows: works automatically with Docker Desktop -└─ Linux: add --add-host=host.docker.internal:host-gateway to docker run -``` - -Automatically translate `localhost` URLs to `host.docker.internal` in the command. - ---- - -## Using MiniMax as AI Provider - -Shannon supports [MiniMax](https://platform.minimax.io) as an alternative AI backend via the Anthropic SDK compatibility layer. MiniMax provides the `MiniMax-M2.7` model through an Anthropic-compatible API endpoint. - -### MiniMax Setup - -1. **Get a MiniMax API key** from [platform.minimax.io](https://platform.minimax.io). - -2. **Configure environment variables** — either export them directly or add to `~/.claude/settings.json`: - -```bash -# Export directly -export ANTHROPIC_AUTH_TOKEN="your-minimax-api-key" -export ANTHROPIC_BASE_URL="https://api.minimax.io/anthropic" # International -# export ANTHROPIC_BASE_URL="https://api.minimaxi.com/anthropic" # China - -# Set model (all model slots use the same MiniMax model) -export ANTHROPIC_MODEL="MiniMax-M2.7" -export ANTHROPIC_SMALL_FAST_MODEL="MiniMax-M2.7" -export ANTHROPIC_DEFAULT_SONNET_MODEL="MiniMax-M2.7" -export ANTHROPIC_DEFAULT_OPUS_MODEL="MiniMax-M2.7" -export ANTHROPIC_DEFAULT_HAIKU_MODEL="MiniMax-M2.7" -``` - -Or in `~/.claude/settings.json`: -```json -{ - "env": { - "ANTHROPIC_AUTH_TOKEN": "your-minimax-api-key", - "ANTHROPIC_BASE_URL": "https://api.minimax.io/anthropic", - "ANTHROPIC_MODEL": "MiniMax-M2.7", - "ANTHROPIC_SMALL_FAST_MODEL": "MiniMax-M2.7", - "ANTHROPIC_DEFAULT_SONNET_MODEL": "MiniMax-M2.7", - "ANTHROPIC_DEFAULT_OPUS_MODEL": "MiniMax-M2.7", - "ANTHROPIC_DEFAULT_HAIKU_MODEL": "MiniMax-M2.7", - "API_TIMEOUT_MS": "3000000", - "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1" - } -} -``` - -3. **Clear conflicting env vars** — ensure `ANTHROPIC_API_KEY` is not set when using MiniMax, as it takes precedence: -```bash -unset ANTHROPIC_API_KEY -``` - -4. **Run Shannon normally** — the MiniMax credentials are passed through to Shannon's Docker containers via the Anthropic SDK compatibility layer: -```bash -cd "$SHANNON_HOME" && ./shannon start URL=http://localhost:3000 REPO=myapp -``` - -### MiniMax Notes -- MiniMax uses `ANTHROPIC_AUTH_TOKEN` (not `ANTHROPIC_API_KEY`) for authentication -- The `ANTHROPIC_BASE_URL` routes requests to MiniMax's Anthropic-compatible endpoint -- Set `API_TIMEOUT_MS=3000000` for extended timeouts (recommended for pentesting workloads) -- Set `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1` to reduce non-essential API calls -- MiniMax provides a single model (`MiniMax-M2.7`) that is used for all model slots - ---- - -## Configuration Reference - -### Environment Variables -| Variable | Required | Description | -|----------|----------|-------------| -| `ANTHROPIC_API_KEY` | One of these | Direct Anthropic API key | -| `ANTHROPIC_AUTH_TOKEN` | required | MiniMax (or compatible) auth token | -| `ANTHROPIC_BASE_URL` | | API base URL (for MiniMax: `https://api.minimax.io/anthropic`) | -| `ANTHROPIC_MODEL` | | Model override (e.g., `MiniMax-M2.7`) | -| `ANTHROPIC_SMALL_FAST_MODEL` | | Small/fast model override | -| `CLAUDE_CODE_OAUTH_TOKEN` | | Anthropic OAuth token | -| `CLAUDE_CODE_USE_BEDROCK` | | Set to `1` for AWS Bedrock | -| `CLAUDE_CODE_USE_VERTEX` | | Set to `1` for Google Vertex AI | -| `CLAUDE_CODE_MAX_OUTPUT_TOKENS` | Recommended | Set to `64000` | -| `API_TIMEOUT_MS` | Optional | Request timeout in ms (MiniMax: `3000000`) | -| `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` | Optional | Set to `1` to reduce non-essential calls | -| `SHANNON_HOME` | Optional | Shannon install dir (default: `~/shannon`) | - -### YAML Config Options -| Section | Field | Description | -|---------|-------|-------------| -| `authentication.type` | `form` / `sso` | Login method | -| `authentication.login_url` | URL | Login page | -| `authentication.credentials` | object | username, password, totp_secret | -| `authentication.flow` | string | Natural language login instructions | -| `authentication.success_condition` | object | `url_contains` or `element_present` | -| `rules.avoid` | list | Paths/subdomains to skip | -| `rules.focus` | list | Paths/subdomains to prioritize | -| `pipeline.retry_preset` | `subscription` | Extended backoff for rate-limited plans | -| `pipeline.max_concurrent_pipelines` | 1-5 | Parallel agent count (default: 5) | - ---- - -## Vulnerability Coverage - -Shannon tests 50+ specific cases across 5 OWASP categories: - -| Category | Examples | -|----------|----------| -| **Injection** | SQL injection, command injection, SSTI, NoSQL injection | -| **XSS** | Reflected, stored, DOM-based, via file upload | -| **SSRF** | Internal service access, cloud metadata, protocol smuggling | -| **Broken Auth** | Default creds, JWT flaws, session fixation, MFA bypass, CSRF | -| **Broken AuthZ** | IDOR, privilege escalation, path traversal, forced browsing | - ---- - -## Integrated Security Tools (bundled in Docker) - -- **Nmap** — port scanning and service detection -- **Subfinder** — subdomain enumeration -- **WhatWeb** — web technology fingerprinting -- **Schemathesis** — API schema-based fuzzing -- **Chromium** — headless browser for automated exploitation (Playwright) - ---- - -## Context Memory - -For the rest of this conversation, remember: -- **SHANNON_HOME**: Path to Shannon installation -- **TARGET_URL**: The URL being tested -- **REPO_NAME**: Source code folder name -- **WORKSPACE**: Workspace name (if any) -- **PENTEST_STATUS**: running / completed / stopped - -When the user asks follow-up questions: -- Check pentest status and report on progress -- Read and interpret new findings from audit-logs -- Help remediate discovered vulnerabilities with code fixes -- Explain PoC exploits and their impact - ---- - -## Security & Permissions - -**What this skill does:** -- Clones/updates the Shannon repo from GitHub to `~/shannon` (or `$SHANNON_HOME`) -- Creates symlinks from user's source code into `~/shannon/repos/` -- Starts Docker containers (Temporal server, worker, optional router) via `./shannon` CLI -- Reads pentest reports from `~/shannon/audit-logs/` -- Optionally creates YAML config files in `~/shannon/configs/` - -**What Shannon does (inside Docker):** -- Executes real exploits against the target URL (SQL injection, XSS, SSRF, etc.) -- Scans with Nmap, Subfinder, WhatWeb, Schemathesis -- Automates browser interactions via headless Chromium -- Sends prompts to Anthropic API (or Bedrock/Vertex) for reasoning -- Writes reports to `audit-logs/` directory - -**What this skill does NOT do:** -- Does not target any system without user confirmation -- Does not store or transmit API keys beyond the configured provider -- Does not modify the user's source code -- Does not access production systems unless explicitly directed (which it warns against) -- Does not run without Docker — all attack tools are containerized - -**Review the Shannon source code before first use:** https://github.com/KeygraphHQ/shannon diff --git a/shannon/scripts/setup-shannon.sh b/shannon/scripts/setup-shannon.sh deleted file mode 100755 index 74891a8..0000000 --- a/shannon/scripts/setup-shannon.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env bash -# setup-shannon.sh - Install or update Shannon pentester -# Usage: bash scripts/setup-shannon.sh [SHANNON_HOME] -set -euo pipefail - -SHANNON_HOME="${1:-${SHANNON_HOME:-$HOME/shannon}}" - -echo "🔐 Shannon Setup" -echo "━━━━━━━━━━━━━━━━" - -# Check Docker -if ! command -v docker &>/dev/null; then - echo "❌ Docker is required but not installed." - echo " Install: https://docker.com/products/docker-desktop" - exit 1 -fi -echo "✅ Docker: $(docker --version 2>/dev/null | head -1)" - -# Check git -if ! command -v git &>/dev/null; then - echo "❌ Git is required but not installed." - exit 1 -fi -echo "✅ Git: $(git --version)" - -# Clone or update Shannon -if [ -d "$SHANNON_HOME" ] && [ -f "$SHANNON_HOME/shannon" ]; then - echo "✅ Shannon found at $SHANNON_HOME" - echo " Updating..." - cd "$SHANNON_HOME" && git pull --ff-only 2>/dev/null || echo " (already up to date or can't fast-forward)" -else - echo "📥 Cloning Shannon to $SHANNON_HOME..." - git clone https://github.com/KeygraphHQ/shannon.git "$SHANNON_HOME" - echo "✅ Shannon cloned successfully" -fi - -# Check API credentials -echo "" -echo "API Credentials:" -if [ -n "${ANTHROPIC_API_KEY:-}" ]; then - echo "✅ ANTHROPIC_API_KEY is set" -elif [ -n "${ANTHROPIC_AUTH_TOKEN:-}" ] && [ -n "${ANTHROPIC_BASE_URL:-}" ]; then - echo "✅ MiniMax mode: ANTHROPIC_AUTH_TOKEN + ANTHROPIC_BASE_URL are set" - echo " Base URL: $ANTHROPIC_BASE_URL" - echo " Model: ${ANTHROPIC_MODEL:-MiniMax-M2.7}" -elif [ -n "${CLAUDE_CODE_OAUTH_TOKEN:-}" ]; then - echo "✅ CLAUDE_CODE_OAUTH_TOKEN is set" -elif [ "${CLAUDE_CODE_USE_BEDROCK:-}" = "1" ]; then - echo "✅ AWS Bedrock mode enabled" -elif [ "${CLAUDE_CODE_USE_VERTEX:-}" = "1" ]; then - echo "✅ Google Vertex AI mode enabled" -else - echo "⚠️ No AI credentials detected. Set one of:" - echo " export ANTHROPIC_API_KEY=sk-ant-..." - echo " export ANTHROPIC_AUTH_TOKEN=... + export ANTHROPIC_BASE_URL=https://api.minimax.io/anthropic (MiniMax)" - echo " export CLAUDE_CODE_OAUTH_TOKEN=..." - echo " export CLAUDE_CODE_USE_BEDROCK=1" - echo " export CLAUDE_CODE_USE_VERTEX=1" -fi - -echo "" -echo "Recommended: export CLAUDE_CODE_MAX_OUTPUT_TOKENS=64000" -echo "" -echo "Shannon is ready at: $SHANNON_HOME" -echo "Run a pentest: cd $SHANNON_HOME && ./shannon start URL=http://localhost:3000 REPO=myapp" diff --git a/shannon/scripts/sync.sh b/shannon/scripts/sync.sh deleted file mode 100755 index 2da838c..0000000 --- a/shannon/scripts/sync.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env bash -# sync.sh - Deploy shannon skill to all host locations -# Usage: bash scripts/sync.sh (run from repo root) -set -euo pipefail - -SRC="$(cd "$(dirname "$0")/.." && pwd)" -echo "Source: $SRC" - -TARGETS=( - "$HOME/.claude/skills/shannon" - "$HOME/.agents/skills/shannon" - "$HOME/.codex/skills/shannon" -) - -for t in "${TARGETS[@]}"; do - echo "" - echo "--- Syncing to $t ---" - mkdir -p "$t/scripts" - - cp "$SRC/SKILL.md" "$t/" - - # Helper scripts - if ls "$SRC/scripts/"*.sh &>/dev/null; then - rsync -a "$SRC/scripts/"*.sh "$t/scripts/" - fi - - echo " Deployed to $t" -done - -echo "" -echo "Sync complete."