Skip to content

Update deployment SSH key ownership and allow branch-based workflow testing#5

Open
findolor wants to merge 11 commits intomainfrom
chore/local-db-op
Open

Update deployment SSH key ownership and allow branch-based workflow testing#5
findolor wants to merge 11 commits intomainfrom
chore/local-db-op

Conversation

@findolor
Copy link
Copy Markdown
Collaborator

@findolor findolor commented Apr 13, 2026

Motivation

The local DB remote deployment should no longer depend on legacy SSH recipients that are not intended to have access in this repo.

This PR updates the provisioning/deployment access model to use the new github_do key, keeps arda as the only additional recipient, and makes the manual GitHub workflows testable from a non-main branch so provisioning and deploy can be exercised before merge.

Solution

  • change the Terraform SSH key lookup to use github_do
  • update the encrypted-recipient config in keys.nix so only github_do and arda retain access
  • remove the old st0x-op, sid, and ci recipients from the repo config
  • update Provision Host to accept target_ref and allow_non_main, check out the selected ref, and persist Terraform state back to that same ref
  • update Deploy to accept target_ref and allow_non_main so the branch version of the workflow can be exercised against the real host before merge
  • keep the default production path unchanged by defaulting both workflows to target_ref=main and allow_non_main=false

Checks

By submitting this for review, I am confirming I have done the following:

  • made this PR as small as possible
  • unit-tested any new functionality
  • linked any relevant issues or PRs
  • included screenshots (if this involves a front-end change)

Validated locally with:

  • not run yet; workflow changes have been reviewed but not exercised through GitHub Actions from this branch

Summary by CodeRabbit

  • Chores
    • Deployment and provisioning workflows now let you choose a target Git ref, include a validation toggle for non-main refs, and show the selected target in summaries. Workflows decrypt and load runtime config at runtime for deployment and storage operations; state persistence follows the chosen target.
    • Infrastructure defaults updated: new default SSH key, larger VM size, and simplified role assignments for SSH/infra credentials.
  • Documentation
    • Added example runtime env and terraform vars entries documenting optional overrides.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 13, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Workflows now accept workflow_dispatch inputs to select a target ref and optionally allow non-main runs; they validate and checkout that ref, decrypt and load runtime env into $GITHUB_ENV at runtime, and push state to the selected ref. SSH keys/roles and Terraform defaults were updated; example runtime config added.

Changes

