Skip to content

Latest commit

 

History

History
810 lines (639 loc) · 29.1 KB

File metadata and controls

810 lines (639 loc) · 29.1 KB

Troubleshooting

Diagnosing a specific failure? Start at the canonical diagnosis registry in docs/diagnostics/README.md, or load the diagnose-awf skill. This guide remains the broad troubleshooting reference.

Domain Access Issues

Domain is Blocked

Problem: Request to allowed domain is being blocked

Solution:

  1. Check domain spelling in --allow-domains
  2. Add subdomains if needed (e.g., api.github.com in addition to github.com)
  3. Enable debug logging to see Squid access logs:
    sudo awf \
      --allow-domains github.com \
      --log-level debug \
      'your-command'
  4. Check Squid logs for blocked requests:
    sudo grep "TCP_DENIED" /tmp/squid-logs-<timestamp>/access.log

Copilot Web Tools Unavailable in API Proxy Mode

Problem: With engine: copilot, tools: web-fetch: or tools: web-search: compiles successfully, but Copilot never exposes web_fetch or web_search. Squid sees no requests to the expected domains, even when they are allowlisted.

Cause: AWF's Copilot API proxy flow sets COPILOT_OFFLINE=true and points COPILOT_PROVIDER_BASE_URL at the sidecar (by default, http://172.30.0.30:10002). Offline mode skips GitHub authentication, keeping real credentials exclusively in the sidecar, but Copilot CLI also disables its native web tools. --allow-tool web_fetch / --allow-tool web_search cannot enable tools absent from the catalog. AWF warns about this limitation when Copilot sidecar routing is active and the agent domain allowlist is non-empty.

Workaround: Ask the agent to fetch content using curl from bash instead. Allow both the shell tool and the destination URL in Copilot CLI, as well as the domain in AWF. In a gh-aw workflow, use:

engine:
  id: copilot
  args: ["--allow-url", "osv.dev"]
network:
  allowed: ["osv.dev"]
tools:
  bash: ["curl"]

Prompt the agent to run curl --fail --location https://osv.dev/. Merge these settings with the workflow's existing tools and network allowlist, and allow any redirect destinations that are needed. Under --no-ask-user, shell permission alone is insufficient: without URL permission, Copilot reports Permission denied and could not request permission from user.

Alternatively, use engine.args: ["--allow-all-urls"] to approve URLs at the Copilot CLI layer. Neither --allow-url nor --allow-all-urls bypasses AWF: Squid still enforces network.allowed (or --allow-domains for direct AWF use). This workaround fetches known URLs; it does not restore native web search. Do not disable offline mode or expose real credentials to the agent to work around this limitation.

Compiler-side warning or an MCP fetch fallback is tracked in github/gh-aw#65043. AWF receives the command and domain allowlist, not gh-aw's tools declarations, so its startup warning cannot identify which native web tools were requested.

Copilot BYOK Sub-Agent Model/API Mismatch

Problem: Copilot CLI sub-agents using a model from a different wire-API family than the session's main model can fail with an upstream 400 response. For example, GPT-5 models use the Responses API, while Claude models use Chat Completions. BYOK configures one wire API for the Copilot CLI session, including requests made by sub-agents.

Workaround: Use sub-agent models that use the same wire API as the main model. With model routing, each sub-agent model must also match the wire API of every model that can be selected for the main session. AWF preserves an explicitly configured COPILOT_PROVIDER_WIRE_API; otherwise it selects the Responses API when COPILOT_MODEL is a GPT-5-family or o3 model.

Copilot CLI does not currently expose per-model BYOK wire-API configuration through its provider environment variables. Compile-time warnings and guidance in gh-aw's sub-agent reference need to be implemented in the github/gh-aw repository.

Container Issues

Container Won't Start

Problem: Docker Compose fails to start containers

Solution:

  1. Ensure Docker is running:
    docker ps
  2. Check for port conflicts (port 3128 must be available):
    netstat -tulpn | grep 3128
  3. Verify Docker Compose is installed:
    docker compose version
  4. Check for orphaned networks:
    docker network ls | grep awf
    If found, clean them up:
    docker network rm awf-net

