Skip to main content

Overview

For best performance, run Apex in the included Kali Linux container with preconfigured penetration testing tools. This provides:
  • Pre-installed tools: nmap, gobuster, sqlmap, nikto, hydra, john, hashcat, and more
  • Consistent environment: Same tooling across all developers/CI systems
  • Isolation: Keep pentest tools separate from your host system
  • Network flexibility: Use host network mode for comprehensive scanning
The Kali container is recommended for production use but not required. Apex works on any system with Bun installed.

Quick Start

1

Navigate to Container Directory

cd container
2

Configure Environment Variables

Copy the example environment file and add your API keys:
cp env.example .env
Edit .env with your API keys:
# .env
ANTHROPIC_API_KEY=sk-ant-xxx
OPENROUTER_API_KEY=sk-or-xxx  # optional
3

Build and Start Container

docker compose up --build -d
4

Exec Into Container

docker compose exec kali-apex bash
5

Run Apex

Inside the container:
pensar

Docker Compose Configuration

The included docker-compose.yml provides a complete Kali Linux environment:
# container/docker-compose.yml
services:
  kali-apex:
    build: .
    image: kali-apex:latest
    container_name: kali-apex
    tty: true
    stdin_open: true
    network_mode: "bridge" # consider "host" on Linux for full network access
    cap_add:
      - NET_ADMIN
      - NET_RAW
    security_opt:
      - seccomp:unconfined
    env_file:
      - .env
    environment:
      - DISABLE_TELEMETRY=1
      - DISABLE_AUTOUPDATER=1
      - DISABLE_ERROR_REPORTING=1
    volumes:
      - ../:/home/pentest/app
      - ./workspace:/home/pentest/workspace
    working_dir: /home/pentest/app

Key Configuration Options

Network Mode

Bridge Mode (Default)
  • Isolated network namespace
  • Port mapping required for external access
  • Use for: General pentesting, web app testing
Host Mode (Linux only)
  • Direct access to host network
  • No port mapping needed
  • Use for: Network scanning, testing local services, comprehensive recon
# For full network access on Linux hosts:
network_mode: "host"
Host mode is only available on Linux. On macOS/Windows, use bridge mode or configure port forwarding.

Capabilities

cap_add:
  - NET_ADMIN  # Required for network configuration
  - NET_RAW    # Required for raw packet manipulation (nmap, etc.)
These capabilities allow:
  • Port scanning with nmap
  • Packet capture with tcpdump
  • Raw socket operations

Security Options

security_opt:
  - seccomp:unconfined
Unconfined seccomp allows unrestricted syscall access, needed for low-level network operations.
These elevated permissions are intentional for a pentest environment. Do not use this configuration for production services.

Dockerfile Breakdown

The Kali container is built from the official Kali Rolling image:
# container/Dockerfile
FROM kalilinux/kali-rolling:latest

ENV DEBIAN_FRONTEND=noninteractive
ARG USER=pentest
ARG UID=1000
ARG GID=1000

# Core tooling and common pentest utilities
RUN apt-get update && apt-get dist-upgrade -y && \
    apt-get install -y --no-install-recommends \
      sudo git curl wget ca-certificates tmux \
      python3 python3-pip python3-venv \
      build-essential gcc g++ make cmake perl ruby \
      netcat-openbsd socat nmap tcpdump iproute2 iputils-ping \
      gdb gdb-multiarch binutils-multiarch \
      strace ltrace hexedit upx \
      binwalk radare2 \
      unzip zip zlib1g-dev \
      gobuster sqlmap nikto hydra john hashcat \
      foremost exiftool \
      wireshark-common \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

# Install bun system-wide (required for @pensar/apex)
ENV BUN_INSTALL="/usr/local"
RUN curl -fsSL https://bun.sh/install | bash

# Install @pensar/apex globally
RUN bun install -g @pensar/apex

# Create non-root user for safety
RUN groupadd -g ${GID} ${USER} || true \
 && useradd -m -u ${UID} -g ${GID} -s /bin/bash ${USER} \
 && echo "${USER} ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/${USER} \
 && chmod 0440 /etc/sudoers.d/${USER}

