fix: mount repos and configs directories into worker container (#107)

* feat: use static repos/ folder mount instead of dynamic TARGET_REPO

Replace dynamic per-run TARGET_REPO bind mount with a static ./repos:/repos
mount. Users place target repositories under ./repos/ and reference them by
folder name. This fixes stale mounts when switching targets and enables
running multiple scans concurrently against different repos.

* feat: mount configs directory into worker container

* docs: add instructions for repos and configs directory setup
This commit is contained in:
ezl-keygraph
2026-02-10 00:05:41 +05:30
committed by GitHub
parent 9bfbf1c3ec
commit b05c505e75
7 changed files with 40 additions and 32 deletions

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@ node_modules/
.env .env
audit-logs/ audit-logs/
dist/ dist/
repos/

View File

@@ -21,14 +21,14 @@ cp .env.example .env
# CLAUDE_CODE_MAX_OUTPUT_TOKENS=64000 # Prevents token limits during long reports # CLAUDE_CODE_MAX_OUTPUT_TOKENS=64000 # Prevents token limits during long reports
# Start a pentest workflow # Start a pentest workflow
./shannon start URL=<url> REPO=<path> ./shannon start URL=<url> REPO=<name>
``` ```
Examples: Examples:
```bash ```bash
./shannon start URL=https://example.com REPO=/path/to/repo ./shannon start URL=https://example.com REPO=repo-name
./shannon start URL=https://example.com REPO=/path/to/repo CONFIG=./configs/my-config.yaml ./shannon start URL=https://example.com REPO=repo-name CONFIG=./configs/my-config.yaml
./shannon start URL=https://example.com REPO=/path/to/repo OUTPUT=./my-reports ./shannon start URL=https://example.com REPO=repo-name OUTPUT=./my-reports
``` ```
### Monitoring Progress ### Monitoring Progress
@@ -62,7 +62,7 @@ TOTP generation is handled automatically via the `generate_totp` MCP tool during
npm run build npm run build
# Run with pipeline testing mode (fast, minimal deliverables) # Run with pipeline testing mode (fast, minimal deliverables)
./shannon start URL=<url> REPO=<path> PIPELINE_TESTING=true ./shannon start URL=<url> REPO=<name> PIPELINE_TESTING=true
``` ```
## Architecture & Components ## Architecture & Components
@@ -232,7 +232,7 @@ The application uses a comprehensive error handling system with:
### Testing Mode ### Testing Mode
The agent includes a testing mode that skips external tool execution for faster development cycles: The agent includes a testing mode that skips external tool execution for faster development cycles:
```bash ```bash
./shannon start URL=<url> REPO=<path> PIPELINE_TESTING=true ./shannon start URL=<url> REPO=<name> PIPELINE_TESTING=true
``` ```
### Security Focus ### Security Focus
@@ -274,7 +274,7 @@ Shannon supports routing Claude Agent SDK requests through alternative LLM provi
**Enable router mode:** **Enable router mode:**
```bash ```bash
./shannon start URL=<url> REPO=<path> ROUTER=true ./shannon start URL=<url> REPO=<name> ROUTER=true
``` ```
**Supported Providers:** **Supported Providers:**

View File

@@ -128,7 +128,7 @@ CLAUDE_CODE_MAX_OUTPUT_TOKENS=64000
EOF EOF
# 3. Run a pentest # 3. Run a pentest
./shannon start URL=https://your-app.com REPO=/path/to/your/repo ./shannon start URL=https://your-app.com REPO=your-repo
``` ```
Shannon will build the containers, start the workflow, and return a workflow ID. The pentest runs in the background. Shannon will build the containers, start the workflow, and return a workflow ID. The pentest runs in the background.
@@ -160,33 +160,34 @@ open http://localhost:8233
```bash ```bash
# Basic pentest # Basic pentest
./shannon start URL=https://example.com REPO=/path/to/repo ./shannon start URL=https://example.com REPO=repo-name
# With a configuration file # With a configuration file
./shannon start URL=https://example.com REPO=/path/to/repo CONFIG=./configs/my-config.yaml ./shannon start URL=https://example.com REPO=repo-name CONFIG=./configs/my-config.yaml
# Custom output directory # Custom output directory
./shannon start URL=https://example.com REPO=/path/to/repo OUTPUT=./my-reports ./shannon start URL=https://example.com REPO=repo-name OUTPUT=./my-reports
``` ```
### Prepare Your Repository ### Prepare Your Repository
Shannon is designed for **web application security testing** and expects all application code to be available in a single directory structure. This works well for: Shannon expects target repositories to be placed under the `./repos/` directory at the project root. The `REPO` flag refers to a folder name inside `./repos/`. Copy the repository you want to scan into `./repos/`, or clone it directly there:
- **Monorepos** - Single repository containing all components ```bash
- **Consolidated setups** - Multiple repositories organized in a shared folder git clone https://github.com/your-org/your-repo.git ./repos/your-repo
```
**For monorepos:** **For monorepos:**
```bash ```bash
git clone https://github.com/your-org/your-monorepo.git /path/to/your-app git clone https://github.com/your-org/your-monorepo.git ./repos/your-monorepo
``` ```
**For multi-repository applications** (e.g., separate frontend/backend): **For multi-repository applications** (e.g., separate frontend/backend):
```bash ```bash
mkdir /path/to/your-app mkdir ./repos/your-app
cd /path/to/your-app cd ./repos/your-app
git clone https://github.com/your-org/frontend.git git clone https://github.com/your-org/frontend.git
git clone https://github.com/your-org/backend.git git clone https://github.com/your-org/backend.git
git clone https://github.com/your-org/api.git git clone https://github.com/your-org/api.git
@@ -207,12 +208,12 @@ Works out of the box with Docker Desktop installed.
Docker containers cannot reach `localhost` on your host machine. Use `host.docker.internal` in place of `localhost`: Docker containers cannot reach `localhost` on your host machine. Use `host.docker.internal` in place of `localhost`:
```bash ```bash
./shannon start URL=http://host.docker.internal:3000 REPO=/path/to/repo ./shannon start URL=http://host.docker.internal:3000 REPO=repo-name
``` ```
### Configuration (Optional) ### Configuration (Optional)
While you can run without a config file, creating one enables authenticated testing and customized analysis. While you can run without a config file, creating one enables authenticated testing and customized analysis. Place your configuration files inside the `./configs/` directory — this folder is mounted into the Docker container automatically.
#### Create Configuration File #### Create Configuration File
@@ -281,7 +282,7 @@ ROUTER_DEFAULT=openai,gpt-5.2 # provider,model format
2. Run with `ROUTER=true`: 2. Run with `ROUTER=true`:
```bash ```bash
./shannon start URL=https://example.com REPO=/path/to/repo ROUTER=true ./shannon start URL=https://example.com REPO=repo-name ROUTER=true
``` ```
#### Experimental Models #### Experimental Models

View File

View File

@@ -29,10 +29,11 @@ services:
temporal: temporal:
condition: service_healthy condition: service_healthy
volumes: volumes:
- ./configs:/app/configs
- ./prompts:/app/prompts - ./prompts:/app/prompts
- ./audit-logs:/app/audit-logs - ./audit-logs:/app/audit-logs
- ${OUTPUT_DIR:-./audit-logs}:/app/output - ${OUTPUT_DIR:-./audit-logs}:/app/output
- ${TARGET_REPO:-.}:/target-repo - ./repos:/repos
- ${BENCHMARKS_BASE:-.}:/benchmarks - ${BENCHMARKS_BASE:-.}:/benchmarks
shm_size: 2gb shm_size: 2gb
ipc: host ipc: host

View File

27
shannon
View File

@@ -25,13 +25,14 @@ show_help() {
AI Penetration Testing Framework AI Penetration Testing Framework
Usage: Usage:
./shannon start URL=<url> REPO=<path> Start a pentest workflow ./shannon start URL=<url> REPO=<name> Start a pentest workflow
./shannon logs ID=<workflow-id> Tail logs for a specific workflow ./shannon logs ID=<workflow-id> Tail logs for a specific workflow
./shannon query ID=<workflow-id> Query workflow progress ./shannon query ID=<workflow-id> Query workflow progress
./shannon stop Stop all containers ./shannon stop Stop all containers
./shannon help Show this help message ./shannon help Show this help message
Options for 'start': Options for 'start':
REPO=<name> Folder name under ./repos/ (e.g. REPO=repo-name)
CONFIG=<path> Configuration file (YAML) CONFIG=<path> Configuration file (YAML)
OUTPUT=<path> Output directory for reports (default: ./audit-logs/) OUTPUT=<path> Output directory for reports (default: ./audit-logs/)
PIPELINE_TESTING=true Use minimal prompts for fast testing PIPELINE_TESTING=true Use minimal prompts for fast testing
@@ -41,9 +42,9 @@ Options for 'stop':
CLEAN=true Remove all data including volumes CLEAN=true Remove all data including volumes
Examples: Examples:
./shannon start URL=https://example.com REPO=/path/to/repo ./shannon start URL=https://example.com REPO=repo-name
./shannon start URL=https://example.com REPO=/path/to/repo CONFIG=./config.yaml ./shannon start URL=https://example.com REPO=repo-name CONFIG=./config.yaml
./shannon start URL=https://example.com REPO=/path/to/repo OUTPUT=./my-reports ./shannon start URL=https://example.com REPO=repo-name OUTPUT=./my-reports
./shannon logs ID=example.com_shannon-1234567890 ./shannon logs ID=example.com_shannon-1234567890
./shannon query ID=shannon-1234567890 ./shannon query ID=shannon-1234567890
./shannon stop CLEAN=true ./shannon stop CLEAN=true
@@ -119,7 +120,7 @@ cmd_start() {
# Validate required vars # Validate required vars
if [ -z "$URL" ] || [ -z "$REPO" ]; then if [ -z "$URL" ] || [ -z "$REPO" ]; then
echo "ERROR: URL and REPO are required" echo "ERROR: URL and REPO are required"
echo "Usage: ./shannon start URL=<url> REPO=<path>" echo "Usage: ./shannon start URL=<url> REPO=<name>"
exit 1 exit 1
fi fi
@@ -136,16 +137,20 @@ cmd_start() {
fi fi
# Determine container path for REPO # Determine container path for REPO
# - If REPO is already a container path (/benchmarks/*, /target-repo), use as-is # - If REPO is already a container path (/benchmarks/*, /repos/*), use as-is
# - Otherwise, it's a host path - mount to /target-repo and use that # - Otherwise, treat as a folder name under ./repos/ (mounted at /repos in container)
case "$REPO" in case "$REPO" in
/benchmarks/*|/target-repo|/target-repo/*) /benchmarks/*|/repos/*)
CONTAINER_REPO="$REPO" CONTAINER_REPO="$REPO"
;; ;;
*) *)
# Host path - export for docker-compose mount if [ ! -d "./repos/$REPO" ]; then
export TARGET_REPO="$REPO" echo "ERROR: Repository not found at ./repos/$REPO"
CONTAINER_REPO="/target-repo" echo ""
echo "Place your target repository under the ./repos/ directory"
exit 1
fi
CONTAINER_REPO="/repos/$REPO"
;; ;;
esac esac