skills/local/cali-deploy-github-tailscale/SKILL.md
[Cali] Deploy to a private server via Tailscale OIDC with ephemeral credentials. Use when: setting up CI/CD deploy pipeline, configuring Tailscale SSH + OpenSSH for GitHub Actions, creating deploy users with restricted access, writing deploy.yml workflows, or troubleshooting deploy authentication failures. Triggers: "deploy to server", "tailscale deploy", "deploy pipeline", "CI/CD deploy", "deploy workflow", "deploy setup", "deploy key", "deploy user".
npx skillsauth add renatocaliari/agent-sync-public-skills cali-deploy-github-tailscaleInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Zero-trust deployment: ephemeral OIDC credentials, restricted SSH keys, WireGuard tunnel.
GITHUB RUNNER SERVER (100.120.175.47)
│ │
│ Tailscale OIDC (ephemeral) │
│ OpenSSH porta 2222 │
│ chave ed25519 restrita │
│ command= limita comandos │
└─────────────────────────────────┘
│
UFW: só tailscale0
Internet: bloqueada
curl -fsSL https://tailscale.com/install.sh | sh)"tagOwners": {
"tag:continuous-integration": ["autogroup:admin"]
}
{
"src": ["autogroup:member", "tag:continuous-integration"],
"dst": ["<SERVER_IP>"],
"ip": ["tcp:22", "tcp:2222"]
}
repo:{owner}/{repo}:ref:refs/heads/{branch}tag:continuous-integrationRun as root on the server:
# Enable Tailscale SSH
tailscale set --ssh=true
# Discover Tailscale IP
TAILSCALE_IP=$(ip -4 addr show tailscale0 | grep -oP 'inet \K[\d.]+')
# Add port 2222 to SSH socket (Ubuntu systemd)
mkdir -p /etc/systemd/system/ssh.socket.d
cat > /etc/systemd/system/ssh.socket.d/override.conf << EOF
[Socket]
ListenStream=
ListenStream=0.0.0.0:22
ListenStream=[::]:22
ListenStream=$TAILSCALE_IP:2222
FreeBind=yes
EOF
systemctl daemon-reload
systemctl restart ssh.socket
systemctl restart ssh
# Firewall
ufw default deny incoming
ufw default allow outgoing
ufw allow in on tailscale0 to any port 22
ufw allow in on tailscale0 to any port 2222
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable
# Create deploy user
adduser --disabled-password --gecos "" deploy
usermod -aG docker deploy
# Restricted SSH key
cat > /home/deploy/.ssh/authorized_keys << 'KEYEOF'
command="cd /opt/{project} && docker compose pull && docker rm -f {container} 2>/dev/null; docker compose up -d && docker image prune -f",no-agent-forwarding,no-port-forwarding,no-user-rc,no-X11-forwarding ssh-ed25519 AAA... github-actions-deploy-{project}
KEYEOF
chmod 600 /home/deploy/.ssh/authorized_keys
chown -R deploy:deploy /home/deploy/.ssh
# Copy Docker registry auth to deploy user
cp /root/.docker/config.json /home/deploy/.docker/config.json
chown -R deploy:deploy /home/deploy/.docker
| Secret | Value |
|---|---|
| TS_OAUTH_CLIENT_ID | OIDC Client ID |
| TS_AUDIENCE | OIDC Audience |
| DEPLOY_SSH_KEY | Private ed25519 key |
See references/workflow-template.yml for the full template.
Key elements:
id-token: write permission for OIDCtailscale/github-action@v4 for ephemeral authcommand=| Measure | What it protects |
|---|---|
| OIDC (ephemeral JWT) | No permanent credentials on runner |
| command= in authorized_keys | Even with key, only docker compose allowed |
| Port 2222 on Tailscale IP only | Invisible on internet |
| UFW + tailscale0 interface | Only WireGuard traffic |
| deploy user (non-root) | Least privilege |
| Tailscale SSH (personal) | You access without keys, by identity |
| Ephemeral runner node | Disappears after workflow |
# On server (as root):
curl -fsSL https://tailscale.com/install.sh | sh
tailscale set --ssh=true
tailscale status # verify connection
# Create deploy user + restricted key
adduser --disabled-password --gecos "" deploy
usermod -aG docker deploy
- name: Authenticate with Tailscale
uses: tailscale/github-action@v4
with:
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
audience: ${{ secrets.TS_AUDIENCE }}
tags: tag:continuous-integration
- name: Deploy
shell: bash
run: |
echo "$SSH_KEY" > /tmp/deploy_key && chmod 600 /tmp/deploy_key
ssh -i /tmp/deploy_key -p 2222 [email protected] \
'cd /opt/app && docker compose pull && docker compose up -d'
# Check deploy user
ssh [email protected] # should NOT get shell (command= restricts)
ssh [email protected] whoami # should fail (command= only allows docker)
# Check UFW
sudo ufw status verbose # should show only tailscale0 ports
tailscale status on both endscp /root/.docker/config.json /home/deploy/.docker/config.jsonsystemctl status ssh.socketListenStream includes Tailscale IPsystemctl daemon-reload && systemctl restart ssh.socketreferences/workflow-template.yml — Full GitHub Actions workflowreferences/server-setup.sh — Server setup scriptreferences/security-checklist.md — Pre-deploy security verificationdevelopment
PocketBase v0.39+ development - API rules, auth, collections, SDK, realtime, files, Go/JS extending, deployment, production tuning.
tools
Auto-initialize structured documentation for any project using lat.md (knowledge graph of markdown files with [[wiki links]], // @lat: code refs, and semantic search). Detects cali-product-workflow artifacts (spec-product.md, spec-tech.md, critiques) and uses them as seed material. Falls back to extracting business rules, architecture, and design decisions directly from the codebase. Use when a project lacks structured documentation or when lat.md/ is missing. After seeding, lat.md extension hooks keep documentation alive automatically.
testing
[Cali] Server security audit and hardening for private servers behind Tailscale. Use when: auditing server security, hardening SSH/firewall/Docker, checking for vulnerabilities, setting up fail2ban, reviewing port exposure, or responding to security alerts. Covers 6 layers: CloudFlare, UFW, Tailscale, SSH, Docker, Application. Triggers: "server security", "security audit", "harden server", "SSH hardening", "firewall rules", "UFW config", "fail2ban", "port security", "Docker security", "vulnerability check", "security review".
tools
Run supply chain security scans before installing packages or before releases. Triggers when: user installs a package (npm, pip, go get, brew), user asks to 'scan dependencies', 'check vulnerabilities', 'supply chain', 'security audit', 'run trivy', 'run socket', or before any release/deployment. Also triggers on mentions of: socket.dev, trivy, OSV-scanner, dotenvx, CVE, dependency audit. Covers all four tools with concrete commands.