Skip to main content

Getting Started

Install and configure the Tunnel Agent to connect your on-premise services to Zihin Cloud. Current agent version: 1.3.

1. Create the tunnel

An admin or owner of your organization creates the tunnel from the Zihin Console:

  1. Go to Management → Connectivity
  2. Click Create Tunnel
  3. Enter a label (e.g., your company name)
  4. Copy the generated token (ztun_...)
caution

The token is displayed only once. Copy it immediately and store it securely (vault, secret manager, or a .env file with restricted permissions).

2. Create the configuration file

Create a file named zihin-agent.yml:

token_env: ZIHIN_TOKEN
tunnel_url: wss://tunnel.zihin.ai
log_level: info

services:
- name: my-service
url: http://192.168.1.100:8080
inject_headers:
Authorization: "Bearer ${SERVICE_API_KEY}"

- name: another-service
url: https://internal.example.com
inject_headers:
X-API-Key: "${ANOTHER_KEY}"
FieldRequiredDescription
token_envYesName of the environment variable containing the token (ZIHIN_TOKEN)
tunnel_urlNoCloud server URL (default: wss://tunnel.zihin.ai)
log_levelNodebug, info, warn, error (default: info)
pool_sizeNoConnections to the cloud (1–10, default 4)
services[].nameYesService name — must match the name configured in Zihin Cloud
services[].urlYesInternal service URL, host and port only (the request path is added automatically)
services[].inject_headersNoHeaders added to every request. Supports ${VAR} for environment variables
tip

Values in inject_headers are resolved locally and never sent to the cloud. Use them for credentials only — do not add an Accept header for MCP services (it causes 406 Not Acceptable).

3. Start the agent

services:
zihin-tunnel:
image: ghcr.io/zihin-ai/tunnel-agent:1.3
container_name: zihin-tunnel
restart: unless-stopped
environment:
- ZIHIN_TOKEN=ztun_your_token_here
- SERVICE_API_KEY=your-api-key
- ANOTHER_KEY=another-key
volumes:
- ./zihin-agent.yml:/app/zihin-agent.yml:ro
docker compose up -d
docker compose logs -f zihin-tunnel

Option B: Docker run

docker run -d \
--name zihin-tunnel \
--restart unless-stopped \
-e ZIHIN_TOKEN="ztun_your_token_here" \
-e SERVICE_API_KEY="your-api-key" \
-v $(pwd)/zihin-agent.yml:/app/zihin-agent.yml:ro \
ghcr.io/zihin-ai/tunnel-agent:1.3

Option C: Node.js

The @zihin/tunnel-agent npm package is not yet published. Use Docker for now.

4. Verify the connection

The logs should show one WebSocket connected line per connection (4 by default):

{"level":"info","message":"Zihin Tunnel Agent starting","services":["my-service","another-service"]}
{"level":"info","message":"WebSocket connected","index":0}
{"level":"info","message":"WebSocket connected","index":1}
{"level":"info","message":"WebSocket connected","index":2}
{"level":"info","message":"WebSocket connected","index":3}

In the Console, the tunnel status changes to Connected and lists the registered services.

5. Self-signed certificates

If an internal service uses HTTPS with a private CA, mount the CA certificate and set NODE_EXTRA_CA_CERTS:

services:
zihin-tunnel:
image: ghcr.io/zihin-ai/tunnel-agent:1.3
environment:
- NODE_EXTRA_CA_CERTS=/app/certs/ca-cert.pem
volumes:
- ./zihin-agent.yml:/app/zihin-agent.yml:ro
- ./certs/ca-cert.pem:/app/certs/ca-cert.pem:ro

ssl_verify: false has no effect — TLS verification is always on.

6. Token rotation

When an admin rotates the token in the Console, the previous token keeps working for 24 hours. Update ZIHIN_TOKEN and restart the agent within that window:

docker compose down && docker compose up -d

7. Updating the agent

docker compose pull
docker compose up -d

The agent reconnects automatically. No configuration changes are needed between versions.

Environment-only configuration

For environments where a YAML file is impractical (Kubernetes, ECS):

export ZIHIN_TOKEN="ztun_your_token_here"
export ZIHIN_TUNNEL_URL="wss://tunnel.zihin.ai"
export ZIHIN_LOG_LEVEL="info"
export ZIHIN_POOL_SIZE="4"
export ZIHIN_SERVICES='[
{"name":"my-service","url":"http://192.168.1.100:8080","headers":{"Authorization":"Bearer key"}},
{"name":"another","url":"http://192.168.1.50:3000","headers":{"X-API-Key":"token"}}
]'

If no zihin-agent.yml is found, the agent uses the environment variables.