Kubernetes Network Policy
Overview
Network traffic between OpenCRVS pods is restricted using Kubernetes NetworkPolicy resources. This document gives an overview of the Kubernetes NetworkPolicy configuration shipped with the OpenCRVS services and dependencies Helm charts.
The following configuration is applied by default:
NetworkPolicy is enabled by default (
network_policy.enabled).Ingress and egress traffic are restricted by default (
network_policy.<ingress|egress>_mode).Each Helm chart (
dependencies,opencrvs-services) has its own configuration for ingress and egress policy.Every pod can always reach other pods in its own namespace (
allow_same_namespace).NetworkPolicy resources are recreated on every
helm upgrade, so the cluster always matchesvalues.yaml.
Ingress / egress modes
Each Helm chart exposes network_policy.ingress_mode and network_policy.egress_mode, configurable globally and per service:
deny
Nothing allowed beyond same-namespace / allowed_namespaces / explicit rules.
private
Additionally allow RFC1918 private ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16); the public internet stays blocked.
full
No restriction.
Default posture per chart:
Chart
ingress_mode
egress_mode
dependencies
private
deny
opencrvs-services
deny
private
opencrvs-services ships with egress_mode: private rather than deny so the application can reach the dependencies chart and other in-VPC services without every deployment having to configure allowed_namespaces up front.
Public entry points
The following services are allowed to accept connections from any private subnet:
clientgatewaylogincountryconfigdashboards
Every other service accepts ingress only from its own namespace.
The MOSIP integration chart (opencrvs-mosip) is usually deployed into the same namespace as opencrvs-services. It ships a mosip-allow-all NetworkPolicy that exempts mosip-api, mosip-mock and esignet-mock from the default-deny policy.
Cross-namespace access
The dependencies chart (Postgres, Elasticsearch, Redis, MinIO) and opencrvs-services chart are typically deployed to separate namespaces. network_policy.allowed_namespaces grants one half of that access per chart:
{env} in this diagram refers to the environment name (e.g. production, qa)
Configuration example for allowed_namespaces:
Hardening
Recommended for production:
Set
egress_mode: denyon theopencrvs-serviceschart (ships asprivate).Set
ingress_mode: denyon thedependencieschart (ships asprivate).Set
network_policy.allowed_namespaceson both charts, pointing at each other's namespace (see above).Countryconfig service has
egress_mode: fullfor SMTP/SMS provider integrations) and replace it with acustom_rulesentry scoped to known IPsDeployment jobs (
deployment_jobs) haveegress_mode: full. Apply samecustom_rulesas for countryconfig.Build custom Postgres image with pgbackrest and other utilities, see Postgres Preinstalling backup/restore utility packages and set
postgres.network_policy.rules: []
Backup and restore server
When backup or restore is enabled, the dependencies chart allows Postgres and MinIO to connect to the backup server over SSH (TCP port 22) only. The rule is built from backup.host / restore.host (set from the BACKUP_HOST / RESTORE_HOST GitHub environment variables) as a /32 IP block, because Kubernetes NetworkPolicy cannot match hostnames. BACKUP_HOST and RESTORE_HOST must be IP addresses.
Cloud-native deployments
By default, egress to internal (RFC1918 private) IP addresses is allowed under
egress_mode: private— this covers pod IPs, Service ClusterIPs, and node IPs on any standard cluster network, including managed Kubernetes offerings.If Postgres (or another datastore) runs as a managed cloud service reachable over a public IP (e.g. AWS RDS, Cloud SQL, Azure Database) rather than an in-cluster address, the private-range rule does not cover it. Add an explicit
custom_rulesentry scoped to that service's IP:
Custom rules
<service>.network_policy.rules/custom_rules entries use the same syntax as a Kubernetes NetworkPolicy spec (policyTypes, ingress, egress) — only podSelector is generated automatically from the service's app_label. See the NetworkPolicy API reference for the full syntax.
Configuration options
Reference for the opencrvs-services chart:
network_policy.enabled
true
Render NetworkPolicy resources.
network_policy.ingress_mode
deny
deny / private / full, see above.
network_policy.egress_mode
private
deny / private / full, see above.
network_policy.allow_same_namespace
true
Allow pods in the same namespace to reach each other.
network_policy.allowed_namespaces
[]
Namespaces OpenCRVS pods are allowed to reach (egress), e.g. the dependencies namespace — see Cross-namespace access.
network_policy.annotations / labels
{}
Extra annotations/labels on every generated NetworkPolicy. Can be overridden per service.
<service>.network_policy.ingress_mode / egress_mode
global
Per-service override, same modes. Unset values inherit the global setting. Chart defaults: ingress_mode: private for client, gateway, login, countryconfig and dashboards; egress_mode: full for countryconfig; ingress_mode: deny / egress_mode: full for deployment_jobs.
<service>.network_policy.rules / custom_rules
[]
Explicit NetworkPolicy rules for one service.
For the complete reference, see:
Last updated