Skip to content

Restrict production deployment transport and sandbox administration - #283

Merged
iamwavecut merged 2 commits into
mainfrom
fix/restricted-deployment-broker
Oct 27, 2026
Merged

iamwavecut merged 2 commits into
mainfrom
fix/restricted-deployment-broker

Conversation

@iamwavecut

@iamwavecut iamwavecut commented Oct 27, 2026 •

Copy link
Copy Markdown
Owner

Changes

  • Build/publish the application in Actions and submit its immutable digest through restricted SSH plus GitHub OIDC.
  • Keep runtime settings, secrets, Docker and the privileged sandbox under administrator control. Fingerprint runtime templates, migrations and sandbox compatibility inputs.
  • Separate manual backup authorization from deployment; remove host script/environment uploads and destructive package cleanup.
  • Constrain OIDC requests to GitHub HTTPS origins, reject redirects and oversized replies, and test the boundaries.
  • Upgrade the vulnerable Zstd family to zstd 0.14.3, zstd-safe 8.2.0 and zstd-sys 2.1.2; no new audit exceptions.

Verification

  • PR CI, dependency gate, security analysis and automated review completed successfully.
  • Local workspace Clippy with warnings denied; server/update tests; formatting: passed.
  • Python: 212 tests, two existing opt-in skips.
  • Actionlint and deployment/backup workflow YAML parsing: passed.
  • Package API confirms the existing application GHCR package is public; anonymous host pulls are intentional.

Deployment risk and verification plan

The production transport changes, but application Rust code, database schema and the running privileged sandbox do not. The Zstd upgrade fixes the existing dependency gate and is covered by update/server tests plus full workspace CI.

The host profile was separately reapplied with the old image and protected settings; health/auth checks passed. A root-only backup completed with verified checksums. Merge only with green CI, deploy the exact main SHA, verify health/readiness and running image identity, exercise rollback to the retained baseline and return to the new image, then revoke only this project's old administrator key. Preserve volumes and rollback images. Sandbox/infrastructure changes remain separate administrator operations.

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Warnings
⚠️ Workflow changes should be verified with actionlint and a YAML parser before merge.
⚠️ Production deploy workflow/assets changed; include an explicit deployment-risk note and verification plan.
Messages
📖 Danger checked 10 changed file(s).

Generated by 🚫 dangerJS against 79a43a9

Comment thread scripts/geta-deploy-request.py Fixed
Comment thread scripts/geta-deploy-request.py Outdated
Comment on lines +81 to +83
if args.check_schema:
_, contract = contract_digest(args.root)
approved = json.loads((args.root / contract['approved_schema']).read_text())

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The shipped contract deploy/geta-deploy.json has no approved_schema key, so
every --check-schema invocation raises KeyError (caught and reported as a
generic failure). Validate the key explicitly and emit a clear error, or add
the key to the contract. [possible issue, importance: 7]

Suggested change
if args.check_schema:
_, contract = contract_digest(args.root)
approved = json.loads((args.root / contract['approved_schema']).read_text())
if args.check_schema:
_, contract = contract_digest(args.root)
approved_path = contract.get('approved_schema')
if not approved_path:
raise ValueError('contract declares no approved_schema; cannot verify migrations')
approved = json.loads((args.root / approved_path).read_text())

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in 79a43a9: --check-schema now explicitly requires an approved_schema contract entry and validates its source-root path. A regression test checks the clear CLI error. Openplotva deployment does not invoke this optional mode.

Comment on lines +137 to +141
- name: Request application-only deployment
env:
GETA_SSH_TARGET: ${{ secrets.GETA_SSH_TARGET }}
GETA_DEPLOY_ROOT: ${{ secrets.GETA_DEPLOY_ROOT }}
DEPLOY_SHA: ${{ github.sha }}
DEPLOY_OPERATION: deploy
OPENPLOTVA_IMAGE_DIGEST: ${{ steps.image.outputs.digest }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The GHCR pull token is no longer sent and the contract sets registry_auth: false,
but the image is pushed under ghcr.io/iamwavecut/openplotva using the ephemeral
GITHUB_TOKEN. If that package is private, the host broker cannot pull it and the
deployment will fail. Confirm the package is public or arrange an authenticated
pull path on the host. [general, importance: 5]

Suggested change
- name: Request application-only deployment
env:
GETA_SSH_TARGET: ${{ secrets.GETA_SSH_TARGET }}
GETA_DEPLOY_ROOT: ${{ secrets.GETA_DEPLOY_ROOT }}
DEPLOY_SHA: ${{ github.sha }}
DEPLOY_OPERATION: deploy
OPENPLOTVA_IMAGE_DIGEST: ${{ steps.image.outputs.digest }}
- name: Request application-only deployment
env:
DEPLOY_SHA: ${{ github.sha }}
DEPLOY_OPERATION: deploy
OPENPLOTVA_IMAGE_DIGEST: ${{ steps.image.outputs.digest }}
run: |
set -euo pipefail
python3 scripts/geta-deploy-request.py |
ssh -T -i ~/.ssh/geta_deploy -o ServerAliveInterval=30 -o ServerAliveCountMax=40 \
deploy@geta.moe "deploy $DEPLOY_SHA"

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Confirmed through the package API: ghcr.io/iamwavecut/openplotva is public. Anonymous host pulls are intentional; the production README now states this explicitly.

if key != 'audience']
query.append(('audience', 'geta-deploy'))
target = endpoint.path + '?' + urllib.parse.urlencode(query)
connection = http.client.HTTPSConnection(endpoint.hostname, timeout=15)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Audited: this helper requires modern Python (Path.is_relative_to alone requires Python 3.9+), and hosted CI uses current Python. HTTPSConnection therefore verifies certificates and hostnames by default. The endpoint is restricted to GitHub Actions HTTPS origins, non-200 replies are rejected, and redirects are not followed. No legacy Python TLS behavior or disabled verification is used.

@iamwavecut
iamwavecut merged commit 50e1bf2 into main Oct 27, 2026
12 checks passed
@iamwavecut
iamwavecut deleted the fix/restricted-deployment-broker branch October 27, 2026 12:09
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.

2 participants