Network Name Collision

Problem: Docker Compose repeatedly warns a network with name awf-net exists but was not created for project "awf-<timestamp>" and containers never start.

Cause: A previous AWF run was killed (timeout, SIGKILL, runner eviction) before its Docker network was removed. Compose will not attach to a fixed-name network that belongs to a different project.

Solution: AWF now reclaims these orphaned networks automatically before docker compose up. If the network still cannot be removed (for example, a live container from another tool is attached to it), remove it manually:

docker network inspect awf-net

Stop or force-disconnect each attached endpoint listed by the inspection, then remove the network:

docker stop <container>
docker network disconnect -f awf-net <container>
docker network rm awf-net

Self-Hosted Runner Issues

ARC / DinD Split Filesystem

Problem: Bind-mounted files exist on the runner, but AWF containers report ENOENT for /tmp/... or other mounted paths.

Cause: The Docker daemon is running in a DinD sidecar or other split-filesystem setup, so bind mounts resolve against the daemon filesystem instead of the runner filesystem.

Solution:

  1. Check whether DOCKER_HOST points to a non-default socket or tcp:// endpoint:
    echo "$DOCKER_HOST"
  2. Verify the split with a sentinel probe:
    SENTINEL="/tmp/awf-split-fs-test"
    echo ok > "$SENTINEL"
    docker run --rm -v /tmp:/tmp alpine sh -lc "ls -l $SENTINEL"
    If the file is missing in the container, the daemon cannot see the runner filesystem directly.
  3. Set a daemon-visible prefix such as:
    awf --docker-host-path-prefix /tmp/gh-aw ...
  4. For stdin JSON/YAML config, use:
    {
      "container": {
        "dockerHostPathPrefix": "/tmp/gh-aw"
      }
    }
  5. See ARC + DinD Configuration for staging options like chroot.binariesSourcePath and dind.stageEngineBinary.

Non-Standard Runner Home

Problem: Paths under /home/runner are wrong on a self-hosted runner, or tools installed under the real $HOME are not found.

Solution:

  1. Confirm the actual runner home:
    echo "$HOME"
  2. If you are passing stdin config, set the real home via chroot.identity.home.
  3. If the missing tool lives in a runner-managed toolcache, also check whether it was installed under $HOME/work/_tool rather than /opt/hostedtoolcache.
  4. For DinD chroot setups, review Chroot Mode and ARC + DinD Configuration to ensure the runner home and runner-installed binaries are visible inside the chroot.

IPv6-Disabled Docker and Squid Startup Failures

Problem: Squid exits with FATAL: http_port: IPv6 is not available or Bungled squid.conf ... [::]:3128.

Solution:

  1. Check Docker's IPv6 state:
    docker info | grep -i ipv6
  2. If the container is still available, inspect the kernel switch inside it:
    docker exec awf-squid cat /proc/sys/net/ipv6/conf/all/disable_ipv6
  3. Enable Docker/kernel IPv6 on the host (required with current AWF builds), or use a custom AWF build that removes the [::] listener.

Corporate Upstream Proxy

Problem: All outbound traffic fails on a self-hosted runner that must reach the internet through a corporate HTTP proxy.

Solution:

  1. Check whether the host already exports proxy variables:
    env | grep -i proxy
  2. AWF automatically reads host https_proxy / http_proxy values and configures Squid cache_peer chaining. If auto-detection is ambiguous, set --upstream-proxy explicitly.
  3. Verify that the generated Squid config includes the upstream proxy:
    docker exec awf-squid grep cache_peer /etc/squid/squid.conf
  4. See Environment Variables for the full upstream-proxy configuration model.

GHES / GHEC / Data Residency Routing

Problem: Copilot auth or gh CLI commands fail on enterprise hosts with symptoms such as:

  • none of the git remotes correspond to the GH_HOST environment variable
  • 400 bad request: Authorization header is badly formatted
  • invalid API key during *.ghe.com token exchange

Solution:

  1. Verify the GitHub host context:
    echo "$GITHUB_SERVER_URL"
    echo "$GH_HOST"
  2. Ensure AWF is recent enough for your platform, especially for GHES auth-header fixes.
  3. If your enterprise setup needs a manual override, set:
    awf --copilot-api-target <enterprise-copilot-endpoint> ...
  4. Review GitHub Enterprise Configuration for the expected endpoint derivation and allowlist behavior.

OpenAI Codex auto Model Fails Under AWF

Problem: A Codex run inside AWF fails with messages such as:

  • Unknown model auto is used
  • The requested model is not supported
  • chatgpt authentication required for remote plugin catalog; api key auth is not supported

Cause: When Codex uses the OpenAI-native endpoint, its auto model alias relies on ChatGPT-authenticated remote model/plugin metadata. AWF's API proxy uses API-key credential injection, so the ChatGPT catalog lookup cannot be used even if chatgpt.com is on the network allowlist.

Solution: Set an explicit Codex model instead of auto, for example model: gpt-5.3-codex in workflow frontmatter or codex exec --model gpt-5.3-codex ... for direct CLI usage.

When using the GitHub Copilot provider, copilot/auto is routed on Responses requests using the available Copilot model inventory; Chat Completions requests retain Copilot's native auto behavior.

Permission Issues

iptables Permission Denied

Problem: Permission denied: iptables commands require root privileges

Solution:

  • All commands MUST be run with sudo for host-level iptables manipulation
  • Run: sudo awf --allow-domains ... 'your-command'
  • In GitHub Actions, the runner already has root access (no sudo needed)

DOCKER-USER Chain Missing

Problem: DOCKER-USER chain does not exist

Solution:

  • Ensure Docker is properly installed and running
  • Docker creates the DOCKER-USER chain automatically
  • Verify Docker version is recent (tested on 20.10+):
    docker version

Environment Variables Not Preserved

Problem: GITHUB_TOKEN or other environment variables not available in container

Solution:

  • Use sudo -E to preserve environment variables:
    sudo -E awf --allow-domains ... 'your-command'
  • Verify variables are exported before running:
    export GITHUB_TOKEN="your-token"
    echo $GITHUB_TOKEN  # Should print the token

Token Caching Issues

Problem: Sensitive tokens (GITHUB_TOKEN, OPENAI_API_KEY, etc.) not being properly cached or cleared

Solution:

  1. Enable debug logging for the one-shot-token library:
    export AWF_ONE_SHOT_TOKEN_DEBUG=1
    sudo -E awf --allow-domains ... 'your-command'
  2. Check the debug output for:
    • Initialized with N default token(s) - Library loaded successfully
    • Token <NAME> accessed and cached - Token was read and cached
    • INFO: Token <NAME> cleared from process environment - Token removed from /proc/environ
    • WARNING: Token <NAME> still exposed - Token cleanup failed (security concern)
  3. If tokens are still exposed, check:
    • The token name is in the default protected list (see containers/agent/one-shot-token/README.md)
    • Or set AWF_ONE_SHOT_TOKENS to explicitly protect custom tokens:
      export AWF_ONE_SHOT_TOKENS="MY_CUSTOM_TOKEN,ANOTHER_TOKEN"
      export AWF_ONE_SHOT_TOKEN_DEBUG=1
      sudo -E awf --allow-domains ... 'your-command'

Note: Debug output goes to stderr. Use 2>&1 | tee debug.log to capture it.

Read-Only Filesystem (EROFS) Inside the Sandbox

Problem: A command that writes to a path AWF normally exposes read-write — for example gh-aw's repo-memory directory /tmp/gh-aw/repo-memory/default — fails with Read-only file system / EROFS.

