home

Conductor connected to Tailscale and Infisical

Nickitah Petintsev

Our company's infrastructure is private and served under a private mesh called Tailscale. With cloud agents benefits, we faced the problem of securely connecting cloud VMs to the private mesh. I'm an active user of @conductor_build and wanted cloud and private mesh together.

In this article I'm gonna share with you my config that I've used for around 2 months.

Tailscale & Cloud VM

In Conductor each workspace is equal to one VM. After shipping a feature we usually archive the workspace, which puts the VM into a so-called sleep mode. We don't want to have our VM always on and connected to our mesh, that's why Tailscale created Ephemeral nodes that automatically remove the device from your tailnet when it goes offline.

Connecting Tailscale to Conductor Cloud Computer

If you're using another Agentic IDE it would be something like a global configuration for all VMs or pre-setup settings. Here is shortly the flow you need to do:

  1. Install the Tailscale CLI in the cloud computer's install script.
  2. Generate an ephemeral TAILSCALE_AUTHKEY (Reusable + Ephemeral) and paste it into the Conductor shared env.
  3. Add a tailscale-connect call to all repos' setup scripts, so every new workspace gets its own ephemeral node.

tailscale-connect is a small helper that does tailscale up --auth-key=$TAILSCALE_AUTHKEY for you. A plain tailscale up doesn't work on Conductor VMs (no systemd, link-local address only, read-only /etc/hosts), so the helper works around that. The full script is at the end of the article.

Rebuild a cloud machine and create a workspace (CMD+N)

After creating a machine a new record with ephemeral tag appears in Tailscale dashboard, indicating success.

CleanShot 2026-10-21 at 00.59.28@2x

Infisical over the mesh

Our secrets live in Infisical, self-hosted inside the tailnet, so it can't be reached without Tailscale. The VM first joins the mesh, then logs into Infisical, and every script runs as infisical run -- pnpm ... instead of a local .env.

