Skip to content

ci(deploy): trigger Coolify deploys over a restricted SSH key - #63

Merged
neo773 merged 1 commit into
masterfrom
chore/ssh-deploy
Oct 24, 2026
Merged

neo773 merged 1 commit into
masterfrom
chore/ssh-deploy

Conversation

@neo773

@neo773 neo773 commented Oct 24, 2026

Copy link
Copy Markdown
Owner

Why

Coolify's dashboard (port 8888) was open to the internet only so the deploy job could call its HTTP API. Coolify has had a run of RCE CVEs this year, so the port should be private.

What

  • The deploy job now SSHes into the server (port 69) as a deployer user and runs deploy.
  • That key is jailed on the server:
    • restrict blocks shells, port forwarding and PTYs.
    • A forced command allows only check and deploy.
    • sudo is limited to /usr/local/bin/coolify-deploy check|deploy.
  • The host key is pinned (StrictHostKeyChecking=yes).
  • The step waits for the Coolify deployment to reach finished or failed, so a failed build now fails CI.
  • The harden-runner egress allowlist swaps the Coolify HTTP endpoint for <host>:69.

Secrets

New production environment secrets: DEPLOY_SSH_HOST, DEPLOY_SSH_KEY, DEPLOY_SSH_KNOWN_HOSTS.

After this deploys successfully, the old COOLIFY_URL, COOLIFY_TOKEN, COOLIFY_APP_UUID and COOLIFY_EGRESS_ENDPOINT can be deleted, the Coolify API token revoked, and port 8888 closed.

🤖 Generated with Claude Code

Coolify's dashboard port was public only so CI could call its deploy API.
CI now SSHes in as a jailed `deployer` user whose key can only run the
deploy command, so the dashboard can be locked to localhost.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@neo773
neo773 merged commit 823230d into master Oct 24, 2026
2 checks passed
@neo773
neo773 deleted the chore/ssh-deploy branch October 24, 2026 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant