The host
The Shipvigil host is a small Cloudflare Worker that serves a static site.
It serves the production build at / and each merge request's review build at /_review/<branch-slug>/.
CI deploys to it with the job's GitLab ID token, so GitLab stores no deploy key.
The source is in host/. Shipvigil's own site runs on it at https://shipvigil.nguyenhieuec.workers.dev.
Why keyless
A deploy key in a CI variable is a secret that leaks with the variable. Instead, GitLab signs an ID token for each job, with claims about the project, the branch and the environment. The host checks the token against GitLab's public keys and allows a deploy only when:
- the token is signed by GitLab (
RS256, key fromhttps://gitlab.com/oauth/discovery/keys) and hasn't expired - the audience is this host's URL
project_pathis the one project this host serves- the token's
environmentclaim is the environment the job deploys to - for production, the branch or tag is protected (
ref_protectedistrue)
A token from a fork, from another project, or from an unprotected branch can't change production.
Endpoints
| Method and path | What it does |
|---|---|
POST /_shipvigil/deploy?env=<env> |
Stores a new version of the environment and makes it current. Keeps the last 3 versions. |
POST /_shipvigil/rollback?env=<env> |
Makes the previous version current. |
DELETE /_shipvigil/deploy?env=review/<slug> |
Removes a review app. Production can't be removed. |
GET /_shipvigil/status |
Lists the environments and their current versions. |
<env> is production or review/<slug>.
The CLI commands publish, rollback and stop call these endpoints.
What it serves
- Every response carries HSTS, a strict content security policy,
nosniff, a referrer policy and a permissions policy. - Review apps carry
x-robots-tag: noindex, so search engines skip them. - HTML is served
no-cache. Other files are cached for 5 minutes.
Run your own
You need a free Cloudflare account.
- In
host/wrangler.jsonc, setAUDIENCEto your Worker URL andPROJECT_PATHto your GitLab project path. - Run
npx wrangler deployinhost/. - Pass your Worker URL as the
hostinput of the CI template.