From 1c2b29bdd2c34e4f4ec631da69f7dbe7cc09489d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 25 Nov 2025 23:39:21 +0000 Subject: [PATCH 1/2] Initial plan From 4097006592aaf143f8249bf7190a0c07b5cc7452 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 25 Nov 2025 23:49:58 +0000 Subject: [PATCH 2/2] docs: add comprehensive cli reference documentation Co-authored-by: Mossaka <5447827+Mossaka@users.noreply.github.com> --- .../content/docs/reference/cli-reference.md | 719 ++++++++++++++++++ 1 file changed, 719 insertions(+) create mode 100644 docs-site/src/content/docs/reference/cli-reference.md diff --git a/docs-site/src/content/docs/reference/cli-reference.md b/docs-site/src/content/docs/reference/cli-reference.md new file mode 100644 index 000000000..108d47f10 --- /dev/null +++ b/docs-site/src/content/docs/reference/cli-reference.md @@ -0,0 +1,719 @@ +--- +title: CLI Reference +description: Complete reference for all command-line options and arguments for the awf firewall tool. +--- + +Complete reference for the `awf` command-line interface. + +## Synopsis + +```bash +awf [options] -- +``` + +The `awf` command creates an isolated Docker environment with network firewall rules that restrict outbound HTTP/HTTPS traffic to whitelisted domains only. + +:::caution[Requires sudo] +The firewall manipulates iptables rules and requires root privileges. Always run with `sudo` or `sudo -E` (to preserve environment variables). +::: + +## Basic Examples + +```bash +# Simple HTTP request +sudo awf --allow-domains github.com -- curl https://api.github.com + +# With environment variables preserved +sudo -E awf --allow-domains github.com -- 'echo $HOME' + +# Running GitHub Copilot CLI +sudo -E awf \ + --allow-domains github.com,api.github.com \ + -- npx @github/copilot@latest --prompt "your prompt" +``` + +## Command Argument + +The command and its arguments must be specified after the `--` separator. + +### Single vs Multiple Arguments + +**Single argument (quoted command):** +```bash +# Shell variables expand in container, not on host +sudo awf --allow-domains github.com -- 'echo $HOME && pwd' +``` + +**Multiple arguments:** +```bash +# Each argument is shell-escaped automatically +sudo awf --allow-domains github.com -- curl -H "Auth: token" https://api.github.com +``` + +:::tip[When to quote] +Use quotes when your command contains shell operators (`&&`, `||`, `|`, `>`, `<`) or variables (`$VAR`) that should expand in the container, not on the host. +::: + +## Options + +### Domain Whitelisting + +#### `--allow-domains ` + +Comma-separated list of allowed domains. + +- **Type**: String (comma-separated) +- **Required**: Yes (unless `--allow-domains-file` is provided) +- **Example**: `--allow-domains github.com,api.github.com` + +Domains automatically match all subdomains: +- `github.com` matches `api.github.com`, `raw.githubusercontent.com`, etc. +- Domains are normalized: case-insensitive, protocols and trailing slashes removed + +**Examples:** +```bash +# Single domain +sudo awf --allow-domains github.com -- curl https://api.github.com + +# Multiple domains +sudo awf --allow-domains github.com,npmjs.org,googleapis.com -- curl https://api.github.com +``` + +:::note +Domain matching is case-insensitive and automatically includes all subdomains. You don't need to specify `api.github.com` if you've already whitelisted `github.com`. +::: + +#### `--allow-domains-file ` + +Path to file containing allowed domains. + +- **Type**: String (file path) +- **Required**: Yes (unless `--allow-domains` is provided) +- **Example**: `--allow-domains-file /path/to/domains.txt` + +**File format:** +- One domain per line or comma-separated +- Comments start with `#` (full line or inline) +- Empty lines are ignored +- Whitespace is automatically trimmed + +**Example file:** +```text +# GitHub domains +github.com +api.github.com + +# NPM registry +npmjs.org, registry.npmjs.org + +# Example with inline comment +example.com # Example domain +``` + +**Usage:** +```bash +sudo awf --allow-domains-file allowed-domains.txt -- curl https://api.github.com +``` + +**Combining both:** +```bash +# Domains from both sources are merged +sudo awf \ + --allow-domains github.com \ + --allow-domains-file additional-domains.txt \ + -- curl https://api.github.com +``` + +### Logging + +#### `--log-level ` + +Set logging verbosity. + +- **Type**: String +- **Options**: `debug`, `info`, `warn`, `error` +- **Default**: `info` +- **Example**: `--log-level debug` + +**Log levels:** +- `debug`: Detailed information including config, container startup, iptables rules +- `info`: Normal operational messages (default) +- `warn`: Warning messages +- `error`: Error messages only + +**Usage:** +```bash +# Debug mode for troubleshooting +sudo awf --allow-domains github.com --log-level debug -- curl https://api.github.com + +# Quiet mode (errors only) +sudo awf --allow-domains github.com --log-level error -- curl https://api.github.com +``` + +:::tip[Debugging Blocked Domains] +Use `--log-level debug` to see the normalized domain list and detailed traffic logs when debugging connection issues. +::: + +### Container Management + +#### `--keep-containers` + +Keep containers and configuration files after command exits. + +- **Type**: Boolean flag +- **Default**: `false` +- **Example**: `--keep-containers` + +When enabled: +- Containers remain running after command completes +- Configuration files preserved in work directory +- Log files remain in work directory +- Host iptables rules remain active + +**Usage:** +```bash +# Keep containers for inspection +sudo awf --allow-domains github.com --keep-containers -- curl https://api.github.com + +# Inspect logs after execution +cat /tmp/awf-*/squid-logs/access.log +docker logs awf-squid +docker logs awf-copilot + +# Manual cleanup when done +docker stop awf-squid awf-copilot +docker network rm awf-net +``` + +:::caution[Manual Cleanup Required] +With `--keep-containers`, you must manually stop containers and remove the network: +```bash +docker stop awf-squid awf-copilot +docker network rm awf-net +``` +::: + +#### `--tty` + +Allocate a pseudo-TTY for the container. + +- **Type**: Boolean flag +- **Default**: `false` +- **Example**: `--tty` + +Required for interactive tools that expect terminal input/output (e.g., Claude Code, interactive shells). + +**Usage:** +```bash +# For interactive tools +sudo awf --allow-domains anthropic.com --tty -- claude-code + +# Not needed for non-interactive commands +sudo awf --allow-domains github.com -- curl https://api.github.com +``` + +:::note +Most commands don't need `--tty`. Only use it for interactive tools that display prompts or expect user input. +::: + +#### `--work-dir ` + +Working directory for temporary files. + +- **Type**: String (directory path) +- **Default**: `/tmp/awf-` +- **Example**: `--work-dir /tmp/my-awf-workspace` + +The work directory contains: +- `squid.conf` - Generated Squid proxy configuration +- `docker-compose.yml` - Generated Docker Compose configuration +- `copilot-logs/` - Copilot CLI logs (if created) +- `squid-logs/` - Squid proxy logs (if created) + +**Usage:** +```bash +# Use specific work directory +sudo awf --allow-domains github.com --work-dir /tmp/my-workspace -- curl https://api.github.com + +# Inspect generated configs +cat /tmp/my-workspace/squid.conf +cat /tmp/my-workspace/docker-compose.yml +``` + +### Container Images + +#### `--build-local` + +Build containers locally instead of using pre-built GHCR images. + +- **Type**: Boolean flag +- **Default**: `false` +- **Example**: `--build-local` + +**Usage:** +```bash +# Build containers from local Dockerfiles +sudo awf --allow-domains github.com --build-local -- curl https://api.github.com +``` + +:::tip[Development Mode] +Use `--build-local` when developing the firewall itself to test local changes to container images. +::: + +#### `--image-registry ` + +Container image registry to pull images from. + +- **Type**: String (registry URL) +- **Default**: `ghcr.io/githubnext/gh-aw-firewall` +- **Example**: `--image-registry my-registry.example.com/awf` + +**Usage:** +```bash +# Use custom registry +sudo awf \ + --allow-domains github.com \ + --image-registry my-registry.example.com/awf \ + -- curl https://api.github.com +``` + +#### `--image-tag ` + +Container image tag to use. + +- **Type**: String (tag name) +- **Default**: `latest` +- **Example**: `--image-tag v0.4.0` + +**Usage:** +```bash +# Use specific version +sudo awf \ + --allow-domains github.com \ + --image-tag v0.4.0 \ + -- curl https://api.github.com +``` + +### Environment Variables + +#### `-e, --env ` + +Pass additional environment variables to the container. + +- **Type**: String in `KEY=VALUE` format +- **Repeatable**: Yes (specify multiple times) +- **Default**: `[]` (empty array) +- **Example**: `-e MY_VAR=value -e ANOTHER=123` + +**Usage:** +```bash +# Single environment variable +sudo awf --allow-domains github.com -e DEBUG=true -- curl https://api.github.com + +# Multiple environment variables +sudo awf \ + --allow-domains github.com \ + -e API_KEY=secret \ + -e REGION=us-west \ + -- 'echo $API_KEY' +``` + +:::tip[Preserving Host Variables] +To pass host environment variables, use `sudo -E` and then reference them in `-e`: +```bash +export MY_TOKEN="secret123" +sudo -E awf --allow-domains github.com -e MY_TOKEN=$MY_TOKEN -- 'echo $MY_TOKEN' +``` +::: + +#### `--env-all` + +Pass all host environment variables to the container. + +- **Type**: Boolean flag +- **Default**: `false` +- **Example**: `--env-all` + +Excludes system variables like `PATH`, `DOCKER_HOST` that could cause conflicts. + +**Usage:** +```bash +# Pass all environment variables +sudo -E awf --allow-domains github.com --env-all -- env +``` + +:::danger[Security Risk] +Using `--env-all` may expose sensitive credentials in logs or configurations. Use `-e` to pass specific variables instead when possible. +::: + +### Volume Mounts + +#### `-v, --mount ` + +Mount host directories or files into the container. + +- **Type**: String in `host_path:container_path[:mode]` format +- **Repeatable**: Yes (specify multiple times) +- **Default**: `[]` (empty array) +- **Example**: `-v /data:/data:ro -v /tmp/output:/output:rw` + +**Format:** +- `host_path`: Absolute path on host (must exist) +- `container_path`: Absolute path in container +- `mode`: Optional - `ro` (read-only) or `rw` (read-write) + +**Validation:** +- Both paths must be absolute (start with `/`) +- Host path must exist +- Mode must be `ro` or `rw` if specified + +**Usage:** +```bash +# Mount directory read-only +sudo awf --allow-domains github.com -v /data:/data:ro -- ls /data + +# Mount directory read-write +sudo awf --allow-domains github.com -v /tmp/output:/output:rw -- touch /output/test.txt + +# Multiple mounts +sudo awf \ + --allow-domains github.com \ + -v /data:/data:ro \ + -v /tmp/output:/output:rw \ + -- ls /data /output +``` + +:::note[Default Mounts] +The firewall automatically mounts: +- Host filesystem at `/host` (read-only) +- User home directory at the same path (read-write) +- Docker socket at `/var/run/docker.sock` (for Docker-in-Docker) + +Additional mounts via `-v` are added to these default mounts. +::: + +#### `--container-workdir ` + +Set the working directory inside the container. + +- **Type**: String (directory path) +- **Default**: Home directory of the user running the command +- **Example**: `--container-workdir /workspace` + +**Usage:** +```bash +# Set container working directory +sudo awf \ + --allow-domains github.com \ + --container-workdir /workspace \ + -- pwd +``` + +:::tip[GitHub Actions Path Consistency] +In GitHub Actions, set to `$GITHUB_WORKSPACE` to maintain path consistency: +```yaml +- run: | + sudo -E awf \ + --allow-domains github.com \ + --container-workdir $GITHUB_WORKSPACE \ + -- npm test +``` +::: + +## Exit Codes + +The firewall propagates the exit code from the wrapped command: + +- `0`: Command succeeded +- `1-255`: Command exit code (or firewall error) +- `130`: Interrupted by SIGINT (Ctrl+C) +- `143`: Terminated by SIGTERM + +**Example:** +```bash +# Command succeeds (exit 0) +sudo awf --allow-domains github.com -- curl https://api.github.com +echo $? # Outputs: 0 + +# Command fails (exit non-zero) +sudo awf --allow-domains github.com -- curl https://nonexistent.invalid +echo $? # Outputs: non-zero (curl's exit code) +``` + +## Common Usage Patterns + +### Basic HTTP Request + +```bash +sudo awf --allow-domains github.com -- curl https://api.github.com/zen +``` + +### GitHub Copilot CLI + +```bash +export GITHUB_TOKEN="your_token" +sudo -E awf \ + --allow-domains github.com,api.github.com,githubusercontent.com,googleapis.com,api.enterprise.githubcopilot.com \ + -- npx @github/copilot@latest --prompt "List my repositories" +``` + +:::tip[Preserving Environment Variables] +Use `sudo -E` instead of just `sudo` to preserve environment variables like `GITHUB_TOKEN`. +::: + +### Docker-in-Docker + +```bash +# Spawned containers inherit firewall restrictions +sudo awf \ + --allow-domains api.github.com,registry-1.docker.io,auth.docker.io \ + -- docker run --rm curlimages/curl -fsS https://api.github.com/zen +``` + +### Using Domains File + +```bash +# Create domains file +cat > domains.txt << 'EOF' +# GitHub +github.com +githubusercontent.com + +# NPM +npmjs.org +EOF + +# Use the file +sudo awf --allow-domains-file domains.txt -- npm install +``` + +### Custom Environment and Mounts + +```bash +sudo awf \ + --allow-domains github.com \ + -e API_KEY=secret123 \ + -e DEBUG=true \ + -v /data:/data:ro \ + -v /tmp/output:/output:rw \ + -- 'curl -H "X-API-Key: $API_KEY" https://api.github.com > /output/result.json' +``` + +### Debugging with Keep Containers + +```bash +# Run with containers preserved +sudo awf \ + --allow-domains github.com \ + --keep-containers \ + --log-level debug \ + -- curl https://api.github.com + +# Inspect logs after execution +docker logs awf-squid +docker logs awf-copilot +cat /tmp/awf-*/squid-logs/access.log + +# Clean up manually when done +docker stop awf-squid awf-copilot +docker network rm awf-net +``` + +## Troubleshooting + +### Common Errors + +#### "No command specified" + +**Error:** +``` +Error: No command specified. Use -- to separate command from options. +Example: awf --allow-domains github.com -- curl https://api.github.com +``` + +**Cause**: Missing `--` separator before the command. + +**Solution**: Always use `--` to separate options from the command: +```bash +# Wrong +sudo awf --allow-domains github.com curl https://api.github.com + +# Correct +sudo awf --allow-domains github.com -- curl https://api.github.com +``` + +#### "At least one domain must be specified" + +**Error:** +``` +At least one domain must be specified with --allow-domains or --allow-domains-file +``` + +**Cause**: Neither `--allow-domains` nor `--allow-domains-file` was provided. + +**Solution**: Specify at least one domain: +```bash +sudo awf --allow-domains github.com -- curl https://api.github.com +``` + +#### "Invalid environment variable format" + +**Error:** +``` +Invalid environment variable format: MYVAR (expected KEY=VALUE) +``` + +**Cause**: Environment variable not in `KEY=VALUE` format. + +**Solution**: Use proper format: +```bash +# Wrong +sudo awf -e MYVAR -- command + +# Correct +sudo awf -e MYVAR=value -- command +``` + +#### "Invalid volume mount" + +**Error:** +``` +Invalid volume mount: /data +Reason: Mount must be in format host_path:container_path[:mode] +``` + +**Cause**: Volume mount not in correct format. + +**Solution**: Use `host_path:container_path[:mode]` format: +```bash +# Wrong +sudo awf -v /data -- command + +# Correct +sudo awf -v /data:/data:ro -- command +``` + +#### "Host path must be absolute" + +**Error:** +``` +Invalid volume mount: data:/data +Reason: Host path must be absolute (start with /) +``` + +**Cause**: Relative path used for host path. + +**Solution**: Use absolute paths: +```bash +# Wrong +sudo awf -v data:/data -- command + +# Correct +sudo awf -v /home/user/data:/data -- command +``` + +#### "Host path does not exist" + +**Error:** +``` +Invalid volume mount: /nonexistent:/data +Reason: Host path does not exist: /nonexistent +``` + +**Cause**: Host path doesn't exist. + +**Solution**: Create the directory first or verify the path: +```bash +mkdir -p /home/user/data +sudo awf -v /home/user/data:/data -- command +``` + +### Connection Issues + +#### Domain Blocked But Should Be Allowed + +**Symptoms**: Connection fails even though domain is in `--allow-domains`. + +**Diagnosis:** +```bash +# Check Squid logs for blocked domains +sudo cat /tmp/squid-logs-*/access.log | grep TCP_DENIED +``` + +**Common causes:** + +1. **Subdomain mismatch**: Verify the base domain is whitelisted + ```bash + # ✗ Whitelisted api.github.com but accessing raw.githubusercontent.com + sudo awf --allow-domains api.github.com -- curl https://raw.githubusercontent.com/... + + # ✓ Whitelist the base domain + sudo awf --allow-domains githubusercontent.com -- curl https://raw.githubusercontent.com/... + ``` + +2. **IP-based access**: Firewall blocks direct IP connections + ```bash + # ✗ Using IP address + sudo awf --allow-domains github.com -- curl https://140.82.121.3 + + # ✓ Use domain name + sudo awf --allow-domains github.com -- curl https://api.github.com + ``` + +3. **Typo in domain**: Check for spelling errors + ```bash + # Use debug mode to see normalized domains + sudo awf --allow-domains github.com --log-level debug -- curl https://api.github.com + ``` + +## Environment Variables + +The firewall recognizes these environment variables when passed via `-e` or `--env-all`: + +### GitHub Tokens + +- `GITHUB_TOKEN`: GitHub Copilot CLI authentication token +- `GITHUB_PERSONAL_ACCESS_TOKEN`: GitHub MCP server authentication token + +**Usage:** +```bash +export GITHUB_TOKEN="your_copilot_token" +export GITHUB_PERSONAL_ACCESS_TOKEN="your_github_pat" + +sudo -E awf \ + --allow-domains github.com \ + -e GITHUB_TOKEN=$GITHUB_TOKEN \ + -e GITHUB_PERSONAL_ACCESS_TOKEN=$GITHUB_PERSONAL_ACCESS_TOKEN \ + -- npx @github/copilot@latest --prompt "your prompt" +``` + +### GitHub Actions Variables + +When running in GitHub Actions, use `--container-workdir` for path consistency: + +```yaml +- name: Run with firewall + env: + GITHUB_TOKEN: ${{ secrets.COPILOT_CLI_TOKEN }} + run: | + sudo -E awf \ + --allow-domains github.com \ + --container-workdir $GITHUB_WORKSPACE \ + -e GITHUB_TOKEN=$GITHUB_TOKEN \ + -- npm test +``` + +## Version Information + +```bash +# Display version +awf --version + +# Display help +awf --help +``` + +## See Also + +- [Architecture](/gh-aw-firewall/reference/architecture) - How the firewall works internally +- [Troubleshooting](/gh-aw-firewall/troubleshooting) - Common issues and solutions