Cohort / File(s) Summary
Deploy workflow
.github/workflows/deploy.yaml
Added workflow_dispatch inputs target_ref and allow_non_main; export TARGET_REF; validate TARGET_REF; checkout ref: ${{ env.TARGET_REF }}; decrypt/load runtime env at runtime into $GITHUB_ENV; removed static SPACES/DUMP env entries; include target in summary.
Provision host workflow
.github/workflows/provision-host.yaml
Same workflow_dispatch inputs and TARGET_REF flow; validate TARGET_REF; checkout chosen ref; push state to "$TARGET_REF"; make persisting Terraform state conditional on file existence; update step summaries.
Local DB / utility workflow
.github/workflows/create-empty-local-db-manifest.yaml
Removed static SPACES env entries; added step to write SSH key, use nix shell + rage to decrypt config/runtime.env.age, source temp env, and export DUMP_BASE_URL and SPACES_* into $GITHUB_ENV; adjust manifest URL capture.
Runtime config examples & secrets
config/runtime.env.example, config/secrets.nix
Added config/runtime.env.example with DUMP_BASE_URL and SPACES_* placeholders. Added config/secrets.nix exposing "runtime.env.age".publicKeys = (import ../keys.nix).roles.infra.
SSH keys / roles
keys.nix
Removed st0x-op, ci, sid key entries; added github_do; updated roles.infra and roles.ssh to [ github_do arda ].
Terraform variables & examples
infra/variables.tf, infra/terraform.tfvars.example
Changed Terraform defaults: ssh_key_name st0x-opgithub_do; droplet_size s-1vcpu-1gbs-2vcpu-4gb. Added commented example override lines documenting ssh_key_name, region, and droplet_size.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant GH as GitHub Actions
    participant Runner as Job Runner
    participant Nix as Nix/rage
    participant Git as Git Remote

    User->>GH: trigger workflow_dispatch(target_ref, allow_non_main)
    GH->>Runner: start job with inputs
    Runner->>Runner: set env TARGET_REF = inputs.target_ref
    Runner->>Runner: validate TARGET_REF == "main" OR allow_non_main == true
    alt validation passes
        Runner->>Git: actions/checkout ref=TARGET_REF
        Runner->>Nix: nix shell -> rage decrypt config/runtime.env.age -> /tmp/runtime.env
        Nix->>Runner: decrypted file
        Runner->>Runner: source /tmp/runtime.env -> export DUMP_BASE_URL, SPACES_* to GITHUB_ENV
        Runner->>Runner: run deployment/provision steps
        Runner->>Git: git push origin HEAD:"$TARGET_REF"
        Runner->>Runner: update step summaries with Target ref
    else validation fails
        Runner->>Runner: fail workflow
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the two main changes: updating SSH key ownership from legacy recipients to github_do, and enabling branch-based workflow testing via new inputs.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/local-db-op

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Collaborator Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@findolor findolor changed the title chore: switch provisioning SSH key to local-db-op Update deployment SSH key ownership and allow branch-based workflow testing Apr 13, 2026
@findolor findolor marked this pull request as ready for review April 13, 2026 09:18
@findolor findolor self-assigned this Apr 13, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/provision-host.yaml:
- Around line 37-44: The current Validate target ref step allows tag/SHA refs
when allow_non_main=true, which can lead to attempting a state push to a
non-branch ref; update that step to explicitly verify TARGET_REF is an existing
branch before proceeding (e.g., run a git query such as git ls-remote --heads
origin "$TARGET_REF" or use the GitHub API to confirm a refs/heads/$TARGET_REF
exists) and fail with a clear error if the branch is missing; keep the existing
allow_non_main gating but add this branch-existence check in the same step so
the later state push only runs for valid branch destinations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 49e623d5-3c09-4f09-9351-63cc3ff7d4fe

📥 Commits

Reviewing files that changed from the base of the PR and between f588169 and 991837d.

📒 Files selected for processing (4)
  • .github/workflows/deploy.yaml
  • .github/workflows/provision-host.yaml
  • infra/variables.tf
  • keys.nix

Comment on lines +37 to 44
- name: Validate target ref
shell: bash
run: |
set -euo pipefail
if [ "${GITHUB_REF_NAME}" != "main" ]; then
echo "This workflow must be run from the main branch." >&2
if [ "$TARGET_REF" != "main" ] && [ "${{ inputs.allow_non_main }}" != "true" ]; then
echo "Set allow_non_main=true to provision from a non-main ref." >&2
exit 1
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Constrain target_ref to an existing branch before state push.

Line 90 assumes TARGET_REF is a branch destination. Current validation (Line 37-Line 44) permits tag/SHA-style refs when allow_non_main=true, which can let provisioning run and then fail persisting encrypted Terraform state.

🔧 Suggested hardening
       - uses: actions/checkout@v4
         with:
           ref: ${{ env.TARGET_REF }}
           submodules: recursive
           fetch-depth: 0
+
+      - name: Ensure target_ref is an existing remote branch
+        shell: bash
+        run: |
+          set -euo pipefail
+          if ! git ls-remote --exit-code --heads origin "$TARGET_REF" >/dev/null; then
+            echo "target_ref must be an existing branch name because terraform state is pushed back to it." >&2
+            exit 1
+          fi

Also applies to: 90-90

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/provision-host.yaml around lines 37 - 44, The current
Validate target ref step allows tag/SHA refs when allow_non_main=true, which can
lead to attempting a state push to a non-branch ref; update that step to
explicitly verify TARGET_REF is an existing branch before proceeding (e.g., run
a git query such as git ls-remote --heads origin "$TARGET_REF" or use the GitHub
API to confirm a refs/heads/$TARGET_REF exists) and fail with a clear error if
the branch is missing; keep the existing allow_non_main gating but add this
branch-existence check in the same step so the later state push only runs for
valid branch destinations.

