Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions .github/workflows/ops-box-ssh-access.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: ops-box-ssh-access

on:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ops-box-ssh-access
cancel-in-progress: false

jobs:
inject:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 security Pin privileged checkout action

This workflow resolves actions/checkout@v4 through a mutable tag before it runs the checked-out do-firewall action with the DigitalOcean token. If the tag is repointed or compromised, altered checkout behavior can replace the local firewall action before it receives that privileged token.

How this was verified: The workflow checks out through actions/checkout@v4 before passing DIGITALOCEAN_TOKEN to the checked-out firewall action.

Artifacts

Evidence from the check

  • The authored Bash script checks the workflow ordering and composite-action token path; it is the executable proof used for this validation.

Command output from the check

  • Captured execution output records lines 18, 32, 35, 41, and 65 and exits successfully, confirming the supplied security proof.

View artifacts

T-Rex Ran code and verified through T-Rex


- name: Install SSH key
run: |
set -euo pipefail
KEY="${{ secrets.PROD_SSH_KEY || secrets.STAGING_SSH_KEY }}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Use staging SSH identity

When both credentials are configured, this selects PROD_SSH_KEY once and uses it for every target, including the staging hosts. The staging deployment uses STAGING_SSH_KEY separately, so staging hosts that accept only their scoped key cannot receive the box key and firewall update.

Artifacts

Evidence from the check

  • The authored shell validator asserts the exact workflow definitions and runs fixture key selection plus host-loop expansion, showing the test method.

Command output from the check

  • The executed staging-only fixture selects STAGING_SSH_KEY and emits attempts solely for the two staging hosts, establishing the scoped baseline.

Command output from the check

  • The executed mixed fixture selects PROD_SSH_KEY and emits attempts for both production and staging hosts, proving the credential-target mismatch.

View artifacts

T-Rex Ran code and verified through T-Rex

test -n "$KEY" || { echo "missing PROD_SSH_KEY/STAGING_SSH_KEY"; exit 1; }
mkdir -p ~/.ssh
printf '%s\n' "$KEY" > ~/.ssh/deploy_ed25519
chmod 600 ~/.ssh/deploy_ed25519
echo "StrictHostKeyChecking accept-new" > ~/.ssh/config

- name: Open firewall for runner
id: fw
uses: ./.github/actions/do-firewall
with:
action: open
token: ${{ secrets.DIGITALOCEAN_TOKEN }}

