CI/CD Integration

Run automated security tests against your wireless devices in your CI/CD pipeline.

How It Works

  1. Upload your test image - Package your test suite as a Docker image and upload it to Test Fire Studio
  2. Create a test - Specify which scenario (WiFi environment) to test against and pass configuration via environment variables
  3. Stream results - Get real-time logs via Server-Sent Events (SSE) or poll for completion
  4. Get artifacts - Download test results and any files your test writes to /results/

Quick Start

1. Get your API Key

Go to Settings → API Keys to create an API key.

2. Upload your test image

# Step 1: Create image record and get upload URL
curl -X POST \
  -H "Authorization: ApiKey YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-test-image",
    "arch": "amd64",
    "size_bytes": 5000000
  }' \
  "https://api.testfirestudio.com/api/v1/images"

# Step 2: Upload your Docker image tar.gz to the presigned URL
curl -X PUT \
  --data-binary @my-test-image.tar.gz \
  -H "Content-Type: application/octet-stream" \
  "UPLOAD_URL_FROM_STEP_1"

# Step 3: Mark upload as complete
curl -X POST \
  -H "Authorization: ApiKey YOUR_API_KEY" \
  "https://api.testfirestudio.com/api/v1/images/IMAGE_ID/complete"

3. Create a test

# Streams results by default
curl -N -X POST \
  -H "Authorization: ApiKey YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "scenario_id": "vulnerable-home-network",
    "timeout_secs": 120,
    "image_id": "YOUR_IMAGE_ID"
  }' \
  "https://api.testfirestudio.com/api/v1/tests"

GitHub Actions Example

name: Security Tests

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  security-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run Test Fire Studio Test
        env:
          ARENA_API_KEY: ${{ secrets.ARENA_API_KEY }}
        run: |
          # Create test
          RESPONSE=$(curl -s -X POST \
            -H "Authorization: ApiKey $ARENA_API_KEY" \
            -H "Content-Type: application/json" \
            -d '{
              "scenario_id": "network-validator",
              "image_id": "YOUR_IMAGE_ID"
            }' \
            "https://api.testfirestudio.com/api/v1/tests")

          TEST_ID=$(echo "$RESPONSE" | jq -r '.id')

          # Poll for completion
          while true; do
            STATUS=$(curl -s \
              -H "Authorization: ApiKey $ARENA_API_KEY" \
              "https://api.testfirestudio.com/api/v1/tests/$TEST_ID" | jq -r '.status')

            case "$STATUS" in
              passed) echo "Test passed!"; exit 0 ;;
              failed) echo "Test failed!"; exit 1 ;;
              error) echo "Test error!"; exit 2 ;;
              *) sleep 5 ;;
            esac
          done

GitLab CI Example

security-test:
  stage: test
  image: curlimages/curl:latest
  script:
    - |
      RESPONSE=$(curl -s -X POST \
        -H "Authorization: ApiKey $ARENA_API_KEY" \
        -H "Content-Type: application/json" \
        -d "{\"scenario_id\": \"network-validator\", \"image_id\": \"$IMAGE_ID\"}" \
        "https://api.testfirestudio.com/api/v1/tests")

      TEST_ID=$(echo "$RESPONSE" | jq -r '.id')

      while true; do
        RESULT=$(curl -s -H "Authorization: ApiKey $ARENA_API_KEY" \
          "https://api.testfirestudio.com/api/v1/tests/$TEST_ID")
        STATUS=$(echo "$RESULT" | jq -r '.status')

        if [ "$STATUS" = "passed" ]; then exit 0; fi
        if [ "$STATUS" = "failed" ]; then exit 1; fi
        if [ "$STATUS" = "error" ]; then exit 2; fi
        sleep 5
      done
  variables:
    ARENA_API_KEY: $ARENA_API_KEY
    IMAGE_ID: "your-image-id"

Environment Variables

Your test container receives these environment variables automatically:

VariableDescription
DUT_INTERFACEThe wireless interface to use (usually wlan4)
TARGET_SSIDDefault target network SSID
TARGET_BSSIDDefault target network BSSID
SSH_PORTSSH port if your image starts an SSH server

You can pass additional environment variables via the env_vars field in the create test request.

Capturing Artifacts

Any files your test writes to /results/ are automatically captured and made available for download after the test completes.

Common patterns:

Exit Codes

CodeStatusDescription
0passedAll tests passed
1failedOne or more tests failed
2+errorTest encountered an error

SSE Events

When streaming test results, you'll receive these event types:

EventDescription
statusTest status changed (pending, running, passed, failed)
logLog line from the test container (stdout/stderr)
resultFinal test result with exit code, duration, and artifacts
completeStream is complete, connection can be closed