@findolor findolor force-pushed the chore/local-db-op branch 3 times, most recently from 0b08c92 to 743a1f6 Compare April 14, 2026 10:48
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/create-empty-local-db-manifest.yaml:
- Around line 30-48: Extract the repeated SSH/rage decryption block into a
reusable composite action (e.g. create
.github/actions/load-runtime-config/action.yaml) that exposes an input like
"ssh_key" and implements the steps currently in the workflow (mkdir ~/.ssh,
write and chmod id_ed25519, run rage to decrypt config/runtime.env.age to
/tmp/local-db-runtime.env, source it and append DUMP_BASE_URL, SPACES_REGION,
SPACES_BUCKET, SPACES_ENDPOINT to $GITHUB_ENV); then replace the inline block in
this workflow and deploy.yaml with a single step that calls the composite action
and passes secrets.SSH_KEY as the ssh_key input.

In `@infra/variables.tf`:
- Line 10: The default SSH key name variable is set to "github_do" which must
exist in DigitalOcean or Terraform will fail; verify or change the default by
updating the variable `var.ssh_key_name` in `infra/variables.tf` or add the
corresponding SSH key in your DigitalOcean account so the `data
"digitalocean_ssh_key"` lookup in `infra/main.tf` can succeed. Ensure the chosen
name matches the actual key label in DigitalOcean and keep `var.ssh_key_name`
consistent across your Terraform configuration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 07dcdc9b-ed2a-4ece-9ec7-f283d96c64e2

📥 Commits

Reviewing files that changed from the base of the PR and between 0b08c92 and 743a1f6.

📒 Files selected for processing (8)
  • .github/workflows/create-empty-local-db-manifest.yaml
  • .github/workflows/deploy.yaml
  • config/runtime.env.age
  • config/runtime.env.example
  • config/secrets.nix
  • infra/terraform.tfvars.age
  • infra/terraform.tfvars.example
  • infra/variables.tf

Comment on lines +30 to +48
- name: Load encrypted runtime config
shell: bash
run: |
set -euo pipefail
mkdir -p ~/.ssh
printf '%s\n' "${{ secrets.SSH_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
nix shell nixpkgs#rage -c sh -c 'rage -d -i ~/.ssh/id_ed25519 config/runtime.env.age > /tmp/local-db-runtime.env'
set -a
# shellcheck disable=SC1091
source /tmp/local-db-runtime.env
set +a
{
echo "DUMP_BASE_URL=$DUMP_BASE_URL"
echo "SPACES_REGION=$SPACES_REGION"
echo "SPACES_BUCKET=$SPACES_BUCKET"
echo "SPACES_ENDPOINT=$SPACES_ENDPOINT"
} >> "$GITHUB_ENV"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider extracting the runtime config loading to a reusable composite action.

This decryption pattern (SSH key setup + rage decrypt + export to $GITHUB_ENV) is duplicated across deploy.yaml and this workflow. A composite action would reduce maintenance burden and ensure consistency.

♻️ Example composite action structure

Create .github/actions/load-runtime-config/action.yaml:

name: Load encrypted runtime config
description: Decrypt and load runtime.env.age into GITHUB_ENV

inputs:
  ssh_key:
    description: SSH private key for decryption
    required: true

runs:
  using: composite
  steps:
    - shell: bash
      run: |
        set -euo pipefail
        mkdir -p ~/.ssh
        printf '%s\n' "${{ inputs.ssh_key }}" > ~/.ssh/id_ed25519
        chmod 600 ~/.ssh/id_ed25519
        nix shell nixpkgs#rage -c sh -c 'rage -d -i ~/.ssh/id_ed25519 config/runtime.env.age > /tmp/local-db-runtime.env'
        set -a
        source /tmp/local-db-runtime.env
        set +a
        {
          echo "DUMP_BASE_URL=$DUMP_BASE_URL"
          echo "SPACES_REGION=$SPACES_REGION"
          echo "SPACES_BUCKET=$SPACES_BUCKET"
          echo "SPACES_ENDPOINT=$SPACES_ENDPOINT"
        } >> "$GITHUB_ENV"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/create-empty-local-db-manifest.yaml around lines 30 - 48,
Extract the repeated SSH/rage decryption block into a reusable composite action
(e.g. create .github/actions/load-runtime-config/action.yaml) that exposes an
input like "ssh_key" and implements the steps currently in the workflow (mkdir
~/.ssh, write and chmod id_ed25519, run rage to decrypt config/runtime.env.age
to /tmp/local-db-runtime.env, source it and append DUMP_BASE_URL, SPACES_REGION,
SPACES_BUCKET, SPACES_ENDPOINT to $GITHUB_ENV); then replace the inline block in
this workflow and deploy.yaml with a single step that calls the composite action
and passes secrets.SSH_KEY as the ssh_key input.

Comment thread infra/variables.tf
description = "Name of the SSH key in DigitalOcean to add to the droplet"
type = string
default = "st0x-op"
default = "github_do"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check how the SSH key is referenced in main.tf
ast-grep --pattern 'data "digitalocean_ssh_key" $_ {
  $$$
}'

Repository: rainlanguage/rain.local-db.remote

Length of output: 59


🏁 Script executed:

#!/bin/bash
# First, check if the infra directory exists and list relevant files
git ls-files infra/ | head -20

Repository: rainlanguage/rain.local-db.remote

Length of output: 254


🏁 Script executed:

#!/bin/bash
# Search for digitalocean_ssh_key references using rg
rg "digitalocean_ssh_key" --type tf -B 2 -A 2

Repository: rainlanguage/rain.local-db.remote

Length of output: 366


🏁 Script executed:

#!/bin/bash
# Read the actual variables.tf file around line 10
if [ -f infra/variables.tf ]; then
  cat -n infra/variables.tf | head -30
else
  echo "infra/variables.tf not found"
fi

Repository: rainlanguage/rain.local-db.remote

Length of output: 912


Ensure the github_do SSH key exists in DigitalOcean before running Terraform.