- name: Inject box pubkey + ufw on hosts
env:
BOX_PUB: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKqDZSYE3t7O+bP80+wOcCLSbsAqzWiERBVqPSmMOsIi box@cursor"
run: |
set -euo pipefail
ID="$HOME/.ssh/deploy_ed25519"
ssh_cmd() { ssh -i "$ID" -o BatchMode=yes -o StrictHostKeyChecking=accept-new -o ConnectTimeout=20 "$@"; }
hosts=()
[[ -n "${{ secrets.PROD_HOST }}" ]] && hosts+=("prod-master|root@${{ secrets.PROD_HOST }}|ufw")
[[ -n "${{ secrets.PROD_VALIDATOR_HOST }}" ]] && hosts+=("prod-validator|root@${{ secrets.PROD_VALIDATOR_HOST }}|")
[[ -n "${{ secrets.STAGING_MASTER_HOST }}" ]] && hosts+=("staging-master|root@${{ secrets.STAGING_MASTER_HOST }}|")
[[ -n "${{ secrets.STAGING_VALIDATOR_HOST }}" ]] && hosts+=("staging-validator|root@${{ secrets.STAGING_VALIDATOR_HOST }}|")
# hard fallbacks if secrets empty names but common IPs known in ops
if [[ ${#hosts[@]} -eq 0 ]]; then
echo "no host secrets; failing"; exit 1
fi
ok=0
for entry in "${hosts[@]}"; do
name="${entry%%|*}"; rest="${entry#*|}"; target="${rest%%|*}"; mode="${rest##*|}"
echo "::group::$name $target"
if ssh_cmd "$target" "set -euo pipefail
mkdir -p /root/.ssh; chmod 700 /root/.ssh
touch /root/.ssh/authorized_keys; chmod 600 /root/.ssh/authorized_keys
grep -qxF '$BOX_PUB' /root/.ssh/authorized_keys || echo '$BOX_PUB' >> /root/.ssh/authorized_keys
echo injected_ok
if [[ '$mode' == ufw ]]; then
ufw allow OpenSSH || ufw allow 22/tcp || true
ufw --force enable || true
Comment on lines +63 to +64

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Preserve production service ports

If the production host uses UFW's default-deny incoming policy, this workflow enables UFW after allowing only SSH. The production master serves traffic on ports 80, 443, and 8080, so dispatching it can block the public gateway and validator connection, causing a production outage.

Artifacts

Evidence from the check

  • The authored Bash script checks the exact workflow UFW commands and the repository's production port requirements; it encodes the narrow supplied finding.

Command output from the check

  • The captured repository excerpts show the SSH-only UFW enablement, production port publishing, Caddy HTTPS contract, and DigitalOcean firewall rules; they establish the compared static state.

Command output from the check

  • The executed validation script exits 0 after confirming SSH-only host-UFW setup alongside required production ports 80, 443, and 8080; the supplied finding is supported.

Evidence from the check

  • A minimal authored Bash harness stubs UFW failures and executes the workflow-equivalent remote command, ending with the finding that masked failures produce host success.

Command output from the check

  • The executed harness output shows all mocked UFW operations exit 42 yet the current block reports SUCCESS, while the fail-closed comparison reports FAIL, ending with the finding that errors are masked.

Command output from the check

  • The captured changed-file inspection shows `|| true` at lines 63-66 and the subsequent SUCCESS branch at lines 68-69, ending with the finding that the workflow can report a host successful after UFW failure.

View artifacts

T-Rex Ran code and verified through T-Rex

ufw reload || true
ufw status || true
Comment on lines +63 to +66

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Fail on UFW errors

Every UFW operation suppresses failures with || true. A missing UFW installation or failed allow, enable, reload, or status command still lets the SSH block report the host as successful, so the workflow can finish green without creating the requested firewall access.

Artifacts

Evidence from the check

  • The authored Bash script checks the exact workflow UFW commands and the repository's production port requirements; it encodes the narrow supplied finding.

Command output from the check

  • The captured repository excerpts show the SSH-only UFW enablement, production port publishing, Caddy HTTPS contract, and DigitalOcean firewall rules; they establish the compared static state.

Command output from the check

  • The executed validation script exits 0 after confirming SSH-only host-UFW setup alongside required production ports 80, 443, and 8080; the supplied finding is supported.

Evidence from the check

  • A minimal authored Bash harness stubs UFW failures and executes the workflow-equivalent remote command, ending with the finding that masked failures produce host success.

Command output from the check

  • The executed harness output shows all mocked UFW operations exit 42 yet the current block reports SUCCESS, while the fail-closed comparison reports FAIL, ending with the finding that errors are masked.

Command output from the check

  • The captured changed-file inspection shows `|| true` at lines 63-66 and the subsequent SUCCESS branch at lines 68-69, ending with the finding that the workflow can report a host successful after UFW failure.

View artifacts

T-Rex Ran code and verified through T-Rex

fi
hostname; ss -lnt | head"; then
echo SUCCESS "$name"; ok=$((ok+1))
else
echo FAIL "$name"
fi
echo "::endgroup::"
done
echo "ok_hosts=$ok"
test "$ok" -gt 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Require all target hosts

The final assertion requires only one successful target. If another host rejects the SSH key or its update fails, the workflow still succeeds after updating a different host, silently leaving the rollout incomplete.

Artifacts

Evidence from the check

  • Minimal Bash harness simulating one successful and one failed target while applying the workflow's exact final predicate; it tests that partial success is accepted.

Command output from the check

  • Captured execution of the harness from `/home/user/repo`, showing one success, one failure, and an overall exit code of 0; the workflow condition permits partial rollout.

Command output from the check

  • Captured numbered workflow excerpt showing the success counter, failure branch, and `test "$ok" -gt 0` at line 76; the condition only requires one successful host.

View artifacts

T-Rex Ran code and verified through T-Rex


- name: Close firewall
if: always() && steps.fw.outputs.ip != ''
uses: ./.github/actions/do-firewall
with:
action: close
token: ${{ secrets.DIGITALOCEAN_TOKEN }}
ip: ${{ steps.fw.outputs.ip }}
firewall-id: ${{ steps.fw.outputs.firewall-id }}
Loading