Skip to main content
pgAgroal docs · Harden the deployment

How-to guide

Harden the deployment

Image verification, runtime hardening, and authentication.

Image verification

Every published image is signed with Cosign using keyless GitHub OIDC. Verify before deploying to confirm the image was built by the Elevarq GitHub Actions workflow and has not been tampered with.

cosign verify elevarq/pgagroal:1.4.3 \
  --certificate-identity-regexp "https://github.com/Elevarq/pgAgroal/.*" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com"

A successful verification confirms:

  • The image was built by GitHub Actions from the Elevarq/pgAgroal repository
  • The signature is tied to a specific commit and workflow run
  • The image has not been modified since signing

Supply chain attestations

Each image includes two attestations attached at build time:

AttestationWhat it provides
SBOMSoftware bill of materials — lists every package in the image
SLSA ProvenanceBuild metadata — source repo, commit, workflow, builder identity

Inspect attestations:

docker buildx imagetools inspect elevarq/pgagroal:1.4.3
The output shows image manifests for each platform (amd64, arm64) plus attestation manifests containing the SBOM and provenance data.

Runtime hardening

The container is hardened by default. These protections are built into the image and the Helm chart — no configuration needed.

  • Non-root execution — runs as UID 1000, never root
  • No capabilities — all Linux capabilities dropped
  • No privilege escalationallowPrivilegeEscalation: false
  • Read-only root filesystem — only /tmp and /etc/pgagroal are writable (via emptyDir in K8s)
  • Seccomp profile — RuntimeDefault restricts system calls
  • Multi-stage build — compilers and build tools are not present in the runtime image

Authentication

Registered users (default)

The container ships with allow_unknown_users = false. Unknown users are rejected at the pooler; register users withPG_USERNAME and PG_PASSWORD, or provide the equivalent existing Secret through Helm.

To restore transparent passthrough, setPGAGROAL_ALLOW_UNKNOWN_USERS=true (Helm:pgagroal.allowUnknownUsers=true). PostgreSQL then becomes the sole user-authentication gate.

Supplying credentials

Set PG_USERNAME and PG_PASSWORD to register a user at startup. The entrypoint writes a hashed credential file that pgagroal uses for initial authentication before forwarding to the backend.

The v1.4.3 Helm chart is credentials-by-reference only: it contains no credential values and creates no Secret. Create a Secret withPG_USERNAME and PG_PASSWORD, then setcredentials.existingSecret.

Source-address allowlist

At startup the container generates pgagroal_hba.conf fromPGAGROAL_HBA_SOURCE (Helm:pgagroal.hbaSource). The default admits RFC1918 private ranges and requires scram-sha-256. Set your actual client CIDR when it falls outside RFC1918; use all only to restore the legacy any-source behavior.

Network considerations

pgagroal speaks the PostgreSQL wire protocol. Anything that can connect to PostgreSQL can connect to pgagroal. This also means pgagroal inherits the same exposure risks.

  • Do not expose to the public internet. pgagroal should only be reachable from application networks. Use Kubernetes NetworkPolicies, security groups, or firewall rules.
  • Use ClusterIP services in Kubernetes. The Helm chart defaults to ClusterIP. Do not change this to LoadBalancer or NodePort unless you have a specific reason and additional access controls.
  • Restrict backend connectivity. The pooler needs to reach PostgreSQL on port 5432. It does not need outbound internet access.
  • TLS to the backend. If your PostgreSQL server requires TLS, configure it in pgagroal. The container supports TLS via pgagroal's built-in TLS settings.

The Helm NetworkPolicy is enabled by default. It allows same-namespace clients and denies cross-namespace ingress unless you addnetworkPolicy.ingressNamespaceSelectors or pod selectors. Egress remains open by default; enablenetworkPolicy.restrictEgress=true only with the correct backend and kube-DNS CIDRs. Disable the policy entirely withnetworkPolicy.enabled=false when required by your CNI.

Compliance alignment

The build and release process is aligned with SOC 2 and ISO 27001 expectations: CI-only publishing, signed images, SBOM and provenance attestations, non-root execution, and auditable build-to-deployment traceability.

Elevarq does not claim SOC 2 or ISO 27001 certification. These practices support compliance readiness and auditability.