AWS Client VPN requires a browser for SAML authentication. That's fine on a developer laptop — impossible on a CI runner or a remote VM behind NAT.
AWS Client VPN uses the CRV1 SAML challenge-response protocol. Phase 1 returns a URL that must be opened in a browser — the user logs in via their IdP (Okta, Azure AD, etc.) and the resulting SAMLResponse completes Phase 2 to bring up the tunnel.
GitHub Actions, GitLab CI, Jenkins, and most cloud runners are headless Ubuntu containers. There is no display, no browser, no way to complete the SAML flow interactively.
Injecting AWS credentials or SAML tokens as CI secrets couples your pipeline to credentials that expire, rotate, and leak. Every rotation breaks builds.
Pre-generated SAML tokens expire in minutes. Spinning up a full desktop VM just for VPN auth wastes money and adds minutes to every build.
The relay is a lightweight broker between the headless agent (CI runner) and the human operator (Android or desktop app). No inbound ports required. No secrets stored anywhere in the pipeline.
Agent registers. CI runner starts openlawsvpn-cli -relay <token> -daemon and connects a WebSocket to the relay. No inbound port needed.
App authenticates. Developer opens the Android or desktop app, sees the agent listed as standby, taps Connect. The app runs Phase 1 + full SAML browser flow.
Relay delivers credentials. App sends the completed SAMLResponse to the relay via HTTPS. Relay pushes it to the waiting agent over the WebSocket.
Tunnel up. Agent executes Phase 2, VPN is established. CI build continues. App shows the agent as connected and can disconnect remotely at any time.
A real screencast: a GitHub Actions workflow starts the relay agent, the Android app approves the SAML flow, and the tunnel comes up — with zero credentials stored in the pipeline.
openlawsvpn-cli -relay $RELAY_TOKEN -daemon -pidfile /tmp/vpn.pid. The step blocks, waiting for an operator to approve auth from the app.TUNNEL UP · tun=172.16.77.1 · daemon started (pid 12483). The pipeline continues to the next step.The public demo token lets you test the full relay flow immediately against the live relay backend. No registration, no credit card.
defaultRun on any Linux host (or CI runner) with openlawsvpn-cli installed:
openlawsvpn-cli -relay default -daemon
Then open the Android app → Relay tab → enter token default → tap Save & Refresh. Your agent appears in the list. Tap Connect to complete the SAML flow.
Demo limits: 10-minute session maximum · 5 concurrent agents · shared public namespace. For longer sessions or private organisation tokens, vote for extended plans on GitHub.
- name: Start relay agent
env:
RELAY_TOKEN: ${{ secrets.RELAY_TOKEN }}
run: |
sudo openlawsvpn-cli \
-relay "$RELAY_TOKEN" \
-daemon \
-pidfile /tmp/vpn.pid \
-logfile /tmp/vpn.log
- name: Check internal service health
run: curl -f https://internal.example.com/health
- name: Disconnect VPN
if: always()
run: |
kill "$(cat /tmp/vpn.pid)" || true
Store your organisation relay token as a repository secret RELAY_TOKEN.
No VPN credentials, no AWS keys, no SAML tokens in CI.
Integration tests, database migrations, internal API calls — any CI step that needs your private VPC. The relay agent starts as a step; a team member approves from their phone before the run begins.
Cloud dev boxes and jump hosts behind NAT can't open a browser. Relay lets you bring up the VPN tunnel on any remote machine with a single CLI command.
Run the relay agent as a VPN init container in your pod spec. The tunnel is ready before your application container starts — no sidecar complexity.
Embedded Linux devices can register as relay agents. A fleet manager approves tunnels from a single mobile session, granting temporary VPN access to field devices.
Install the client, run with -relay default to test immediately — no account required.