WORKDIR /home/${USER}
USER ${USER}
ENV HOME=/home/${USER}

# Load variables from ~/.env automatically for convenience inside the shell
RUN echo 'if [ -f ~/.env ]; then' >> ~/.bashrc && \
    echo '    export $(cat ~/.env | xargs)' >> ~/.bashrc && \
    echo 'fi' >> ~/.bashrc

ENTRYPOINT ["/bin/bash"]

Installed Tools

The container includes these pentest tools used by Apex:
ToolPurpose
nmapPort scanning and service detection
gobusterDirectory/file brute forcing
sqlmapSQL injection testing
niktoWeb server vulnerability scanning
hydraLogin brute forcing
johnPassword cracking
hashcatGPU-accelerated password cracking
binwalkFirmware analysis
radare2Binary analysis and reverse engineering
foremostFile carving from disk images
exiftoolMetadata extraction
Apex automatically detects which tools are available and adjusts its testing strategy accordingly. Run pensar doctor to check installed dependencies.

Network Modes Explained

Bridge Mode (Default)

network_mode: "bridge"
How it works:
  • Container gets its own network namespace
  • Docker creates a virtual bridge (docker0)
  • Container IP is in Docker’s subnet (e.g., 172.17.0.0/16)
  • Port mapping required to access services from host
Use when:
  • Testing external web applications
  • Running on macOS or Windows
  • You want network isolation
Example: Testing https://staging.example.com
docker compose up -d
docker compose exec kali-apex bash
pensar pentest --target https://staging.example.com

Host Mode (Linux Only)

network_mode: "host"
How it works:
  • Container uses the host’s network stack directly
  • No network isolation
  • Container can access localhost, LAN devices, etc.
Use when:
  • Scanning local network (192.168.x.x)
  • Testing localhost services
  • Comprehensive network reconnaissance
  • Need raw socket access
On Linux hosts, consider using network_mode: host for comprehensive network scanning.
Example: Scanning your local network
# docker-compose.yml (on Linux)
network_mode: "host"
docker compose up -d
docker compose exec kali-apex bash
pensar pentest --target 192.168.1.100

Custom Bridge Networks

For multi-container setups:
networks:
  pentest:
    driver: bridge

services:
  kali-apex:
    networks:
      - pentest

  vulnerable-app:
    image: webgoat/webgoat:latest
    networks:
      - pentest
Now Apex can test vulnerable-app by hostname:
pensar pentest --target http://vulnerable-app:8080

Environment Variables

The .env file is automatically loaded inside the container:
# container/.env

# Required: AI provider API key
ANTHROPIC_API_KEY=sk-ant-xxx

# Optional: Additional providers
OPENROUTER_API_KEY=sk-or-xxx
OPENAI_API_KEY=sk-xxx

# Optional: vLLM local model
LOCAL_MODEL_URL=http://localhost:8000/v1

# Optional: Disable telemetry
DISABLE_TELEMETRY=1
DISABLE_AUTOUPDATER=1
DISABLE_ERROR_REPORTING=1
The Dockerfile automatically exports these variables in the shell:
# From Dockerfile
RUN echo 'if [ -f ~/.env ]; then' >> ~/.bashrc && \
    echo '    export $(cat ~/.env | xargs)' >> ~/.bashrc && \
    echo 'fi' >> ~/.bashrc

Volume Mounts

volumes:
  - ../:/home/pentest/app        # Mount source code (for whitebox testing)
  - ./workspace:/home/pentest/workspace  # Persistent workspace

Source Code Mount

The ../:/home/pentest/app mount allows whitebox testing:
# Inside container
cd /home/pentest/app
pensar pentest --target https://staging.example.com --cwd .

Workspace Mount

The workspace/ directory persists across container restarts:
  • Session data
  • Findings
  • Reports
  • Screenshots
# On host
ls container/workspace/
# sessions/  findings/  reports/

Common Workflows

Testing a Web Application

