Installing the Connector
The Connector is the small agent that runs inside your network and is the only thing that ever reaches your internal apps. It dials out, never listens, and needs no firewall rule. This is the one step both Cloud and self-hosted customers perform.
What the Connector is
A container you run on a machine inside the network that holds the apps. It opens an encrypted WebSocket tunnel outward to the data-plane and keeps it open; every vendor request that passes the sign-in and grant checks travels down that tunnel, and the Connector makes the final hop to the internal address. Nothing on the internet can connect to it, because it has no listening port at all.
You do not configure upstream apps on the Connector. Each app's internal address lives on its resource in the console, and the Manager sends that address down the tunnel with each request. Adding an app never means touching the Connector host again.
Every Connector host also runs the two session engines: guacd for recorded RDP, SSH and VNC sessions, and KasmVNC for the isolated browser. The install command starts them next to the connector on a private Docker network, so there is nothing to enable separately.
1Add a connector in the console
Open Infrastructure → Connectors and choose Add connector. The console shows a single ready-to-run command with your MANAGER_URL, DATAPLANE_URL and a one-time PAIR_CODE already filled in. Copy it as shown.
docker run misses the two session engines, and the container name access-connector and volume access_connector_data must match what the console's Re-pair and Update commands expect later.2Run the command on a machine inside your network
The machine needs Docker, outbound access on port 443 to both URLs in the command, and network reachability to the internal apps you will publish. A small VM or an existing utility host is enough. Paste the command and run it; it pulls three images and starts three containers.
| Container | Role |
|---|---|
| access-connector | The outbound agent. Its token lives in the access_connector_data volume, so it reconnects after restarts without the pairing code. |
| captivo-guacd | The session engine for RDP, SSH and VNC resources. |
| captivo-kasm | The isolated-browser engine (KasmVNC). |
For orientation, a simplified form of the connector container alone. The console's real command is longer and also starts the two engines; use that one.
docker run -d \
--name access-connector --restart unless-stopped \
-e MANAGER_URL=https://manager.access.example.com \
-e DATAPLANE_URL=wss://connect.access.example.com \
-e PAIR_CODE=<one-time code from the console> \
-v access_connector_data:/data \
ghcr.io/captivo-io/captivo-access-connector:latestMANAGER_URL is your console address and DATAPLANE_URL is wss://connect.cloud.captivo.io. On your own server they are the manager and connect hostnames you created in DNS. Either way the console fills them in; you never type them.3Confirm it is online
Back in Infrastructure → Connectors, the new connector flips to Online within a few seconds. Its detail page shows live telemetry (version, uptime, active and total connections, bytes in and out, denied attempts) and the last lines of its log. If it stays Offline, docker logs access-connector on the host says why, and The connector shows offline walks through the usual causes.
Egress boundary: ALLOWED_TARGETS and egress policy
Left alone, the Connector dials whatever internal address the Manager routes to it. To put a hard ceiling on that, add -e ALLOWED_TARGETS=... to the connector container: a comma-separated list of CIDRs, hostnames or host:port pairs, for example 10.0.5.0/24,jira.internal,192.168.1.50:8080. Anything outside the list is refused even if a resource points there.
ALLOWED_TARGETS, it must also include the two engines, or remote desktop and isolated browser sessions stop working: captivo-guacd:4822, captivo-kasm:6901 and captivo-kasm:7900.The console can additionally push an egress policy to a connector from its detail page. The two combine as an intersection: a target must satisfy both to be dialed. The variable set on the host is the ceiling, and a policy pushed from the console can only tighten it, never widen it, so even a compromised control plane cannot make a connector reach something its local boundary forbids.
| Variable | Meaning |
|---|---|
| MANAGER_URL | Console address, used for enrollment. Required. |
| DATAPLANE_URL | Tunnel address. Must start with wss://; a ws:// tunnel is unencrypted. Required. |
| PAIR_CODE | One-time pairing code. Read on the first run only; ignored once a token is stored. |
| ALLOWED_TARGETS | Optional egress ceiling, as above. |
| TOKEN_FILE | Where the connector token is stored. Default /data/token. |
| LOG_LEVEL | Initial log threshold (debug, info, warn, error). Default info; the console can override it live. |
Data directory, backup and the recording key
/data must be a mounted volume, and the console's command makes it one. It holds the connector token, so the container can be recreated without re-pairing, and since version 2.0 it also holds the session recordings themselves: screen streams, keystroke logs and isolated-browser video, encrypted with AES-256-GCM using a key generated on first start and kept at /data/recording.key. The connector warns in its log at start-up if the directory is not on a volume, because a docker rm would then destroy every recording.
- Back up the volume, recording.key included. Nobody else has a copy, not even on Cloud; without the key the recordings cannot be read, and it cannot be reissued.
- Size the disk for recordings, not just the token. A recording runs as long as its session and nothing cuts it short; what bounds the disk is the retention window set in the console, which the connector applies to its own files, and how long your sessions tend to run.
- A recording is playable and searchable only while this connector is online, and a deletion requested in the console completes when it next connects.
How recordings are enabled, replayed and deleted is in Session recording and live view.
Updating, re-pairing and log level
Updating. Pull the new connector image and recreate the container; the token in /data persists, so the connector reconnects without a pairing code. The connector's detail page shows the exact update command when a newer version exists, and marks the connector Outdated until it is applied. Connectors are never updated by the server-side update, on Cloud or on your own server.
Re-pairing. If the volume was lost or the token revoked, the detail page's Re-pair action issues a fresh pairing code and the command to run. Resources bound to the connector keep working once it is back.
Log level. Under Logging on the detail page you can switch a connector to debug for per-request logging while troubleshooting, then back to info; the change is pushed live over the tunnel, no redeploy. The same page tails the connector's recent log, the Gateway logs from guacd and the Isolated browser logs from KasmVNC, so a failing remote desktop connection can be read without logging in to the host.
For product-wide problems: The connector shows offline · The app does not open · Cannot sign in with a passkey