Blog

Test APIs behind a VPN with a self-hosted runner

Run API tests inside your private network without opening an inbound runner port. Understand outbound HTTPS, result uploads, and CI access requirements.

An API can be healthy and still be unreachable from the machine running its tests. Staging may sit behind a VPN, an internal service may have no public ingress, or an on-prem API may accept traffic only from your network.

Echopoint’s self-hosted runner puts API test execution inside that network. A developer or coding agent can launch a reviewed API flow through the CLI, while the runner sends the actual requests from a machine that can reach the service.

The important boundary: no inbound runner port is required, but outbound access is. The runner contacts https://api.echopoint.dev to receive work and upload results. This is not a fully air-gapped setup, and it is not a guarantee that all test data remains on your infrastructure.

When a private runner is useful

Common cases include:

  • Staging behind a VPN: run from a host with the required routes and DNS
  • Private VPC services: keep the target API’s public ingress closed
  • On-prem environments with approved egress: allow control-plane traffic while testing services locally
  • IP-allowlisted APIs: execute from infrastructure with an approved source address

A cloud runner can work when the target is reachable from it. If it cannot reach the service, choose an execution host with the right connectivity rather than assuming the testing tool establishes a VPN or configures your firewall.

Choose where the flow executes

Echopoint supports three execution locations:

RunnerWhere requests originateTypical use
CloudEchopoint’s managed runnerAPIs reachable from the managed environment
Self-hostedInfrastructure you operatePrivate services with a persistent runner
EphemeralThe machine running the CLI or CI jobLocal development and pull-request checks

The flow definition, request sequence, and assertions are reusable. Network access and runtime configuration still matter: a hostname that resolves on your laptop may not resolve in CI, and a production credential may be inappropriate for a staging test.

Use the runner reference for execution options and environments for selecting the right inputs. If the suite starts from an API specification, OpenAPI Sync helps maintain its request collection; it does not provide network access.

How the runner reaches a private API

A self-hosted runner sends requests to an internal API over the private network and makes outbound HTTPS calls to the Echopoint control plane to claim jobs, send heartbeats, and publish execution results.

The runner is installed inside your network, where it can resolve and reach the target API. For the runner job protocol, it opens connections to the control plane rather than waiting for an inbound connection:

  1. Claim a job: the runner polls the control plane and takes a lease on available work
  2. Receive inputs: the job includes the flow snapshot and resolved execution inputs
  3. Execute locally: request steps call the target API using the runner host’s connectivity
  4. Report progress: events and heartbeats update execution status
  5. Upload results: node outcomes and assertion results are sent to the control plane for run history

The control plane does not need a direct network route to the private API. Your runner needs both access to that API and outbound HTTPS to the configured control-plane host. With Echopoint’s hosted control plane, set ECHOPOINT_BASE_URL=https://api.echopoint.dev explicitly in the runner configuration.

Check the data boundary before deployment

Self-hosting changes where requests execute. It does not make Echopoint a local-only data store. The runner receives resolved inputs, and recorded execution results are uploaded to Echopoint. Those results can include response or derived data and assertion expected/actual values.

Before connecting sensitive systems, review what your flow sends, extracts, and records. Use suitable test accounts and synthetic data where possible, and confirm that the result-upload behavior fits your organization’s requirements. If the network cannot allow control-plane egress, this runner setup will not work.

Set up a self-hosted run

You need an Echopoint workspace with access, a flow to execute, and a runner registered and configured for that workspace. Follow the runner documentation and the runner project’s setup instructions for the supported configuration.

Before the first run, check:

  • The host can resolve and reach the internal API
  • Outbound HTTPS to api.echopoint.dev is allowed
  • Runner authentication and organization configuration are correct
  • The selected environment contains the intended test inputs
  • Uploading the resulting execution data is acceptable for the target system

Once the runner is available, launch a flow on it:

Terminal window
echopoint flows launch <flow-id> --runner self_hosted

For a coding agent, that separates the machine issuing the launch from the machine making the API requests. Give the agent the flow ID, intended environment, and the assertions to inspect. Review the execution history when the run completes; a successful launch is not itself a passing test.

Run inside CI when the job has network access

For pull-request checks, the CLI’s embedded ephemeral runner executes the flow inside the CI job and exits afterward. It reaches only what that job can reach. Installing the GitHub Action on a public runner does not automatically connect it to your VPN.

The minimal Action step is:

- uses: nanostack-dev/echopoint-cli@v1
with:
api-key: ${{ secrets.ECHOPOINT_API_KEY }}
organization-id: ${{ secrets.ECHOPOINT_ORG_ID }}
tags: smoke
environment: staging
parallel: '3'

The current Action needs flows:execute, plus flows:read for tag selection. Its CLI uses a one-shot job token for progress and completion reporting. The Action downloads the CLI; the runner is embedded, so no separate runner binary is required.

The GitHub Action guide covers prerequisites, required checks, result outputs, and safe handling of pull requests. The CI feature page compares local and pipeline execution.

For another CI system or an agent’s terminal:

Terminal window
echopoint flows run --tag smoke --environment staging --parallel 3 -o json

Configure API-key authentication with ECHOPOINT_API_KEY and ECHOPOINT_ORGANIZATION_ID using your environment’s secret configuration. See the CLI reference.

JSON results let an agent inspect failures programmatically. Exit code 0 means all flows passed; 1 means a flow failed; 2 means cancelled; 3 indicates an API, runner, or contract error; and 4 means a poll timeout. Investigate a failed flow’s evidence before deciding whether the API, test data, dependencies, or test expectation needs to change.

Choose the smallest setup that reaches your API

Use the managed cloud runner when it can reach your target. Use a self-hosted runner for persistent private-network execution, or the embedded CLI runner when the agent’s machine or CI job already has the needed connectivity. Both private execution options still require control-plane egress and upload execution results.

Review the runner docs and visual flow guide to plan the test. The runner and CLI source are public on GitHub. Join the waitlist for Echopoint access updates; joining does not provide immediate access.

FAQ

Do I have to open an inbound firewall port for the self-hosted runner?

No inbound runner port is required for job claiming and reporting. The runner needs outbound HTTPS to the Echopoint control plane at api.echopoint.dev, plus network access to the APIs it tests. It uploads progress and execution results to the control plane.

Does the self-hosted runner work in a fully air-gapped network?

No. The documented setup depends on outbound control-plane access to receive jobs and report results. Running API requests inside your network does not mean all execution data stays there.

Can the same flow run on a cloud, self-hosted, or CI runner?

The flow definition is reusable across runner types. The selected runner still needs the network routes, DNS, credentials, and environment configuration required by the target API.

How can a coding agent test a private API?

An agent can use the Echopoint CLI to launch a flow on a self-hosted runner inside the private network. Alternatively, flows run executes through the CLI's embedded runner wherever the agent or CI job runs. That process needs access to both the target API and the Echopoint control plane.

Echopoint is free while in beta.

Join the waitlist and we'll let you in as your spot opens.

Runner docs