vault
13 — Network Model
Network Model
Target state. The current MVP is documented in 02-Architecture and deploys through the AWS dev Terraform stack for speed of delivery. This page is the AWS-native network/SG model that lands with the AWS refactor — see 11-Target-Architecture and 12-Environments. Production never runs outside AWS.
Network zones
| Zone | What lives here | Internet-facing? |
|---|---|---|
| Public | Route 53, CloudFront, AWS WAF, AWS Shield, API Gateway, NAT Gateway | Yes (controlled) |
| Private App Subnet | App + worker containers on EC2, CoSigner parent EC2 | No |
| Private Data Subnet | Postgres (data + pg-boss queues), S3 internal buckets | No |
Key directional rules
- Route 53 → CloudFront + AWS WAF → API Gateway → internal ALB → private app.
- Public never speaks to data subnet directly.
- Private services reach providers via NAT egress only.
- CoSigner has its own outbound (Fireblocks) and no public inbound.
Public components
Route 53
- Authoritative DNS for the zone.
- Health checks + failover routing for multi-AZ / multi-region (Prod).
CloudFront + AWS WAF + AWS Shield
- CDN for static + cached responses; HTTPS termination at the edge.
- AWS WAF web ACL: managed rule sets (OWASP, anonymous IP, bot control) + rate-based rules per IP / per session.
- AWS Shield Standard always on; Shield Advanced enabled for Prod.
- First control layer for user / merchant / admin traffic.
API Gateway
- Public entry into AWS for HTTP.
- VPC Link to internal ALB.
NAT Gateway
- Outbound-only egress for private workloads.
- All provider calls (Fireblocks, TRES, Sumsub, Elliptic, Mercuryo, CEX.IO, Resend) leave through this.
S3 (static delivery)
- Origin for CloudFront. No direct public access (Origin Access Control only).
Private components
| Component | Purpose |
|---|---|
| internal ALB | Routes API Gateway traffic into private app layer |
| App containers (EC2) | User / merchant / admin API |
| Worker containers (EC2) | Background jobs, async integration |
| Fireblocks CoSigner (EC2 + Nitro Enclave) | Signing-policy enforcement |
| pg-boss (on Postgres) | Queue, retry, scheduling |
| PostgreSQL | Primary data store |
Postgres rate_limits |
Rate-limit windows + login lockout |
| S3 internal buckets | Exports, logs, generated artifacts |
| Secrets Manager / KMS | Credentials, encryption-at-rest |
| CloudWatch / CloudTrail / GuardDuty / Security Hub (Prod) | Observability + audit + threat |
Security groups
SG-ALB
- Used by: internal Application Load Balancer.
- Inbound: from API Gateway / VPC Link only.
- Outbound: to
SG-APPonly. - Rule: no broad public access; routes through controlled entry.
SG-APP
- Used by: application containers on EC2.
- Inbound: from
SG-ALBonly. - Outbound: to
SG-WORKER,SG-DB, NAT (provider egress). - Rule: minimum ports, minimum peers.
SG-WORKER
- Used by: pg-boss worker containers on EC2.
- Inbound: from controlled internal sources only (no public).
- Outbound: to
SG-DB, NAT, S3. - Rule: workers must not be reachable from the public internet.
SG-COSIGNER
- Used by: Fireblocks CoSigner parent EC2 (with Nitro Enclave).
- Inbound: from controlled internal app/worker paths only as required.
- Outbound: only to Fireblocks endpoints + required dependencies.
- Rule: tightest restriction. CoSigner is not general-purpose compute.
SG-DB
- Used by: PostgreSQL.
- Inbound: from
SG-APPandSG-WORKERonly. - Outbound: none required.
- Rule: never publicly reachable.
Allowed peer matrix
| SG-ALB | SG-APP | SG-WORKER | SG-COSIGNER | SG-DB | |
|---|---|---|---|---|---|
| From API GW | ✓ | – | – | – | – |
| From SG-ALB | – | ✓ | – | – | – |
| From SG-APP | – | – | ✓ (where needed) | ✓ (where needed) | ✓ |
| From SG-WORKER | – | – | – | ✓ (where needed) | ✓ |
| From Public | – | – | – | – | – |
| From SG-COSIGNER | – | – | – | – | – |
A blank cell means the peer is not allowed. CoSigner only emits outbound to Fireblocks — it never accepts public inbound and only accepts narrow internal inbound.
General rules
No public DB or cache access
The database must never be reachable from the public internet — full stop. Backed by SG rules + private-subnet placement.
CoSigner isolation
Tighter than every other workload. Treat it as a single-purpose dependency, not a general compute target.
Minimal-path design
Every SG exposes the minimum ports to the minimum peers. New rules require explicit justification at review time.
NAT-only egress
Workloads in private subnets reach providers exclusively through the NAT Gateway. No direct internet routes from private services.
Environment usage
| Environment | Network model |
|---|---|
| Dev | Same conceptual SGs, reduced scale, simplified peering |
| Test | Full logical model, production-like enforcement |
| Prod | Full model + strongest review/audit posture |
See 12-Environments for HA/DR profile per env.
Admin access path
Admin traffic uses a separate posture from user/merchant:
admin user
|
v
AWS IAM Identity Center (SSO + MFA)
|
v
CloudFront + AWS WAF (admin ruleset, IP allowlist)
|
v
admin-subdomain entry (private API GW route)
|
v
internal ALB (SG-ALB)
|
v
admin app containers (SG-APP)
- AWS IAM Identity Center provides SSO + MFA + group-based access.
- A dedicated AWS WAF web ACL on the admin distribution applies a stricter ruleset (IP allowlist, geo restriction, lower rate-limit thresholds).
- VPN / PrivateLink option for ops-grade access where required.
- No shared entry path with user/merchant traffic.
Drawbacks
- The SG matrix is strict by design — adding new internal services requires explicit SG changes, slowing experimentation.
- NAT-only egress costs money and concentrates blast radius if NAT misbehaves; mitigated by Multi-AZ NAT in Prod.
Open Questions
- 09-Open Questions#NAT topology — Multi-AZ NAT vs single NAT in Test.
- 09-Open Questions#CoSigner topology — Dev CoSigner network exposure.