-
Notifications
You must be signed in to change notification settings - Fork 0
Backend Operations
PumpSync.backend runs the same ASP.NET Core container image for hosted service and self-host/demo distribution, with different configuration.
Hosted PumpSync runs on Azure Container Apps with Azure Table Storage.
PumpSync__BackendMode=HostedPumpSync__DataSourceMode=TandemSourcePumpSync__StorageProvider=AzureTableStorage- Azure Container Apps scale minimum:
0 - Public app base URL includes
/api - App Store Server Notification URL is
/api/v1/app-store/notifications
infra/bicep/main.subscription.bicep creates or updates:
- Resource group.
- Azure Container Apps managed environment.
- Backend container app (with HTTP liveness/readiness probes against
/health). - User-assigned managed identity.
- Key Vault.
- Application Insights and Log Analytics.
- Storage account and Table Storage tables.
- Optional managed identity role assignments.
An App Configuration store from an earlier iteration is no longer part of the template; nothing reads or writes it, so any live instance can be deleted.
Build the templates:
az bicep build --file infra/bicep/main.bicep
az bicep build --file infra/bicep/main.subscription.bicepDeploy with the GitHub Deploy Backend workflow. The workflow restores, builds, tests, builds and pushes the Docker image to GitHub Container Registry, deploys Bicep with that image, runs smoke tests, and prints the hosted API base URL and App Store Server Notification URL.
Renewable authentication uses protocol 3 exclusively beginning with Build 7. PumpSync-hosted mode validates request-bound App Attest enrollment, stores the locally validated receipt encrypted, and fails closed when proof or local receipt validation does not pass. The backend may submit stored receipts to Apple's optional risk exchange; that exchange is currently disabled and remains observe-only when enabled, so an exchange outage or non-blocking Apple response does not reject an otherwise valid enrollment. Self-hosted mode enrolls with a Secure Enclave P-256 key and has no Apple dependency; both modes rotate device-bound refresh credentials. Exact configuration, encryption-key bootstrap, receipt-retention cleanup, Application Insights queries, and deployment checks live in the backend repository's docs/authentication-operations.md.
Protocol 3 hosted deployment order is strict: deploy and validate the compatible nonproduction backend first, then distribute Build 7. Confirm /api/v1/capabilities reports session protocol 3, complete new-key enrollment and renewal on a physical device, verify receipt assessment and cleanup telemetry without logging receipt or key material, and only then repeat the sequence for production. Do not promote an app build that can silently downgrade hosted access when protocol 3 is unavailable.
| Image use | Registry | Visibility | Notes |
|---|---|---|---|
| Hosted production/nonprod API | GitHub Container Registry | Private |
ghcr.io/eslutz/pumpsync-backend. Nonprod publishes SHA + nonprod-latest; a production workflow run from a matching stable Git tag also publishes the numeric SemVer tag, prod-latest, and latest. |
| Self-host/demo distribution image | GitHub Container Registry | Public |
ghcr.io/eslutz/pumpsync-backend-self-hosted. Every main build publishes its SHA; a matching stable Git tag also publishes the numeric SemVer tag and moves latest. Used by Docker self-hosters and the demo Container App. |
The iOS app does not choose a registry. It only stores a backend base URL.
Public docs intentionally avoid listing live hosted backend endpoint values. Use the Deploy Backend workflow output, Azure Container Apps configuration, or trusted operator notes to retrieve the current hosted base URL.
Container Apps run the commit-SHA image tag printed by the deploy workflow, not a floating or numeric alias. See Versioning and Releases for the component version contract.
Smoke test:
curl --fail <hosted-api-base-url>/v1/capabilities
curl --silent --output /tmp/status.json --write-out '%{http_code}' <hosted-api-base-url>/v1/statusThe unauthenticated status call should return 401.
Hosted demo API base URL:
https://demo.pumpsync.ericslutz.dev/api
Current demo Container App recorded in backend docs:
ca-pumpsync-demo-api
The demo image recorded in backend deployment output must be an immutable released commit-SHA reference:
ghcr.io/eslutz/pumpsync-backend-self-hosted:<released-commit-sha>
The demo Container App pulls the public self-host/demo GHCR image without registry credentials and is redeployed explicitly for each stable backend release.
Hosted Container Apps pulls from private GitHub Container Registry with a classic GitHub token that has only read:packages.
Do not grant:
repowrite:packagesdelete:packages
The runtime token is stored in Key Vault as GitHubContainerRegistry--PullToken and exposed to Container Apps through a Key Vault-backed secret named ghcr-pull-token.
tools/PumpSync.DataDeletionRequest is the operator CLI for hosted and self-host data deletion requests. For the build/dry-run/execute commands, see the backend repo's docs/data-deletion.md.
Hosted deletion includes the encrypted App Attest receipt and categorical risk outcome associated with the deleted key. Independently of a request, retention cleanup must remove both no later than 30 days after the key becomes inactive. Self-host storage has neither record because self-hosted authentication never uses App Attest.
PumpSync documentation: iOS repository · Backend repository · Issues