Commit Graph
2 Commits
Author SHA1 Message Date
Satoshi Qazi Muhammed f6d53f51b1 ci: deploy over pinned, single-purpose keys; root installs the gate
The deploy reached VPS3 as root with one key, handed to appleboy actions
referenced by tag, and on every run it reinstalled the edge-function
ownership gate and its registry as root. That gate guards every project's
functions in the shared volume, so any change merged here could rewrite the
rule that protects pwap's functions.

Now CI connects as miniapp-deploy with two keys, each pinned on the host
(authorized_keys restrict,command=) to a script in ops/host:

- MINIAPP_SITE_DEPLOY_KEY -> miniapp-site-receive: the site tar on stdin,
  into /var/www/telegram.pezkiwi.app, nothing else.
- MINIAPP_FUNCTIONS_DEPLOY_KEY -> miniapp-functions-ssh: `gate-sha`, or
  `deploy` with functions.tgz on stdin, run through sudo for exactly those
  arguments.

Root installs the gate and registry from ops/; the deploy checks the host's
copies against them and refuses to deploy functions while they differ.

The asset cleanup that ran after each deploy (/opt/cleanup-miniapp.sh, only
on the host) protected lazy chunks by mtime and so removed live ones when a
build was shipped more than two hours after it was made; it took seven pages
down for about two minutes on 2026-10-09 while this was being tested, and
they were restored from the same tar. The receive script now keeps every
file of the new build and removes other assets only after four hours. Its
tests cover that (red with the keep rule removed) and the refusals; CI runs
them with shellcheck, and apply-repo-settings.sh requires the job.

VPS3's host key is pinned. The commented-out VPS1 deploy is gone; that host
no longer exists. Every action is pinned to a commit SHA.
2026-10-09 06:09:22 +04:00
Satoshi Qazi Muhammed b2b4751f7a ops: version the ownership gate and this repo's branch protection
Two pieces of infrastructure existed only on servers, as single copies with no
history and no review:

  /usr/local/bin/supabase-deploy-functions   the gate both projects deploy through
  /opt/supabase-self-hosted/functions-registry.json   who owns which function name

The gate exists to stop silent drift between what a repo declares and what a
server actually runs. Leaving it unversioned meant the mechanism was drifting the
same way it was built to prevent — and losing that host would have lost it
entirely, along with any record of why it works the way it does.

Both are now in ops/ and synced to the host by CI on every deploy, installed
before the functions they validate so a change to the gate ships together with
them. Verified identical to the server copies by checksum before committing, so
this captures the running state rather than replacing it.

Branch protection gets the same treatment: apply-repo-settings.sh is idempotent
and has a --check mode that reports drift without changing anything. It was
applied by hand through the API today, so nothing here reflected it.

Documented alongside: why the registry lives in this repo even though pwap-web
depends on it (a pwap-web change needs a PR here — deliberate friction, since
the registry is the record of who owns what and should not be edited on a server
where nobody sees the change), and why listing each CI job individually in the
protection rules is a weakness here that pwap-web avoids with an aggregate job.
2026-07-31 10:02:14 -07:00