feat(deploy): add Contabo release workflow and portal payload gate
This commit is contained in:
1 parent
5fa54719b2
commit
ba93a54942
18 files changed
+697
-28
No files matched your search
@@ -1,9 +1,25 @@
|
||||
# Employee portal compatibility and private migration
|
||||
|
||||
Recorded 2026-10-30. Browser-side shared-code decryption is approved only for
|
||||
local compatibility development. It is not authentication, individual revocation,
|
||||
a secure session or a HIPAA compliance determination. Resources need separate
|
||||
server authorization before cutover.
|
||||
Recorded 2026-11-04. The clinical director accepted the collected, non-PHI
|
||||
staff and management portal content and the interim shared-code presentation.
|
||||
Browser-side decryption remains access friction rather than individual
|
||||
authentication, revocation, a secure session, or a HIPAA determination.
|
||||
|
||||
## Approved production ciphertext
|
||||
|
||||
An indexing-enabled production build may include one owner-approved encrypted
|
||||
two-stream payload when both of these non-public build inputs are set:
|
||||
|
||||
```sh
|
||||
AIA_PORTAL_PRODUCTION_APPROVED=true
|
||||
AIA_PORTAL_PRODUCTION_CIPHERTEXT_FILE=/absolute/private/employee-portal/approved-production-ciphertext.json
|
||||
```
|
||||
|
||||
The build rejects missing, malformed, symlinked, oversized, wrong-mode, or
|
||||
simultaneous local-preview/production inputs. It never decrypts the payload at
|
||||
build time. `/employee-portal` remains noindex, sitemap-excluded and
|
||||
hreflang-excluded. See [the deployment runbook](../nixos/deploy.md) for the
|
||||
approved release and protected-resource installation commands.
|
||||
|
||||
## Source and private collection
|
||||
|
||||
|
||||
@@ -63,10 +63,10 @@ Test direct requests, alternate encodings, role crossover and rollback.
|
||||
- Portal HTML: shared-code browser decryption, offline-guessable access friction.
|
||||
- Documents: require server authorization even if URLs are encrypted in the UI.
|
||||
|
||||
The compatibility preview cannot grant production portal access. Before cutover,
|
||||
classify every document, implement and verify its delivery destination, rewrite
|
||||
and re-encrypt links, test two-view separation, rotate shared codes privately,
|
||||
check the public artifact for private files, and obtain owner/security approval.
|
||||
Back up encrypted configuration and documents separately from keys; rehearse
|
||||
restore and rollback. Revoking a static release cannot retract ciphertext or
|
||||
files already downloaded by visitors. Site cutover is still unauthorized.
|
||||
The approved production portal build uses a non-public encrypted two-stream
|
||||
payload and retains the same browser-side decryption boundary. Approved non-PHI
|
||||
documents install separately into the VPS-owned staff/management directories;
|
||||
they are never copied into `dist`. Verify both protected namespaces, two-view
|
||||
separation, artifact exclusions, code rotation, restore and rollback before
|
||||
cutover. Revoking a static release cannot retract ciphertext or files already
|
||||
downloaded by visitors. Site cutover remains separately authorized.
|
||||
@@ -0,0 +1,87 @@
|
||||
# Contabo release operations
|
||||
|
||||
This site publishes static content through the merged Contabo release manager.
|
||||
It does not run `nixos-rebuild`, reload nginx, change DNS, or write directly to
|
||||
`/srv/www/azinstitute4autism.com/www/dist`.
|
||||
|
||||
## Required local tools and private inputs
|
||||
|
||||
- Node.js 22+, Git, tar, SSH and rsync.
|
||||
- A normal SSH identity accepted by the existing root receiver:
|
||||
`AIA_DEPLOY_SSH_IDENTITY=/absolute/path/to/identity`.
|
||||
- `AIA_DEPLOY_HOST=administrator@host` (or the approved equivalent).
|
||||
- For a real public release, an owner-controlled, regular encrypted payload:
|
||||
`AIA_PORTAL_PRODUCTION_CIPHERTEXT_FILE=/absolute/private/employee-portal/approved-production-ciphertext.json`.
|
||||
|
||||
The payload remains outside Git and the source snapshot. It is browser ciphertext
|
||||
only; neither access code nor decrypted portal HTML enters an Astro environment
|
||||
variable, public resource directory, build log, or deployment manifest.
|
||||
|
||||
## Commands
|
||||
|
||||
From `www/`:
|
||||
|
||||
```sh
|
||||
npm run deploy -- --dry-run
|
||||
```
|
||||
|
||||
Dry-run performs the local production build, tests, artifact verification,
|
||||
manifest creation and source-snapshot preparation. With no private production
|
||||
payload it uses a generated synthetic two-stream fixture and explicitly reports
|
||||
that the result is not production-ready. It never opens SSH or rsync.
|
||||
|
||||
```sh
|
||||
AIA_DEPLOY_HOST='root@approved-host' \
|
||||
AIA_DEPLOY_SSH_IDENTITY="$HOME/.ssh/AIAMarketing" \
|
||||
AIA_PORTAL_PRODUCTION_CIPHERTEXT_FILE="$PWD/private/employee-portal/approved-production-ciphertext.json" \
|
||||
npm run deploy -- --confirm
|
||||
```
|
||||
|
||||
The confirmed command builds with `PUBLIC_ALLOW_INDEXING=true`, Form A live and
|
||||
counters off, then uploads only fresh commit-specific `staging/source-<sha>` and
|
||||
`staging/dist-<sha>` directories. It runs, in order:
|
||||
|
||||
```text
|
||||
aia-website-release verify
|
||||
aia-website-release sync-source
|
||||
aia-website-release promote
|
||||
```
|
||||
|
||||
The VPS verifies the manifest, promotes an immutable release by atomic symlink,
|
||||
and retains the prior release. A successful rsync transfer alone is not success.
|
||||
|
||||
Rollback requires the reviewed manifest retained at the server’s fixed path:
|
||||
|
||||
```sh
|
||||
AIA_DEPLOY_HOST='root@approved-host' \
|
||||
AIA_DEPLOY_SSH_IDENTITY="$HOME/.ssh/AIAMarketing" \
|
||||
npm run deploy:rollback -- FULL_APPROVED_SHA --confirm
|
||||
```
|
||||
|
||||
## Employee resources: separate one-time operation
|
||||
|
||||
Approved non-PHI employee files are never part of an ordinary release. After
|
||||
the website release that contains `portal-resource-install.mjs` is promoted and
|
||||
the VPS SOPS-backed Basic Auth material is independently ready:
|
||||
|
||||
```sh
|
||||
npm run deploy:portal-resources -- --dry-run
|
||||
|
||||
AIA_DEPLOY_HOST='root@approved-host' \
|
||||
AIA_DEPLOY_SSH_IDENTITY="$HOME/.ssh/AIAMarketing" \
|
||||
npm run deploy:portal-resources -- --confirm
|
||||
```
|
||||
|
||||
The installer reads only the private collection manifest, accepts approved
|
||||
`STAFF-INTERNAL` and `MANAGEMENT-INTERNAL` mappings to `/staff-resources/` and
|
||||
`/management-resources/`, verifies every local hash, rejects links/traversal and
|
||||
uploads a root-controlled temporary tree. It never uses `--delete` for resource
|
||||
directories and refuses to replace a different existing file. The VPS installs
|
||||
regular files as `root:nginx` mode `0640` and reports metadata only.
|
||||
|
||||
Before public DNS cutover, test the site with approved host-header/SNI methods,
|
||||
including the portal’s noindex response, valid ciphertext unlock, both protected
|
||||
resource namespaces, denial cases, redirects, Form A, IPv4 and IPv6. Portal
|
||||
shared-code rotation is coordinated: update VPS SOPS inputs and privately
|
||||
re-encrypt the browser payload together. This interim portal is non-PHI and is
|
||||
not an employee identity system.
|
||||
Reference in new issue
Block a user