Files
PacketStation/scripts
spencermandClaude Opus 5.5 a82e056b6a
ci / frontend (pull_request) Successful in 1m11s
ci / server (pull_request) Successful in 12m2s
ci / image (pull_request) Skipped
ci / e2e (pull_request) Successful in 6m1s
Phase 9: Admin completion, reconcile, notifications, integrity, backups
Admin: Departments (name and stations; add shows the three groups IT must
create), Profiles (welder stamp, station limits, active) with a CSV import
that previews and applies only when clean, Checklists (weld and plain),
Security (session, lockout and rate-limit settings with bounds, alerts for
the last 24 hours, the integrity result), Access log with filters and a
guarded CSV, Who is in, Stamp check, Notifications, and the employeeID
flags. Every Admin change is audited.

Worker: ad-reconcile (nightly and on "refresh from AD now"), session-refresh
(15 minutes), integrity (seals, asset hashes, missing and orphan files, the
audit chain), backup-check, notify-send and notify-digest. Notifications
route per event type to AD groups, users, mailboxes or the department
Supervisor group, immediately or in a daily digest, over STARTTLS verified
against the PESCO CA, with dry run on the test stack.

Backups: scripts/backup/ps-backup.sh and ps-restore.sh with a systemd timer
at 02:00 America/Denver. Restore rehearsed on the test stack 2026-10-21.
CI: pip-audit and npm audit. pypdf 6.21.1 and certifi 2026.10.19.

Migration 0010. Closes the app part of I6, M3, O1, O2 and S3.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 18:27:09 -06:00
..

scripts

backup/

The nightly per-stack pg_dump backup with its systemd timer, and the restore script. See backup/README.md for what they write and Spencer's install steps. The restore rehearsal is recorded in docs/DEPLOY.md.

Export-PescoCaBundle.ps1

Run on a domain-joined PC. Exports every unexpired PESCO CA certificate from the Windows stores to one PEM bundle and copies it to docker-1 with scp (default target ~/packetstation/test/ca/pesco-ca.pem). Use -Remote for another path and -NoCopy to only write the file. It warns on SHA-1 signed certificates; see docs/DEPLOY.md.

Request-VsqlServerCertificate.ps1

Run elevated on the SQL Server host behind vsql, in Windows PowerShell 5.1 or PowerShell 7. Requests a TLS certificate from PESCO-PSYLOCKE-CA with certreq the way SQL Server requires it (legacy Microsoft RSA SChannel Cryptographic Provider, KeySpec AT_KEYEXCHANGE, RSA 2048, SHA-256, Server Authentication, key usage 0xA0, SANs vsql.pesco.com, vsql and the host FQDN and short name). It installs it and validates it before anything is bound. The validation checks the key provider and KeySpec from the certificate's own key property, the key size, the signature, the dates, the EKU, and the SAN DNS names as whole names. It grants only the selected instances' service accounts read on the private key, then binds the thumbprint and reads it back.

  • -WhatIf previews every step and changes nothing. -Confirm asks before each change. Declining enrollment or a key grant cancels the run with nothing bound (exit code 2).
  • -CerFile continues a request that was pending. -Thumbprint binds a certificate already installed. -Instances limits the run (DEV, MSSQLSERVER). -RestartInstances restarts them and starts SQL Server Agent again if it ran. The running dependents are written to dependents-<service>.json before the stop and the file is removed once they run again, so after a failed restart the next restart of that service starts them too.
  • Each deployment writes a new deploy-<time>.json in C:\ProgramData\PacketStation\vsql-cert with the values it replaced. Instances already bound to the thumbprint are left alone and get no snapshot, so a rerun never hides the useful one. A pending request writes request-<time>.json with its request id. A registry value that cannot be read stops the run; only a value confirmed absent is saved as absent.
  • -Rollback restores the newest snapshot not yet rolled back, each instance on its own, verified by reading back, and records it in rollback-<time>.json with which restarts succeeded. A snapshot stays open while an instance is unrestored or its restart failed, so -Rollback -RestartInstances again retries exactly those. -Snapshot picks another. Failures are listed and the run exits with an error.
  • Instances are read from the value names of Instance Names\SQL, so a name starting with PS (for example PSREPORTING) is found.

Tests: scripts/tests/Request-VsqlServerCertificate.Tests.ps1 (Pester 5) fakes the host (instances, services, registry, machine store, certreq, icacls) and uses real throwaway certificates in Cert:\CurrentUser\My. Run it on both PowerShell versions:

Install-Module Pester -RequiredVersion 5.7.1 -Scope CurrentUser -SkipPublisherCheck
Invoke-Pester -Path scripts	ests -Output Detailed

The run procedure is in docs/DEPLOY.md, under the vsql known issue. Gitea issue 5 tracks the switch to VISUAL_ENCRYPT=yes.