AegisRunner
Start free
All docs

Integrations

Testing behind a firewall

Reach private, staging, localhost, or IP-restricted targets the cloud can't: static-IP allowlist, the aegis tunnel, and a self-hosted runner that runs inside your network.

Last updated: July 14, 2026

Testing behind a firewall

Not every app is on the public internet. Pre-production and staging environments often sit behind a corporate VPN, a firewall, an IP allowlist, or on a developer’s localhost. AegisRunner reaches all of them — pick the option that matches your setup.

Just want to test a local dev app? The fastest path is local execution — a real browser runs on your machine and scans localhost directly, no tunnel: aegis scan-runner then aegis scan —local —url http://localhost:3000. Or drop in a framework plugin and click the in-app shield. See A local dev app below, or the Test a localhost app overview.
Your situationUse
Staging is on the internet but IP-restrictedStatic-IP allowlist
A dev app on localhostLocal execution (or tunnel)
Staging behind a VPN / firewall / air-gappedSelf-hosted runner

1. Static-IP allowlist

If your target is reachable from the internet but only from approved IPs, allow AegisRunner’s scanner addresses through your firewall or WAF. Find the current list under Project settings → Testing behind a firewall — the scanner egresses from a small, stable set of static IPs you can paste into an allow rule. No agent to install; scans run from our cloud as usual.

2. A local dev app (localhost)

Working on an app that’s only running on your machine? Two ways in — both keep your app off the public internet.

Local execution — the browser runs on your machine (recommended)

A real browser runs on your own machine and scans localhost directly — no tunnel, no cloud relay. It’s the fastest and most reliable path (nothing round-trips through the cloud, so even big apps scan quickly), and your app and credentials never leave your machine. The first run fetches a headless browser (Chromium, ~150 MB, cached after); no Docker required.

# install the CLI once (zero dependencies, Node 18+)
npm install -g @aegisrunner/cli
export AEGIS_TOKEN=aegis_xxxxxxxx

# start the local browser executor (docker-free), then scan localhost:
aegis scan-runner &
aegis scan --local --url http://localhost:3000 --watch

# prefer a container? run the executor as an image instead:
docker run -e AEGIS_TOKEN=aegis_xxxxxxxx aegisrunner1/scan-runner

Behind a login? For local scans, credentials stay on your machine — set AEGIS_USERNAME / AEGIS_PASSWORD on the runner and it signs in locally (they are never sent to the cloud).

Run the generated tests locally too. The same runner also executes an already-generated suite on your machine — the AI decides what to test in our cloud, but the browser runs on your box against localhost, with verdicts identical to a cloud run:

# with a runner connected, run your latest generated suite locally:
aegis run --local --base-url http://localhost:3000 --wait

In a framework plugin, the in-app shield has a Run generated tests button that does the same in one click.

Tunnel — relay our cloud browser

Prefer not to run a browser locally? Open a temporary, encrypted, outbound-only tunnel from a local port to the cloud scanner — no deploy, no public URL.

# open the tunnel, scan it, and watch — all in one command:
aegis scan --tunnel --port 3000 --watch

# behind a login? add credentials (password from stdin, never on the CLI):
printf %s "$DEV_PW" | aegis scan --tunnel --port 3000 --username you@example.com --password-stdin --watch

The tunnel stays open while the command runs and closes when you stop it. It’s meant for quick, interactive checks; for always-on private environments, use a self-hosted runner instead.

Even simpler: a framework plugin wires either mode into your dev server so you never run a command. One line in your Vite, Nuxt or Next config puts a scan — local by default — one click away on npm run dev, via a floating in-app shield. See Framework plugins.

3. Self-hosted runner (VPN / firewall / air-gapped)

Run AegisRunner inside your own network. The runner makes an outbound-only HTTPS connection to AegisRunner, claims jobs, executes them locally against your private targets, and reports results back. No inbound port is opened — so it works from behind a corporate firewall, a VPN, or NAT.

Docker (recommended)

docker run --network host \
  -e AEGIS_TOKEN=aegis_xxxxxxxx \
  aegisrunner1/runner

—network host lets the runner reach private hosts on your LAN/VPC. If your target is on a specific Docker network, attach the container to that network instead (—network my-net). The image is also on GitHub Container Registry: ghcr.io/aegis-runner/runner.

npm

npm install -g @aegisrunner/cli
aegis runner            # reads AEGIS_TOKEN from the environment

Get a token

Create a CI trigger token under Manage → CI/CD (Pro or Business plan). The runner is scoped to that token’s project; revoke it there to cut a runner off.

Queue a check

Once a runner is connected, queue work for it from the CLI, from CI, or from the dashboard (Project settings → Self-hosted runner → Run a check):

# waits for the result and prints it
aegis runner-enqueue --url http://staging.internal:8080 --note "nightly smoke"

# fire and forget
aegis runner-enqueue --url http://staging.internal:8080 --no-wait

Networking & security

  • Outbound only. The runner initiates every connection; you never open an inbound port or expose your environment to the internet.
  • Egress: allow HTTPS to app.aegisrunner.com (or your configured AEGIS_API host).
  • Data stays local. The runner reaches your target directly; the target’s traffic stays in your network. Only the job result — status, timings, findings — is sent back.
  • Least privilege. A single CI token, scoped to one project. The container runs as a non-root user and needs no privileges.

Which option should I use?

IP-restricted but public → allowlist. A local dev app → local execution (browser on your machine), or the tunnel if you’d rather not run a browser locally. Anything genuinely private, on a VPN, or air-gapped → self-hosted runner. They all use the same project trigger token, so you can mix them as your environments differ.

Related