Cause: In the Cloud Hypervisor repo-memory case, AWF's normal /tmp export is read-write. The read-only view of /tmp/gh-aw/repo-memory comes from a filesystem.allowWrite policy in the AWF config file: when that key is present, the writable export is narrowed to the listed guest-visible paths and everything else becomes read-only (see awf-config-spec.md §4.1).

Solution:

  1. Find the effective boundary in the run log. For the Cloud Hypervisor runtime AWF logs it before the guest boots:
    [cloud-hypervisor] stage=filesystem-write-policy boundary /workspace=ro /tmp/gh-aw=ro except /tmp/gh-aw/agent (writes outside these paths fail with EROFS; widen filesystem.allowWrite to permit them)
    
  2. Add the directory the workload must write to filesystem.allowWrite:
    { "filesystem": { "allowWrite": ["/tmp/gh-aw/agent", "/tmp/gh-aw/repo-memory"] } }
    Every listed path must already exist on the host before AWF starts, otherwise planning fails closed with filesystem.allowWrite path is not an existing path within a writable ....
  3. When AWF is launched by the gh-aw compiler, the list is generated from the workflow's sandbox.agent.config.filesystem.allowWrite; the directory has to be declared there rather than passed to AWF directly.

MCP Server Issues

MCP Server Can't Connect

Problem: MCP server cannot reach external API

Solution:

  1. Add MCP server's domain to --allow-domains
  2. Check if MCP server uses subdomain (e.g., api.example.com)
  3. Verify DNS resolution is working:
    sudo awf --allow-domains example.com \
      'nslookup api.example.com'
  4. Check Squid logs for blocked requests:
    sudo grep "api.example.com" /tmp/squid-logs-<timestamp>/access.log

MCP Tools Not Available

Problem: MCP tools not showing up in Copilot CLI

