Updates & Automation
How to maintain and automatically update your deployment safely.
Updates & Upgrades
The Deployment repository (payment-gateway-deploy) includes a powerful set of scripts and mechanisms to keep your Payment Gateway updated, ensuring you receive the latest security patches and features.
This page describes the customer-facing updater behavior from payment-gateway-deploy. Internal automation stacks may choose different image sources; for example, payment-gateway-infra-deploy currently defaults to origin image sources unless an environment overrides them explicitly.
The important trust boundary is this:
- Release orchestration is internal.
- Customer upgrades are driven by release metadata from
RELEASE_METADATA_URL. When registry access credentials are configured, the updater authenticates to that endpoint and receives only the releases entitled for that license. If the endpoint is unavailable or invalid, the updater stops instead of guessing from registry tags or stale local state. - Customer image delivery uses the OCI registry configured for that
deployment. In the first-party hosted setup this is
registry.payment-gateway.app, but the updater does not discover the newest version from registry tags.
Published release notes (changelog-style pages per product version) are maintained in the docs site under Releases.
Release Security Transparency
Each published product release now includes auditable security artifacts:
- A release-time Trivy scan runs after changed component images are published and promoted.
- CycloneDX SBOM files are generated per repository and versioned.
- Trivy vulnerability and misconfiguration reports are generated per repository and versioned.
- These artifacts are committed to the internal release-orchestrator repository, then linked to the same product version used by release notes and deploy metadata.
In addition, component repositories enforce branch-based license scanning with Trivy:
- Trigger: push to
developfor application repositories, push tomainforpayment-gateway-lib-commonandpayment-gateway-lib-crypto. - Command behavior:
trivy fs --scanners license --format json. - Gate policy: the workflow fails on license findings with severities
UNKNOWN,HIGH,CRITICAL.
For additional shared libraries scanned by the release pipeline, the scanner prefers a matching v<version> tag and falls back to main if that tag does not exist yet. This keeps release-version traceability explicit while still ensuring coverage.
This gives operators and customers better traceability between what was released and what was scanned.
Additional security checks in the release ecosystem:
- Backend CI includes Go-native vulnerability/security checks (such as
govulncheckandgosec) in dedicated security workflows. - Aikido Security can run as an additional organization/repository security integration for continuous code and dependency monitoring.
Security Scan Matrix
| Control | Scope | Trigger | Output | Blocking |
|---|---|---|---|---|
| Trivy vuln+misconfig + CycloneDX SBOM | release-managed repos + shared libs | product release continuation after image promotion | security/sbom/v<version>/*.cyclonedx.json, security/reports/v<version>/*.vuln.json, scan-manifest.json in release-orchestrator | Yes |
| Trivy license gate | each component repository | push (develop for app repos, main for libs) | machine-readable JSON output in CI workflow run | Yes (UNKNOWN,HIGH,CRITICAL) |
| Govulncheck | admin/main backend | backend security scan workflow on push | workflow findings | Yes |
| Gosec | admin/main backend | backend security scan workflow on push | workflow findings | Yes |
| Aikido Security | organization/repository security integration | continuous | Aikido findings dashboard | Policy-driven |
Security Reporting Policy
The public disclosure and reporting policy should be published on the operator-facing license portal for your deployment. In the first-party production deployment it is available here:
https://payment-gateway.app/security-policy
The required discovery file should also be published on that same operator-facing portal. In the first-party production deployment it is available at:
https://payment-gateway.app/.well-known/security.txt
This follows the common best-practice pattern of keeping the machine-readable
security.txt contact file and the human-readable reporting policy aligned.
Automated Updates
The stack features a unified updater script that safely orchestrates system upgrades.
Key Features:
- Automatic detection of existing installations.
- Graceful service shutdown and restart to minimize downtime.
- Automatic backup creation before updates.
- Detailed logging of all operations.
- Emergency rollback capability provided by
./rollback.sh. - Image validation and Compatibility Checks gating updates safely.
How the Updater Finds a Version
./scripts/update.sh does not query GitHub Releases or the customer registry
for the latest version. Instead it requires the metadata endpoint:
https://payment-gateway.app/api/releases/metadatain the first-party hosted deployment, or the metadata endpoint exposed by your own licensing authority
This is deliberate because customer pull credentials should be scoped to image pull only, not registry catalog browsing.
When REGISTRY_ACCESS_ID and REGISTRY_ACCESS_SECRET are present, the
updater sends them as Basic Auth during preflight. The licensing authority then
returns the latest release set still entitled for that license and support
window. The same credentials do not grant registry catalog access.
Remote-First Metadata
Set the metadata host with RELEASE_METADATA_URL. Production should use the
licensing authority endpoint for that deployment by default. Other environments
can override that value explicitly when they need a different metadata host.
The endpoint has two useful modes:
- unauthenticated requests return the public channel metadata used by status surfaces such as version badges
- authenticated requests return entitlement-filtered metadata for the specific license access grant used by the updater
If the metadata endpoint is temporarily unavailable or invalid, the updater fails fast so operators do not accidentally roll forward based on stale metadata.
Published release metadata should describe the full managed image baseline for a release, not only first-party application services. In the first-party hosted setup that baseline includes the mirrored runtime images for mongo, garnet, mgob, gotenberg, and mongo-express alongside the Payment Gateway application images.
The metadata served from /api/releases/metadata is intentionally compact. It
uses version at both the release and component level, and it only exposes the
current channel-head releases rather than a full release history.
Running a Manual Update
To manually trigger a full stack update using the unified updater:
# From the root of payment-gateway-deploy
# For Docker Compose
./scripts/update.sh --engine docker-compose --channel stable
# For Podman
./scripts/update.sh --engine podman --channel stableScheduling Automated Upgrades
You can install weekly systemd timers on Linux to handle background updates for you automatically:
# For Docker Compose
./scripts/install-update-timer.sh --engine docker-compose
# For Podman
./scripts/install-update-timer.sh --engine podmanComponent Updates
Sometimes you only need to update a single microservice (e.g. admin-backend or main-worker) without a full metadata-driven upgrade. Targeted updates use the platform deploy.sh:
# Run from payment-gateway-deploy/docker-compose OR payment-gateway-deploy/podman
./deploy.sh --update-component admin-backend --version 3.1.1Common Components:
admin-backend, admin-frontend, main-backend, main-frontend, main-worker, reverseproxy, mongo, garnet, mgob, gotenberg, mongo-express
Container Registries & Auto-Renew
For production, the Payment Gateway requires access to the OCI registry that serves your deployment. In the first-party hosted setup this is registry.payment-gateway.app. You configure this access using license access credentials issued for a specific license in the operator-facing license workspace:
REGISTRY_HOSTREGISTRY_TOKEN_SERVICE_URLREGISTRY_ACCESS_IDREGISTRY_ACCESS_SECRET
When these are securely injected, the deployment and update scripts automatically request short-lived bearer tokens from the configured registry token service. In the first-party hosted setup that token service is registry-auth.payment-gateway.app. The first successful exchange binds the deployment host's public IP on first use and configures docker / podman pulls non-interactively.
The license access scope must cover every mirrored repository in the shipped stack, not only the first-party application images. In the first-party hosted setup that means the registry grant should cover payment-gateway-admin-backend, payment-gateway-admin-frontend, payment-gateway-main-backend, payment-gateway-main-frontend, payment-gateway-reverseproxy, mongo, garnet, mgob, gotenberg, and mongo-express.
The updater also reuses those same credentials when requesting release metadata so it can resolve the highest version still entitled for that license. This is separate from pull authorization: metadata can report the support-window ceiling even when fresh image pulls are no longer entitled.
The first successful token exchange also binds that license access identity to the deployment public IP. If the outbound public IP changes later, rotate the license access secret in the license workspace before the next deploy or update.
Customers normally do not need direct permission to enumerate registry tags. The release channel decision comes from the deploy manifest, and the license access credentials are used only to fetch short-lived pull tokens for the exact repositories allowed by the license manager.
Recommended Public Metadata Pattern
For UI surfaces such as an admin-frontend "update available" indicator, the
recommended pattern is to publish a small public release metadata document or
API from a stable operator-controlled domain. In the first-party hosted setup
that domain is payment-gateway.app.
That public metadata should mirror the channel information already present in
releases/manifest.json:
- current channel-head version per channel
- release date
- compatibility flag
- release notes URL
- exact managed image baseline with
version, image reference, and digest
The admin frontend Version Badge consumes the same public metadata and changes state based on channel-aware version comparison plus dependency health.
This is preferable to making the internal release orchestrator repository public just to expose version discovery. The updater, however, should use authenticated metadata whenever registry access credentials are available so release resolution respects the license support window.