The flow is the same as the Infisical guide for Cursor cloud agents:

  1. Install the Infisical CLI in the cloud computer's install script.
  2. Create a Universal Auth machine identity in Infisical (Organization settings → Machine Identities).
  3. Add to the Conductor shared env: INFISICAL_API_URL (your Infisical's Tailscale address), INFISICAL_CLIENT_ID, INFISICAL_CLIENT_SECRET.
  4. Add infisical-connect right after tailscale-connect in all repos' setup scripts.

Infisical-connect logs in with the machine identity, reads the project id from the repo's .infisical.yaml, and exports INFISICAL_TOKEN into ~/.bash_profile11: To save env vars from this script for later use, write them to ~/. bash_profile. After that machine is authorized and can run infisical cli commands as usual.

Result

Every new workspace joins the tailnet as an ephemeral node, logs into Infisical over the mesh, and has the project's secrets in every shell. Archive the workspace and the node is gone. Nothing identity-bound lives in the snapshot, only in the Conductor shared env:

VariableWhat
TAILSCALE_AUTHKEYreusable, ephemeral, pre-authorized, 90-day max
INFISICAL_API_URLInfisical's address inside the tailnet
INFISICAL_CLIENT_ID / INFISICAL_CLIENT_SECRETuniversal-auth machine identity

The whole cloud computer setup

Two scripts, that's all. The install script runs once when Conductor builds the computer snapshot. The setup script runs for every new workspace.

Install script (cloud computer)
#!/usr/bin/env bash
set -euo pipefail

sudo curl -fsSL https://pkgs.tailscale.com/stable/amazon-linux/2023/tailscale.repo -o /etc/yum.repos.d/tailscale.repo
sudo dnf install -y tailscale

curl -1sLf https://artifacts-cli.infisical.com/setup.rpm.sh | sudo -E bash
sudo dnf install -y infisical

sudo tee /usr/local/bin/tailscale-connect >/dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

if [ -z "${TAILSCALE_AUTHKEY:-}" ]; then
  echo "tailscale-connect: TAILSCALE_AUTHKEY is not set; skipping" >&2
  exit 0
fi

ip -4 addr show eth0 | grep -q 10.255.255.1/32 || sudo ip addr add 10.255.255.1/32 dev eth0

if ! pgrep -x tailscaled >/dev/null; then
  sudo mkdir -p /var/lib/tailscale /var/run/tailscale
  sudo setsid nohup tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/var/run/tailscale/tailscaled.sock >/var/log/tailscaled.log 2>&1 </dev/null &
  for _ in $(seq 30); do
    [ -S /var/run/tailscale/tailscaled.sock ] && break
    sleep 1
  done
fi

state=$(sudo tailscale status --json 2>/dev/null | python3 -c 'import sys,json;print(json.load(sys.stdin)["BackendState"])' || true)
if [ "$state" != "Running" ]; then
  sudo tailscale up \
    --auth-key="$TAILSCALE_AUTHKEY" \
    --hostname="conductor-${TAILSCALE_HOSTNAME:-$(hostname | cut -c1-40)}" \
    --accept-dns=false \
    --accept-routes \
    --netfilter-mode=off \
    --timeout=60s
fi

if ! sudo test -w /etc/hosts; then
  sudo mkdir -p /var/lib/tailscale-connect
  sudo cp /etc/hosts /var/lib/tailscale-connect/hosts
  sudo mount --bind /var/lib/tailscale-connect/hosts /etc/hosts
fi
sudo python3 - <<'PY'
import json, re, subprocess
status = json.loads(subprocess.check_output(["tailscale", "status", "--json"]))
lines = []
for peer in [status["Self"], *status.get("Peer", {}).values()]:
    name = peer.get("DNSName", "").rstrip(".")
    ipv4 = [ip for ip in peer.get("TailscaleIPs", []) if ":" not in ip]
    if name and ipv4:
        lines.append(f"{ipv4[0]} {name} {name.split('.')[0]}")
block = "# BEGIN tailscale-connect\n" + "\n".join(lines) + "\n# END tailscale-connect\n"
hosts = open("/etc/hosts").read()
hosts = re.sub(r"\n?# BEGIN tailscale-connect.*?# END tailscale-connect\n?", "\n", hosts, flags=re.S).rstrip("\n") + "\n"
open("/etc/hosts", "w").write(hosts + block)
PY

echo "tailscale-connect: $(sudo tailscale ip -4)"
EOF

sudo tee /usr/local/bin/infisical-connect >/dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

for var in INFISICAL_API_URL INFISICAL_CLIENT_ID INFISICAL_CLIENT_SECRET; do
  if [ -z "${!var:-}" ]; then
    echo "infisical-connect: $var is not set; skipping" >&2
    exit 0
  fi
done

api="${INFISICAL_API_URL%/}"
[[ "$api" == */api ]] || api="$api/api"

token=$(infisical login --method=universal-auth --client-id="$INFISICAL_CLIENT_ID" --client-secret="$INFISICAL_CLIENT_SECRET" --domain="$api" --silent --plain </dev/null)

read -r project_id environment < <(python3 - <<'PY'
import json, os, re
project, env = "", ""
if os.path.exists(".infisical.yaml"):
    text = open(".infisical.yaml").read()
    project = (re.search(r"project-id:\s*(\S+)", text) or [None, ""])[1]
    env = (re.search(r"default-environment:\s*(\S+)", text) or [None, ""])[1]
elif os.path.exists(".infisical.json"):
    config = json.load(open(".infisical.json"))
    project, env = config.get("workspaceId", ""), config.get("defaultEnvironment", "")
print(project or "-", env.strip('"') or "-")
PY
)
[ "$project_id" != "-" ] || project_id="${INFISICAL_PROJECT_ID:-}"
[ "$environment" != "-" ] || environment="${INFISICAL_ENVIRONMENT:-dev}"

umask 077
cat > "$HOME/.infisical.env" <<ENV
export INFISICAL_API_URL="$api"
export INFISICAL_TOKEN="$token"
export INFISICAL_ENVIRONMENT="$environment"
export INFISICAL_DISABLE_UPDATE_CHECK=true
${project_id:+export INFISICAL_PROJECT_ID="$project_id"}
ENV
grep -q infisical.env "$HOME/.bash_profile" 2>/dev/null || printf '\n[ -f "$HOME/.infisical.env" ] && . "$HOME/.infisical.env"\n' >> "$HOME/.bash_profile"

. "$HOME/.infisical.env"
count=$(cd "$(mktemp -d)" && infisical secrets --plain </dev/null 2>/dev/null | wc -l)
echo "infisical-connect: project ${project_id:-none} env $environment, $count secrets"
EOF

sudo chmod +x /usr/local/bin/tailscale-connect /usr/local/bin/infisical-connect
Setup script (every repo)
#!/usr/bin/env bash
set -euo pipefail
tailscale-connect
infisical-connect

Refs:

Footnotes

  1. To save env vars from this script for later use, write them to ~/. bash_profile ↩