Network Policy
Control network access to your AxiomDB Postgres instances with CIDR allowlists, port-level rules, and progressive security modes.
Network Policy
Security is all about having multiple layers of defense. That's why every AxiomDB Postgres instance is protected by a managed firewall (UFW), a connection pooler (PgBouncer), and PostgreSQL's built-in pg_hba.conf control list. Whenever you define a network rule in the dashboard or via the API, we update all three of these layers atomically for you.
Security Modes
To keep your data safe, every new project starts in restricted mode by default. You can open up access as your system design requires, but keep in mind that moving to a more public mode will require explicit confirmation and will leave a clear audit trail.
Restricted (default)
We block all incoming traffic unless it matches a CIDR rule you've explicitly added. No public ports are open to the wild, making this the safest bet for production.
Public Runtime
We open up port 6432 (PgBouncer) to the internet, but keep port 5432 (direct connection to Postgres) restricted to only your allowlisted IPs.
Public All
We open both port 6432 and port 5432 to the entire internet. Because this is a major change, you'll need the Owner role, typed confirmation, and an audit trail event to turn it on.
Comparing Security Modes
| Mode | Port 6432 (runtime) | Port 5432 (direct) | Requires allowlist | Confirmation |
|---|---|---|---|---|
restricted | Blocked | Blocked | Yes | No |
public_runtime | Open | Blocked | Direct only | No |
public_all | Open | Open | No | Owner + typed confirmation |
Public All needs double confirmation
Enabling public_all requires the project owner to type the exact name of the project to confirm. We log this event immediately as network.policy.changed, noting who did it, the exact timestamp, and the previous security mode.
Managing CIDR Rules
A CIDR rule tells AxiomDB exactly which IP ranges are allowed to connect to your database. Every rule you create has metadata settings that let you control its scope, which ports it opens, and how long it stays active.
Rule schema
{
"id": "rule_2kF9x3mZ",
"label": "Office VPN",
"cidr": "203.0.113.0/24",
"ports": "both",
"scope": "project",
"expires_at": "2026-06-01T00:00:00Z",
"created_at": "2025-01-15T10:30:00Z",
"created_by": "usr_8xK2mP"
}Field reference
| Field | Type | Description |
|---|---|---|
label | string | A friendly name for the rule (shown in the dashboard and logs). |
cidr | string | The IP range in standard CIDR notation. For a single IP, just append /32. |
ports | runtime | direct | both | Tells us which ports to open. Select runtime (6432), direct (5432), or both. |
scope | project | branch | The scope of the rule. project covers every branch, while branch only applies to one specific branch. |
expires_at | ISO 8601 | Optional expiration date. When this time passes, we'll clean up the rule automatically. |
Creating a rule using the CLI
axiom network rule create \
--project my-project \
--label "CI Runner" \
--cidr "198.51.100.0/24" \
--ports both \
--scope project \
--expires "72h"Creating a rule using the API
curl -X POST "https://api.axiom.cloud/v1/projects/prj_abc123/network/rules" \
-H "Authorization: Bearer ptk_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"label": "Staging server",
"cidr": "192.0.2.0/24",
"ports": "runtime",
"scope": "branch",
"branch_id": "br_def456",
"expires_at": "2026-03-01T00:00:00Z"
}'Listing active rules
axiom network rule list --project my-projectID LABEL CIDR PORTS SCOPE EXPIRES
rule_2kF9x3mZ Office VPN 203.0.113.0/24 both project 2026-06-01
rule_7pQ4nR8w CI Runner 198.51.100.0/24 both project 2025-01-22
rule_aB3xK9mL Staging server 192.0.2.0/24 runtime branch 2026-03-01What Happens When You Save a Rule?
Whenever you add, modify, or delete a network rule, AxiomDB automatically coordinates updates across multiple systems:
┌─────────────────────────────────────────────────────────┐
│ AxiomDB Control Plane │
│ │
│ 1. Validate CIDR syntax │
│ 2. Check role permission (admin+ for project scope) │
│ 3. Write rule to metadata store │
│ 4. Emit audit event │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ UFW Rules │ │ pg_hba.conf │ │ PgBouncer.ini │ │
│ │ (iptables) │ │ (managed │ │ (managed │ │
│ │ │ │ block) │ │ block) │ │
│ └──────┬──────┘ └──────┬──────┘ └───────┬─────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ PostgreSQL Instance │ │
│ │ • UFW: port-level allow/deny │ │
│ │ • pg_hba.conf: hostssl rules with client cert │ │
│ │ • PgBouncer: connection-level filtering │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘The pg_hba.conf managed block
AxiomDB manages a designated section inside your database's pg_hba.conf file. Please avoid editing this block by hand, as your manual changes will be overwritten the next time a network rule updates.
-- === AXIOMDB MANAGED BLOCK — DO NOT EDIT ===
hostssl mydb axiom_pooler 203.0.113.0/24 scram-sha-256
hostssl mydb axiom_pooler 198.51.100.0/24 scram-sha-256
hostssl mydb axiom_direct 203.0.113.0/24 scram-sha-256
-- === END AXIOMDB MANAGED BLOCK ===Managed UFW firewall rules
# Managed by AxiomDB — do not edit manually
ufw allow from 203.0.113.0/24 to any port 6432 proto tcp
ufw allow from 203.0.113.0/24 to any port 5432 proto tcp
ufw allow from 198.51.100.0/24 to any port 6432 proto tcp
ufw allow from 198.51.100.0/24 to any port 5432 proto tcpHow fast does it take effect?
Network rules usually take about 5 to 15 seconds to apply. To make sure we don't accidentally drop any active connections, we keep both the old and new rule sets active while the update propagates.
Enforcing TLS for Every Connection
To keep your traffic secure, all public connections must use TLS. AxiomDB enforces sslmode=require on all pooler and direct database endpoints. We also take care of rotating self-signed certificates automatically every 90 days.
| Endpoint | TLS | sslmode |
|---|---|---|
pooler.axiom.cloud:6432 | Required | require |
direct.axiom.cloud:5432 | Required | require |
| Internal (private networking) | Optional | prefer |
If you want to verify certificates directly in your database client, you can connect like this:
psql "host=direct.axiom.cloud port=5432 dbname=mydb sslmode=verify-full sslrootcert=/path/to/ca.pem"Choosing the Right Scope: Project vs. Branch
Project-wide rules are active across all branches, including main, preview branches, and any new branches you create down the road. This is perfect for team VPNs or monitoring tools that need access to everything.
Branch-specific rules apply to a single branch only. Use these for temporary preview branches or staging environments where you want to lock down access separate from production.
# Project-wide rule: CI runners can reach all branches
axiom network rule create \
--project my-project \
--label "CI" \
--cidr "198.51.100.0/24" \
--scope project
# Branch-specific rule: preview deploy only
axiom network rule create \
--project my-project \
--branch preview/pr-42 \
--label "PR #42 deploy" \
--cidr "192.0.2.50/32" \
--scope branch \
--expires "168h"Cleaning Up Expired Rules
If you set an expiration time (expires_at), we'll automatically delete the rule once it expires. We'll also log a network.rule.deleted audit event with the reason marked as "expired".
Of course, you can also delete a rule manually whenever you want:
axiom network rule delete --project my-project --rule rule_7pQ4nR8wHow the grace period works
When a rule expires, we give active connections a 5-minute grace period to wind down. During this time, existing connections can finish their work, but no new connections are allowed. Once the 5 minutes are up, we'll terminate any remaining connections.
Putting It All Together: Modes and Rules
How do security modes and CIDR rules work together? The active access is determined by combining the rules for both:
| Mode | CIDR rule exists | Port 6432 access | Port 5432 access |
|---|---|---|---|
restricted | Yes | Allowed | Allowed |
restricted | No | Blocked | Blocked |
public_runtime | Yes | Allowed (anyone) | Allowed |
public_runtime | No | Allowed (anyone) | Blocked |
public_all | Yes | Allowed (anyone) | Allowed (anyone) |
public_all | No | Allowed (anyone) | Allowed (anyone) |
Best Practices for Network Security
- Default to restricted. Keep your project restricted unless you absolutely need to open it up to the public.
- Give rules clear labels. Use friendly names so it's easy to read your rule list and audit logs later.
- Set expirations for temporary access. If you're letting in a CI runner, a temporary deploy, or an external contractor, set a rule expiration time.
- Use project scope for core tools. Infrastructure like your company VPN, monitoring systems, or CI pipelines are best handled with project-scoped rules.
- Set up alerts on changes. Get notified whenever someone changes the project's overall security mode.
- Keep IP lists clean. If your cloud provider updates its IP ranges, make sure to update your rules and clean up old, unused ranges.
Troubleshooting Network Access
Connection refused
psql: connection to server at "direct.axiom.cloud" (203.0.113.1), port 5432 failed:
Connection refusedWhat went wrong: Your current IP address might not be allowlisted, or the security mode is blocking the port you're trying to use.
How to fix it: Double-check your public IP and add a new rule to allow access:
curl -s https://api.axiom.cloud/v1/network/my-ip
# {"ip": "198.51.100.42"}
axiom network rule create \
--project my-project \
--label "My machine" \
--cidr "198.51.100.42/32" \
--ports bothConnection timed out
What went wrong: The firewall changes might still be propagating, or the rule has expired.
How to fix it: Give it about 15 seconds to apply, then check that the rule is active:
axiom network rule get --project my-project --rule rule_2kF9x3mZSSL error
FATAL: no pg_hba.conf entry for host "198.51.100.42", user "axiom_pooler", database "mydb", SSL offWhat went wrong: Your database client is trying to connect without using TLS/SSL encryption.
How to fix it: Make sure to add sslmode=require to your connection string settings.
Related Pages
How is this guide?
Security
AxiomDB's security model spans authentication, tenant isolation (Row-Level Security), network access control, audit logging, credential audit, CORS policy, and the VPS hardening stack.
Credential Rotation
Rotate Postgres credentials atomically across all layers — database, pooler, and secret store — with zero downtime and full audit trails.
