Files
curriculum-project-hub/.scratch/saas-production-readiness/issues/10-provision-nonroot-service.md
T

2.0 KiB

Provision a runnable non-root Hub service

Type: task Status: resolved

Question

Make clean-host installation create or validate the dedicated service identity, home/cache/state/workspace paths and ownership, generate a complete production configuration, honor the configured bind host, and fail preflight before unit installation when any required value or prerequisite is invalid. The persistent workspace root must be outside all release trees, and preflight must reject any path that overlaps rsync, release switching, rollback, or release pruning.

Answer

The installer now creates or strictly validates a dedicated non-root, non-login service identity with no supplementary groups; provisions its home/state/cache/workspace directories at mode 0750; and refuses persistent paths that overlap the deployment tree after both lexical and physical path resolution. A missing production environment file is seeded completely and exits with status 78; invalid configuration or prerequisites fail before the unit is written or enabled.

Preflight validates the configured bind host/port, authenticated PostgreSQL access, Node/cph/Prisma, configured and canonical path traversal, and a real bubblewrap namespace. The post-provision phase runs the built Hub dependency graph, a database query, cph and bubblewrap as the service user under no_new_privs, matching the systemd security context. HTTP binding is awaited before the Feishu listener starts, so bind failure rejects startup instead of leaving a listener-only process alive.

Verification evidence:

  • npm run check, npm run build, and npm run prisma:validate
  • 166 unit tests and 86 integration tests passed; one external-model test skipped
  • bash -n deploy/install_service.sh and shellcheck deploy/install_service.sh
  • prisma migrate deploy: 9 migrations found, none pending
  • production-mode HTTP smoke test on 127.0.0.1:8878 returned /api/healthz
  • final Standards and Spec reviews found no remaining Issue 10 gap