Connect via DQC Proxy
The DQC Proxy connects your databases to the DQC Platform without opening a single inbound firewall port. It runs as a small service inside your network and establishes an outbound, TLS-encrypted tunnel (WSS over port 443) to the DQC tunnel gateway. All database access from the platform travels through this tunnel — your firewall stays closed.
In one sentence: the DQC Platform reaches your database exclusively through the tunnel that your proxy established from the inside out — and even then only the targets you explicitly allowlisted.
System requirements
Linux server or VM (x86_64 or ARM64) — 1 vCPU / 256 MB RAM are plenty
Outbound HTTPS (port 443) to
gw.shared.app.dqc.aiNetwork access from the proxy host to the database(s) you want to connect
No inbound firewall rules required
Download & installation
Download the archive for your architecture from the DQC Proxy releases page:
dqcproxy-linux-amd64.tar.gz — Linux x86_64
dqcproxy-linux-arm64.tar.gz — Linux ARM64 (aarch64)
SHA256SUMS — checksums for both archives
Verify the checksum, then install:
sha256sum --check --ignore-missing SHA256SUMS
tar -xzf dqcproxy-linux-<arch>.tar.gz
sudo install -m 0755 dqcproxy /usr/local/bin/dqcproxyCurrent checksums (v0.1.0): amd64 e3b8e49004dd771d16c49bcd3027539116cd8fe9469fe0811252c4e0b8e7c76b, arm64 ebf774d7ad2d3d4b2debc488c0c586d0c056743ce8496b36af1d481ddcd5ef78.
Run as a dedicated VM (cloud-init)
If you prefer a dedicated proxy VM in your infrastructure, create a standard Ubuntu 22.04/24.04 minimal VM (1 vCPU / 1 GB RAM / 10 GB disk) and attach our cloud-init.yaml as user-data — fill in your token and allowlist, boot, done. The VM installs the proxy (checksum-verified), hardens the service, and enables unattended OS security updates. For an already-running VM there is an install.sh:
curl -fsSLO https://github.com/dataqcompany/dqcproxy-releases/raw/main/vm/install.sh
sudo bash install.sh --token dqcpx_YOUR_TOKEN --allow "db1.internal.example.com:5432"The operating system stays under your control and patch policy — the proxy is a single static binary on top.
Run as a container
If you run Docker or Kubernetes, use the public multi-arch image ghcr.io/dataqcompany/dqcproxy instead of a VM:
docker run -d --name dqcproxy --restart always \
-e DQCPROXY_MODE=client \
-e DQCPROXY_GATEWAY_URL=wss://gw.shared.app.dqc.ai \
-e DQCPROXY_TOKEN=dqcpx_YOUR_TOKEN \
-e DQCPROXY_ALLOW="db1.internal.example.com:5432" \
ghcr.io/dataqcompany/dqcproxy:latestNo ports are published — the proxy is outbound-only. The image is distroless (no shell, no package manager) and runs as a non-root user.
Start the proxy
You receive a one-time enrollment token (dqcpx_…) from DQC. It identifies your proxy to the gateway — treat it like a password.
dqcproxy --mode=client \
--gateway wss://gw.shared.app.dqc.ai \
--token dqcpx_YOUR_TOKEN \
--allow "db1.internal.example.com:5432,db2.internal.example.com:1433"On success the log shows:
{"level":"INFO","msg":"tunnel established","gateway":"wss://gw.shared.app.dqc.ai"}Run as a systemd service (recommended)
/etc/systemd/system/dqcproxy.service:
[Unit]
Description=DQC Proxy (reverse tunnel to the DQC Platform)
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/dqcproxy --mode=client
Environment=DQCPROXY_GATEWAY_URL=wss://gw.shared.app.dqc.ai
EnvironmentFile=/etc/dqcproxy/env
Restart=always
RestartSec=5
DynamicUser=yes
NoNewPrivileges=yes
ProtectSystem=strict
[Install]
WantedBy=multi-user.target/etc/dqcproxy/env (mode 600, owned by root):
DQCPROXY_TOKEN=dqcpx_YOUR_TOKEN
DQCPROXY_ALLOW=db1.internal.example.com:5432Enable it with sudo systemctl enable --now dqcproxy.
Configuration reference
Every flag can alternatively be set as an environment variable:
--mode/DQCPROXY_MODE— alwaysclientin your network--gateway/DQCPROXY_GATEWAY_URL— gateway URL:wss://gw.shared.app.dqc.ai--token/DQCPROXY_TOKEN— your enrollment token (dqcpx_…)--allow/DQCPROXY_ALLOW— allowlist of reachable targets (see below)
Target allowlist
The proxy connects exclusively to targets you allow here — everything else is rejected (default deny). Comma-separated entries, three forms:
host:port— exactly this host and port, e.g.db1.internal.example.com:5432*.domain:port— all subdomains, fixed port, e.g.*.sql.example.com:1433host:*— fixed host, any port, e.g.dwh.example.com:*
Blanket patterns like *:5432 are deliberately not accepted.
Security
Outbound only: the proxy never opens a listening port. It dials the DQC gateway via WSS (TLS, port 443).
No credentials in the proxy: database credentials stay encrypted in the DQC Platform. The proxy relays opaque bytes; with database TLS enabled it only ever sees encrypted traffic.
Allowlist in your hands: target restrictions are enforced inside your network. Even a fully compromised cloud counterpart could only reach the
host:porttargets you listed.Server-authoritative routes: which targets are requested is determined by the connectors configured in the DQC Platform — the tunnel does not transport arbitrary externally chosen addresses.
No code execution: the proxy contains no business logic and executes nothing. A single static binary.
Troubleshooting
tunnel establishednever appears — outbound port 443 togw.shared.app.dqc.aiis blocked (check firewall/web proxy) or the token is invalid. Contact DQC support.The log shows a rejected target — the target
host:portis missing from--allow. Add it and restart the service. Note:localhostand127.0.0.1are distinct entries.Connection drops — the proxy reconnects automatically with backoff; short interruptions heal themselves. A permanent reconnect loop: contact DQC support.
Error “refusing plaintext ws://” — the gateway URL must start with
wss://(TLS).ws://is only permitted in development setups.
Questions? support@dqc.ai — please include a log excerpt and the release version.