The digitalocean_ssh_key data source in infra/main.tf looks up the SSH key by the name stored in var.ssh_key_name. If no SSH key named github_do exists in the DigitalOcean account, Terraform will fail during the apply step.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@infra/variables.tf` at line 10, The default SSH key name variable is set to
"github_do" which must exist in DigitalOcean or Terraform will fail; verify or
change the default by updating the variable `var.ssh_key_name` in
`infra/variables.tf` or add the corresponding SSH key in your DigitalOcean
account so the `data "digitalocean_ssh_key"` lookup in `infra/main.tf` can
succeed. Ensure the chosen name matches the actual key label in DigitalOcean and
keep `var.ssh_key_name` consistent across your Terraform configuration.

@findolor findolor force-pushed the chore/local-db-op branch from 743a1f6 to ea4d719 Compare April 14, 2026 12:47
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/create-empty-local-db-manifest.yaml:
- Around line 30-47: The decrypted runtime file /tmp/local-db-runtime.env
created in the "Load encrypted runtime config" step contains sensitive secrets
and must be removed after use; modify the step so that after sourcing and
appending the needed variables to GITHUB_ENV you securely delete the temporary
file (e.g., overwrite/shred if available or at minimum rm -f
/tmp/local-db-runtime.env) and ensure it had restrictive permissions while
present; reference the commands that create/source the file (nix shell ... >
/tmp/local-db-runtime.env and source /tmp/local-db-runtime.env) and add a
cleanup action immediately after exporting the variables.

In @.github/workflows/deploy.yaml:
- Around line 74-88: The decrypted runtime file /tmp/local-db-runtime.env is
left on disk after the "Load encrypted runtime config" step; update that step
(the shell block that runs nix/rage and sources /tmp/local-db-runtime.env) to
securely remove the file when done by adding a removal command (e.g., rm -f
/tmp/local-db-runtime.env) after exporting the variables to $GITHUB_ENV so the
temporary secret file does not persist on the runner.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 40a610b8-8592-4734-be71-fc916fb07d33

📥 Commits

Reviewing files that changed from the base of the PR and between 743a1f6 and ea4d719.

📒 Files selected for processing (8)
  • .github/workflows/create-empty-local-db-manifest.yaml
  • .github/workflows/deploy.yaml
  • config/runtime.env.age
  • config/runtime.env.example
  • config/secrets.nix
  • infra/terraform.tfvars.age
  • infra/terraform.tfvars.example
  • infra/variables.tf

Comment on lines +30 to +47
- name: Load encrypted runtime config
shell: bash
run: |
set -euo pipefail
mkdir -p ~/.ssh
printf '%s\n' "${{ secrets.SSH_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
nix shell nixpkgs#rage -c sh -c 'rage -d -i ~/.ssh/id_ed25519 config/runtime.env.age > /tmp/local-db-runtime.env'
set -a
# shellcheck disable=SC1091
source /tmp/local-db-runtime.env
set +a
{
echo "DUMP_BASE_URL=$DUMP_BASE_URL"
echo "SPACES_REGION=$SPACES_REGION"
echo "SPACES_BUCKET=$SPACES_BUCKET"
echo "SPACES_ENDPOINT=$SPACES_ENDPOINT"
} >> "$GITHUB_ENV"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider cleaning up the decrypted secrets file.

The decrypted runtime config at /tmp/local-db-runtime.env contains sensitive values and persists after the step completes. Consider adding cleanup for defense in depth.

🛡️ Suggested cleanup
          {
            echo "DUMP_BASE_URL=$DUMP_BASE_URL"
            echo "SPACES_REGION=$SPACES_REGION"
            echo "SPACES_BUCKET=$SPACES_BUCKET"
            echo "SPACES_ENDPOINT=$SPACES_ENDPOINT"
          } >> "$GITHUB_ENV"
+         rm -f /tmp/local-db-runtime.env
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Load encrypted runtime config
shell: bash
run: |
set -euo pipefail
mkdir -p ~/.ssh
printf '%s\n' "${{ secrets.SSH_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
nix shell nixpkgs#rage -c sh -c 'rage -d -i ~/.ssh/id_ed25519 config/runtime.env.age > /tmp/local-db-runtime.env'
set -a
# shellcheck disable=SC1091
source /tmp/local-db-runtime.env
set +a
{
echo "DUMP_BASE_URL=$DUMP_BASE_URL"
echo "SPACES_REGION=$SPACES_REGION"
echo "SPACES_BUCKET=$SPACES_BUCKET"
echo "SPACES_ENDPOINT=$SPACES_ENDPOINT"
} >> "$GITHUB_ENV"
- name: Load encrypted runtime config
shell: bash
run: |
set -euo pipefail
mkdir -p ~/.ssh
printf '%s\n' "${{ secrets.SSH_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
nix shell nixpkgs#rage -c sh -c 'rage -d -i ~/.ssh/id_ed25519 config/runtime.env.age > /tmp/local-db-runtime.env'
set -a
# shellcheck disable=SC1091
source /tmp/local-db-runtime.env
set +a
{
echo "DUMP_BASE_URL=$DUMP_BASE_URL"
echo "SPACES_REGION=$SPACES_REGION"
echo "SPACES_BUCKET=$SPACES_BUCKET"
echo "SPACES_ENDPOINT=$SPACES_ENDPOINT"
} >> "$GITHUB_ENV"
rm -f /tmp/local-db-runtime.env
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/create-empty-local-db-manifest.yaml around lines 30 - 47,
The decrypted runtime file /tmp/local-db-runtime.env created in the "Load
encrypted runtime config" step contains sensitive secrets and must be removed
after use; modify the step so that after sourcing and appending the needed
variables to GITHUB_ENV you securely delete the temporary file (e.g.,
overwrite/shred if available or at minimum rm -f /tmp/local-db-runtime.env) and
ensure it had restrictive permissions while present; reference the commands that
create/source the file (nix shell ... > /tmp/local-db-runtime.env and source
/tmp/local-db-runtime.env) and add a cleanup action immediately after exporting
the variables.

Comment on lines +74 to +88
- name: Load encrypted runtime config
shell: bash
run: |
set -euo pipefail
nix shell nixpkgs#rage -c sh -c 'rage -d -i ~/.ssh/id_ed25519 config/runtime.env.age > /tmp/local-db-runtime.env'
set -a
# shellcheck disable=SC1091
source /tmp/local-db-runtime.env
set +a
{
echo "DUMP_BASE_URL=$DUMP_BASE_URL"
echo "SPACES_REGION=$SPACES_REGION"
echo "SPACES_BUCKET=$SPACES_BUCKET"
echo "SPACES_ENDPOINT=$SPACES_ENDPOINT"
} >> "$GITHUB_ENV"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider cleaning up the decrypted secrets file.

Same as in create-empty-local-db-manifest.yaml: the decrypted runtime config at /tmp/local-db-runtime.env persists after the step. Consider adding rm -f /tmp/local-db-runtime.env at the end for defense in depth.

🛡️ Suggested cleanup
          {
            echo "DUMP_BASE_URL=$DUMP_BASE_URL"
            echo "SPACES_REGION=$SPACES_REGION"
            echo "SPACES_BUCKET=$SPACES_BUCKET"
            echo "SPACES_ENDPOINT=$SPACES_ENDPOINT"
          } >> "$GITHUB_ENV"
+         rm -f /tmp/local-db-runtime.env
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Load encrypted runtime config
shell: bash
run: |
set -euo pipefail
nix shell nixpkgs#rage -c sh -c 'rage -d -i ~/.ssh/id_ed25519 config/runtime.env.age > /tmp/local-db-runtime.env'
set -a
# shellcheck disable=SC1091
source /tmp/local-db-runtime.env
set +a
{
echo "DUMP_BASE_URL=$DUMP_BASE_URL"
echo "SPACES_REGION=$SPACES_REGION"
echo "SPACES_BUCKET=$SPACES_BUCKET"
echo "SPACES_ENDPOINT=$SPACES_ENDPOINT"
} >> "$GITHUB_ENV"
- name: Load encrypted runtime config
shell: bash
run: |
set -euo pipefail
nix shell nixpkgs#rage -c sh -c 'rage -d -i ~/.ssh/id_ed25519 config/runtime.env.age > /tmp/local-db-runtime.env'
set -a
# shellcheck disable=SC1091
source /tmp/local-db-runtime.env
set +a
{
echo "DUMP_BASE_URL=$DUMP_BASE_URL"
echo "SPACES_REGION=$SPACES_REGION"
echo "SPACES_BUCKET=$SPACES_BUCKET"
echo "SPACES_ENDPOINT=$SPACES_ENDPOINT"
} >> "$GITHUB_ENV"
rm -f /tmp/local-db-runtime.env
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/deploy.yaml around lines 74 - 88, The decrypted runtime
file /tmp/local-db-runtime.env is left on disk after the "Load encrypted runtime
config" step; update that step (the shell block that runs nix/rage and sources
/tmp/local-db-runtime.env) to securely remove the file when done by adding a
removal command (e.g., rm -f /tmp/local-db-runtime.env) after exporting the
variables to $GITHUB_ENV so the temporary secret file does not persist on the
runner.

@findolor findolor force-pushed the chore/local-db-op branch 5 times, most recently from 83ae77c to 8516824 Compare April 15, 2026 06:58
@findolor findolor force-pushed the chore/local-db-op branch from 8516824 to 3f38d00 Compare April 15, 2026 07:26
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