Deployment
Evaluation: docker-compose
One command brings up Postgres 16, the API, and the SPA with auth disabled:
docker compose up --build
# SPA: http://localhost:8082
# API: http://localhost:5080 (Swagger at /swagger)
Compose is for evaluation and development. It uses obvious dev credentials and no operator auth - don't expose it.
Production: Kubernetes (Kustomize + Flux + SOPS)
deploy/base holds the core manifests (Deployment, Service, Ingress, PVCs for the
Data Protection key ring and package store); deploy/overlays/production applies
environment specifics. Render to verify:
kubectl kustomize deploy/overlays/production
Configuration split
| Kind | Where | Examples |
|---|---|---|
| Non-secret config | configMapGenerator in the overlay |
Auth authority/audience, CORS origins, EXO cert path, notification format |
| Secrets | secrets.sops.yaml - encrypt with SOPS before committing |
Postgres connection string, Entra client secret, optional seed refresh token, notification webhook URL |
secrets.sops.yaml as a CHANGEME template.
Never commit real values unencrypted; with Flux + SOPS the encrypted file is decrypted
in-cluster at reconcile time.
What must persist
- Postgres - tenants, contracts, templates, deployments, workflow run history, and the encrypted SAM token live here.
- Data Protection key ring (
DataProtection:KeyRingPath) - loses this and the encrypted SAM token can't be decrypted; you'll need to re-bootstrap. - Package store - uploaded
.intunewintemplates. - Git sync working copy (
GitSync:LocalPath, default/git-sync) - only if git sync is enabled. Not strictly required to persist (it re-clones if missing) but avoids a full re-clone on every pod restart.
Operator auth
Two options, not just one -- full detail on both: Authentication.
- OIDC - point the
Authsection at your provider (authority + audience; tested with Authentik) and give the SPA matchingVITE_OIDC_AUTHORITY,VITE_OIDC_CLIENT_ID,VITE_API_BASE. The operator name claim (preferred_usernameby default) is what workflow run history records. Auth:Mode=Local- self-registered accounts, no IdP to stand up. SetAuth:Local:SigningKey(a secret) and, for passkeys,Auth:Local:Passkey:RelyingPartyId/Originsmatching the public hostname the SPA is served from.
Config snapshot git sync (optional)
Set GitSync:RepoUrl (and GitSync:Token, a secret) to mirror every
config snapshot capture to a real git repo. Unset by default -- see
Config Snapshots for the full key reference.
Exchange Online certificate
Mailbox workflows shell out to the EXO PowerShell V3 module with app-only certificate auth.
Mount the PFX and set the Exchange section (AppId,
CertificatePath, CertificatePassword). The API container image
already includes PowerShell and the ExchangeOnlineManagement module.
Upgrades
EF Core migrations apply automatically at startup, so rolling a new image forward is the whole upgrade. Roll back by deploying the previous image (migrations are additive).