payment-gateway.app Docs
Deployment

Updates & Automation

How to maintain and automatically update your deployment safely.

Updates & Upgrades

The Deployment repository (payment-gateway-deploy) includes 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. Additional engineering repositories are not part of the customer installation path; customers do not need them to install or update the product.

The important trust boundary is this:

  • Customer upgrades are driven by release metadata from RELEASE_METADATA_URL. When deployment 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.
  • Release metadata is signed by the Licensing Authority. The updater verifies the inline signature and payload hash with the pinned public key in payment-gateway-deploy before selecting a release.
  • Each managed component in release metadata must include a valid sha256: digest. The updater writes digest-pinned refs such as image:version@sha256:<digest> into Docker Compose and Podman configuration, and normalized digest refs are used for no-op comparison.
  • Customer image delivery uses the image source configured for that deployment. The updater does not discover the newest version from image repository tags.

Published release notes (changelog-style pages per product version) are maintained in the docs site under Releases.

Release Security Transparency

Published product releases can include auditable security artifacts tied to the same product version used by release notes and deployment metadata. These artifacts help operators understand what was shipped, what was scanned, and whether release-blocking vulnerability policy checks passed.

Use Release Security Transparency as the canonical artifact contract for SBOMs, vulnerability reports, policy results, checksums, and provenance evidence.

Security Scan Matrix

ArtifactPurpose
SBOMProvides a dependency and component inventory for each scanned source repository or runtime image in the released version.
Vulnerability reportSummarizes known vulnerability findings reviewed for each scanned source repository or runtime image.
Scan manifestTies published security artifacts to the product release version, scan type, image digest, and deployment metadata.
Component image provenance verificationRecords first-party image signature, build identity, digest, and source-revision verification before image promotion.

Security Reporting Policy

The public disclosure and reporting policy should be published on the customer-facing product 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 customer-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 docker-compose/rollback.sh or podman/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 configured image source for the latest version. Instead it requires the metadata endpoint:

  • the RELEASE_METADATA_URL provided in your deployment access snippet

This is deliberate because customer pull credentials should be scoped to image pull only, not image catalog browsing.

When REGISTRY_ACCESS_ID and REGISTRY_ACCESS_SECRET are present, the updater sends them as Basic Auth during preflight. The metadata service then returns the latest release set still entitled for that license and support window. The same credentials do not grant image catalog access.

Remote-First Metadata

Set the metadata host with RELEASE_METADATA_URL. Production should use the metadata endpoint provided in the deployment access snippet. Other environments can override that value explicitly when they need a different metadata host.

/api/releases/metadata requires registry-grant Basic Auth. Unauthenticated requests receive 401 Unauthorized and no release payload.

Authenticated requests return signed, entitlement-filtered metadata for the license access grant. The response includes channel heads plus a bounded releases history filtered to builds published on or before the license support window (Maintenance & Updates expiry). Active support receives the full metadata set; lapsed support receives only entitled releases.

If the metadata endpoint is temporarily unavailable, unsigned, tampered, 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 and signed. It uses version at both the release and component level.

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 stable

# Install a specific entitled version instead of the channel head
./scripts/update.sh --engine docker-compose --channel stable --version 4.0.12
# Or set UPDATE_TARGET_VERSION before running update.sh

Use --version VERSION or the UPDATE_TARGET_VERSION environment variable when you need an exact entitled release rather than the latest version on the configured channel.

Scheduling 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 podman

Component Updates

Use ./scripts/update.sh for production updates, including small service updates. It resolves the signed, entitled release baseline and deploys digest-pinned image refs.

The engine deploy.sh --update-component and Podman --update-components flags are internal automation mechanics for callers that have already resolved exact component versions or image refs. They do not publish or verify signed release metadata by themselves.

Customer and operator app rollouts should use the unified updater so signed release metadata and digest-pinned refs remain the deployment authority.

Common Components: admin-backend, admin-frontend, main-backend, main-frontend, main-worker, reverseproxy, mongo, garnet, mgob, gotenberg, mongo-express

main-worker is deployed as a separate service but uses the same image as main-backend with the worker entrypoint (/app/worker) for PDF generation and background jobs.

Image Access & Auto-Renew

For production, the Payment Gateway requires access to the image source that serves your deployment. You configure this access using deployment credentials issued for a specific license:

  • REGISTRY_HOST
  • REGISTRY_TOKEN_SERVICE_URL
  • REGISTRY_ACCESS_ID
  • REGISTRY_ACCESS_SECRET

When these are securely injected, the deployment and update scripts automatically request short-lived pull tokens from the configured endpoint. The first successful exchange can bind the deployment host's public IP on first use and configures docker / podman pulls non-interactively.

The license access scope must cover every image in the shipped stack, not only the first-party application images. That includes the application services and the managed runtime images shipped with the deployment package.

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 image tags. The release channel decision comes from remote signed metadata at RELEASE_METADATA_URL, and the license access credentials authenticate both metadata fetch and short-lived pull tokens for the repositories allowed by the license manager.

Version Badge and Release Discovery

The admin frontend Version Badge does not call /api/releases/metadata directly. It reads /api/v1/system/versions on the Admin Backend, which combines local module health checks with authenticated release metadata fetched server-side using MPG_RELEASE_METADATA_URL and the matching release metadata access credentials (MPG_RELEASE_METADATA_ACCESS_ID / MPG_RELEASE_METADATA_ACCESS_SECRET, mapped from the same deployment access snippet as the updater).

Configure those admin-backend variables alongside RELEASE_METADATA_URL and the registry access credentials so the badge can compare the running deployment against entitled channel heads and show dependency health. The updater and the badge both rely on the same signed metadata endpoint; neither falls back to public or unauthenticated metadata.

On this page