# Start container
cd container
docker compose up -d

# Exec in
docker compose exec kali-apex bash

# Inside container
pensar pentest --target https://webapp.example.com

Whitebox Testing with Source Code

# Container already mounts source from ../
cd container
docker compose up -d
docker compose exec kali-apex bash

# Inside container, source is at /home/pentest/app
cd /home/pentest/app
pensar pentest --target https://staging.example.com --cwd .

Network Scanning (Linux)

# docker-compose.yml
network_mode: "host"
docker compose up --build -d
docker compose exec kali-apex bash

# Scan local network
pensar pentest --target 192.168.1.0/24

Troubleshooting

”Permission denied” when running nmap

Cause: Missing NET_RAW capability. Solution: Ensure cap_add includes NET_RAW in docker-compose.yml:
cap_add:
  - NET_ADMIN
  - NET_RAW

Container exits immediately

Cause: Missing tty: true and stdin_open: true. Solution: Verify your docker-compose.yml includes:
tty: true
stdin_open: true

“Cannot connect to target” on localhost

Cause: Bridge mode isolates the container network. Solutions:
  1. Use host mode (Linux only): network_mode: "host"
  2. Use host.docker.internal instead of localhost:
    pensar pentest --target http://host.docker.internal:3000
    
  3. Use the host’s LAN IP (e.g., 192.168.1.100)

Tools not found (nmap, gobuster, etc.)

Cause: Container wasn’t rebuilt after Dockerfile changes. Solution: Rebuild with --no-cache:
docker compose build --no-cache
docker compose up -d

API key not recognized inside container

Cause: .env file not created or mounted. Solution:
  1. Ensure container/.env exists:
    cd container
    ls -la .env
    
  2. Verify env_file: - .env is in docker-compose.yml
  3. Restart container:
    docker compose down
    docker compose up -d
    
  4. Test inside container:
    docker compose exec kali-apex bash
    echo $ANTHROPIC_API_KEY
    

Advanced Configuration

Custom Dockerfile

Add additional tools:
# container/Dockerfile.custom
FROM kali-apex:latest

# Install additional tools
RUN apt-get update && apt-get install -y \
  metasploit-framework \
  burpsuite \
  zaproxy
# docker-compose.yml
services:
  kali-apex:
    build:
      context: .
      dockerfile: Dockerfile.custom

GPU Access for Hashcat

services:
  kali-apex:
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

Multiple Containers for Parallel Testing

services:
  apex-1:
    image: kali-apex:latest
    container_name: apex-1
    # ... config ...

  apex-2:
    image: kali-apex:latest
    container_name: apex-2
    # ... config ...
Run parallel pentests:
docker compose exec apex-1 bash -c "pensar pentest --target https://target1.com"
docker compose exec apex-2 bash -c "pensar pentest --target https://target2.com"

CI/CD Integration

GitHub Actions

name: Pentest in Docker
on: [push]

jobs:
  pentest:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Build Kali Container
        run: |
          cd container
          docker compose build

      - name: Run Pentest
        run: |
          cd container
          echo "ANTHROPIC_API_KEY=${{ secrets.ANTHROPIC_API_KEY }}" > .env
          docker compose up -d
          docker compose exec -T kali-apex pensar pentest --target https://staging.example.com

      - name: Upload Report
        uses: actions/upload-artifact@v3
        with:
          name: pentest-report
          path: container/workspace/sessions/*/report.md

GitLab CI

pentest:
  image: docker:latest
  services:
    - docker:dind
  script:
    - cd container
    - docker compose build
    - echo "ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY" > .env
    - docker compose up -d
    - docker compose exec -T kali-apex pensar pentest --target $CI_ENVIRONMENT_URL
  artifacts:
    paths:
      - container/workspace/sessions/*/report.md

Next Steps

Blackbox Testing

Run external penetration tests from the Kali container

Whitebox Testing

Analyze source code with the —cwd flag

Authentication

Configure credentials for authenticated testing

vLLM Setup

Use local models instead of cloud APIs

Build docs developers (and LLMs) love