Solution:

  1. Verify MCP config has "tools": ["*"] field:
    cat ~/.copilot/mcp-config.json
  2. Ensure --allow-tool flag matches MCP server name:
    # MCP config has "github" as server name
    copilot --allow-tool github --prompt "..."
  3. Check if built-in MCP is disabled:
    copilot --disable-builtin-mcps --prompt "..."
  4. Review agent logs for MCP connection errors:
    cat /tmp/awf-agent-logs-<timestamp>/*.log

Java / Maven / Gradle Issues

How AWF Handles Java Proxy

AWF automatically sets JAVA_TOOL_OPTIONS with -Dhttp.proxyHost, -Dhttp.proxyPort, -Dhttps.proxyHost, -Dhttps.proxyPort, and -Dhttp.nonProxyHosts inside the agent container. This works for most Java tools that read standard JVM system properties, including Gradle and SBT.

Maven Requires Extra Configuration

Problem: Maven builds fail with network errors even though the domain is in --allow-domains

Cause: Maven's HTTP transport (Apache HttpClient / Maven Resolver) ignores Java system properties for proxy configuration. Unlike Gradle and most other Java tools, Maven does not read -DproxyHost/-DproxyPort from JAVA_TOOL_OPTIONS.

Solution: Create ~/.m2/settings.xml with proxy configuration before running Maven:

mkdir -p ~/.m2
cat > ~/.m2/settings.xml << EOF
<settings>
  <proxies>
    <proxy>
      <id>awf-http</id><active>true</active><protocol>http</protocol>
      <host>${SQUID_PROXY_HOST}</host><port>${SQUID_PROXY_PORT}</port>
    </proxy>
    <proxy>
      <id>awf-https</id><active>true</active><protocol>https</protocol>
      <host>${SQUID_PROXY_HOST}</host><port>${SQUID_PROXY_PORT}</port>
    </proxy>
  </proxies>
</settings>
EOF

The SQUID_PROXY_HOST and SQUID_PROXY_PORT environment variables are automatically set by AWF in the agent container.

For agentic workflows, add this as a setup step in the workflow .md file so the agent creates the file before running Maven commands.

Gradle Works Automatically

Gradle reads JVM system properties via ProxySelector.getDefault(), so the JAVA_TOOL_OPTIONS environment variable set by AWF is sufficient. No extra configuration is needed for Gradle builds.

Why This Is Needed

AWF uses a forward proxy (Squid) for HTTPS egress control rather than transparent interception. This means tools must be proxy-aware:

  • Most tools: Use HTTP_PROXY/HTTPS_PROXY environment variables (set automatically by AWF)
  • Java tools: Use JAVA_TOOL_OPTIONS with JVM system properties (set automatically by AWF)
  • Maven: Requires ~/.m2/settings.xml (must be configured manually — see above)

Playwright / Chromium Issues

Browser fails to launch with missing shared libraries

Problem: playwright-cli (or npx playwright) fails to start Chromium with errors such as:

error while loading shared libraries: libnspr4.so: cannot open shared object file
Host system is missing dependencies to run browsers.

Cause: The agent container uses selective bind mounts rather than a full host filesystem mount, so browsers downloaded by Playwright cannot pick up native libraries installed on the host.

Solution: The agent image preinstalls Chromium's native runtime libraries (libnspr4, libnss3, libatk1.0-0, libatk-bridge2.0-0, libatspi2.0-0, libcups2, libdrm2, libgbm1, libpango-1.0-0, libxkbcommon0, libxcomposite1, libxdamage1, libxrandr2, libasound2, fonts-liberation, and related packages). In chroot mode (the default), entrypoint.sh stages copies of these libraries under /run/awf-lib/browser-libs — on the container's own writable rootfs, so they are not shadowed by the host /usr//lib bind mounts — and sets LD_LIBRARY_PATH so Chromium resolves them there. Use a current agent image (--image-tag latest, or --build-local when building from source) and the browser will launch.

Verify the libraries are present inside the sandbox:

sudo awf --allow-domains '' -- bash -c 'ldd $(find ~/.cache/ms-playwright -name headless_shell | head -1) | grep "not found" || echo "all libraries resolved"'

If you pin an older agent image, or you use a custom base image, install the dependencies yourself before running the browser:

npx playwright install-deps chromium

Browser downloads are blocked

Playwright downloads browser binaries from cdn.playwright.dev. Either add that domain to --allow-domains, or download the browsers on the host before the sandbox starts and point PLAYWRIGHT_BROWSERS_PATH at the staged directory.

Harness Binary Resolution Issues

spawn /usr/local/bin/<tool> ENOENT (hardcoded absolute paths)

Problem: An agentic harness (e.g. the gh-aw Copilot engine) fails with an error like:

spawn /usr/local/bin/copilot ENOENT

even though the tool is installed and resolvable via PATH on the runner.

Cause: Some harnesses hardcode an absolute path to the tool binary (e.g. /usr/local/bin/copilot) instead of doing a PATH lookup, and their installer/cache-hit logic can skip creating that file (e.g. a tool-cache hit short-circuits before the /usr/local/bin wrapper is installed). This is a bug in the harness/installer, not in AWF — but it interacts with how AWF's agent container mounts the host filesystem:

  • AWF's agent container mounts host /usr (and therefore /usr/local) read-only at /host/usr (chroot mode) so it can't be written to from inside the container.
  • The bind mount is a live view of host /usr/local/bin: changes made on the host (including host-side pre-agent-steps) are visible in the sandbox.
  • Commands that run inside the AWF sandbox still cannot create this symlink, because /usr is mounted read-only there.

Automatic mitigation (Copilot CLI): For Copilot runs, AWF's agent entrypoint now checks /usr/local/bin/copilot at container start. When the entry is missing, it resolves copilot through the chroot PATH and the $GITHUB_PATH entries (which is where a warm Copilot CLI tool-cache is activated) and creates the expected symlink before the command runs. Because host /usr is read-only, AWF stages the symlink in a root-owned directory and bind-mounts it over the chroot's /usr/local/bin, preserving every existing entry; the host filesystem is never modified. The behavior is driven by the internal AWF_ENSURE_USR_LOCAL_BIN environment variable (comma-separated binary names) and is a no-op when the path already exists.

Workarounds (other tools):

  1. Host-side symlink before invoking awf — if you control the step immediately before AWF starts the sandbox, create the missing binary on the host filesystem so it is present when AWF takes its /usr bind mount:
    sudo ln -sf "$(command -v copilot)" /usr/local/bin/copilot
    sudo awf --allow-domains ... -- <command>
    Doing this from inside the sandboxed command will not work, since /usr/local is read-only once the container is running.
  2. chroot.binariesSourcePath — point this config option at a host directory containing the tool binary (or a symlink to it). AWF mounts it read-only at /host/tmp/awf-runner-bin and entrypoint.sh prepends it to the chrooted PATH. This fixes PATH-based lookups, but does not help harnesses that spawn a hardcoded absolute path (like /usr/local/bin/copilot) rather than resolving the binary via PATH. See docs/awf-config-spec.md §chroot.binariesSourcePath.
  3. Fix upstream — the durable fix is in the harness/installer itself (e.g. gh-aw's install_copilot_cli.sh / pkg/constants/constants.go), so that it always resolves the binary via PATH or always populates the hardcoded path, even on a tool-cache hit. Track/coordinate with the upstream project for the permanent fix.

Log Analysis

Finding Blocked Domains

# View all blocked domains
sudo grep "TCP_DENIED" /tmp/squid-logs-<timestamp>/access.log | awk '{print $3}' | sort -u

# Count blocked attempts by domain
sudo grep "TCP_DENIED" /tmp/squid-logs-<timestamp>/access.log | awk '{print $3}' | sort | uniq -c | sort -rn

Checking Container Logs

While containers are running (with --keep-containers):

docker logs awf-agent
docker logs awf-squid

After command completes:

# Agent logs (includes GitHub Copilot CLI logs)
cat /tmp/awf-agent-logs-<timestamp>/*.log

# Squid logs (requires sudo)
sudo cat /tmp/squid-logs-<timestamp>/access.log

Checking iptables Logs

Blocked UDP and non-standard protocols are logged to the host kernel log via the DOCKER-USER chain:

# From host (requires sudo)
sudo dmesg | grep FW_BLOCKED

Network Issues

DNS Resolution Failures

Problem: Domains cannot be resolved

Solution:

  1. Verify DNS is allowed in iptables rules (should be automatic)
  2. Test DNS resolution:
    sudo awf --allow-domains example.com \
      'nslookup example.com'
  3. Check if DNS servers are reachable:
    sudo awf --allow-domains example.com \
      'cat /etc/resolv.conf'

awf-net Subnet Collides With the Host or Cluster Network

Problem: Every request fails with 503 and the Squid access log shows TCP_MISS/503 ... HIER_NONE, or AWF aborts at startup with "The awf-net subnet 172.30.0.0/24 contains the DNS resolver(s) ...".

Cause: The default awf-net subnet (172.30.0.0/24) overlaps the host or cluster network. On OpenShift/ARO it is inside the default service CIDR (172.30.0.0/16) and the CoreDNS ClusterIP is exactly 172.30.0.10 — the address AWF assigns to Squid, so Squid sends its DNS queries to itself.

Solution: Relocate the network to a free RFC1918 block:

sudo awf --network-subnet 10.88.0.0/24 --allow-domains github.com -- curl https://github.com/

Or in an AWF config file:

{ "network": { "subnet": "10.88.0.0/24" } }

The fixed host offsets are preserved inside the new block (.1 gateway, .10 Squid, .20 agent, .30 api-proxy, .40 DoH proxy, .50 CLI proxy). Accepted prefix lengths are /16 through /26.

Connection Timeouts

Problem: Requests timeout instead of being blocked

Solution:

  1. Check if Squid proxy is running:
    docker ps | grep awf-squid
  2. Verify iptables rules are applied:
    docker exec awf-agent iptables -t nat -L -n -v
  3. Increase timeout in your command:
    sudo awf --allow-domains github.com \
      'curl --max-time 30 https://github.com/proxy/api.github.com/'

Proxy Connection Refused

Problem: curl: (7) Failed to connect to 172.30.0.10 port 3128

Solution:

  1. Ensure Squid container is healthy:
    docker ps --filter name=awf-squid
    # Should show "healthy" status
  2. Check Squid logs for errors:
    sudo cat /tmp/squid-logs-<timestamp>/cache.log
  3. Verify network connectivity:
    docker exec awf-agent ping -c 3 172.30.0.10

Cleanup Issues

Orphaned Containers

Problem: Containers remain after command exits

Solution:

  1. Manually clean up containers:
    docker rm -f awf-agent awf-squid
  2. Clean up networks:
    docker network rm awf-net
  3. Use cleanup script:
    ./scripts/ci/cleanup.sh

Disk Space Issues

Problem: /tmp directory filling up with logs

Solution:

  1. Manually remove old logs:
    rm -rf /tmp/awf-agent-logs-*
    rm -rf /tmp/squid-logs-*
    rm -rf /tmp/awf-*
  2. Empty log directories are not preserved automatically
  3. Use --keep-containers only when needed for debugging

GitHub Actions Specific Issues

Workflow Timeout

Problem: GitHub Actions workflow times out

Solution:

  1. Increase timeout in workflow:
    timeout-minutes: 15
  2. Use timeout command in script:
    timeout 60s awf --allow-domains ... 'your-command'

Cleanup Not Running

Problem: Cleanup step not executing in workflow

Solution:

  1. Ensure cleanup step has if: always():
    - name: Cleanup
      if: always()
      run: ./scripts/ci/cleanup.sh
  2. Add pre-test cleanup to prevent resource accumulation:
    - name: Pre-test cleanup
      run: ./scripts/ci/cleanup.sh

Network Pool Exhaustion

Problem: Pool overlaps with other one on this address space

Solution:

  1. Run cleanup before tests:
    ./scripts/ci/cleanup.sh
  2. Add network pruning:
    docker network prune -f
  3. This is why pre-test cleanup is critical in CI/CD

SSL Bump Issues

Certificate Validation Failures

Problem: Agent reports SSL/TLS certificate errors when --ssl-bump is enabled

Solution:

  1. Verify the CA was injected into the trust store:
    docker exec awf-agent ls -la /usr/local/share/ca-certificates/
    docker exec awf-agent cat /etc/ssl/certs/ca-certificates.crt | grep -A1 "AWF Session CA"
  2. Check if the application uses certificate pinning (incompatible with SSL Bump)
  3. For Node.js applications, verify NODE_EXTRA_CA_CERTS is not overriding:
    docker exec awf-agent printenv | grep -i cert

URL Patterns Not Matching

Problem: Allowed URL patterns are being blocked with --ssl-bump

Solution:

  1. Enable debug logging to see pattern matching:
    sudo awf --log-level debug --ssl-bump --allow-urls "..." 'your-command'
  2. Check the exact URL format in Squid logs:
    sudo cat /tmp/squid-logs-*/access.log | grep your-domain
  3. Ensure patterns include the scheme:
    # ✗ Wrong: github.com/myorg/*
    # ✓ Correct: https://github.com/myorg/*

Application Fails with Certificate Pinning

Problem: Application refuses to connect due to certificate pinning

Solution:

  • Applications with certificate pinning are incompatible with SSL Bump
  • Use domain-only filtering without --ssl-bump for these applications:
    sudo awf --allow-domains github.com 'your-pinned-app'

Getting More Help

If you're still experiencing issues:

  1. Enable debug logging:

    sudo awf --log-level debug --allow-domains ... 'your-command'
  2. Keep containers for inspection:

    sudo awf --keep-containers --allow-domains ... 'your-command'
  3. Review all logs:

    • Agent logs: /tmp/awf-agent-logs-<timestamp>/
    • Squid logs: /tmp/squid-logs-<timestamp>/
    • Container logs: docker logs awf-agent
  4. Check documentation: