Skip to content

Network — service-to-service — N1 IT Landscape

N1 IT Landscape — The Blueprint · CF-Access internal

N1 IT Landscape · Owner: Arun Venkataraman · source of truth: markdown SSOT

N1 IT Landscape — Network — service-to-service map

Section titled “N1 IT Landscape — Network — service-to-service map”

CURRENT-STATE as of 2026-06-09 · part of the N1 IT Landscape (start at Overview). Owner: Arun Venkataraman (Principal Engineer).


The who-calls-whom layer: every in-cluster service and port, the Valkey stream topology, ingress and egress edges, DB/cache allow-lists. The companion VPC/subnet/route-table map lives in NETWORK.md.

N1 service topology overview: Cloudflare ingress reaches identity and application services; applications use Valkey stream workers and PgBouncer-managed Aurora data stores.
Topology overview only; use the interactive topology explorer or the service, port, node, and edge lists below for complete operational detail. Download SVG source

This document is the service-level wire map for the N1 EKS clusters. NETWORK.md covers the VPC/subnet/peering/NAT/IGW layer; cross-reference it for CIDR blocks, route tables, and peering IDs.

Security model — flat pod network behind the edge. Both clusters (staging and production) have exactly 2 NetworkPolicies each — one permits Prometheus scraping of the ArgoCD image-updater metrics pod, and one permits Prometheus scraping of the KEDA event-notifier pod. Neither is an application-traffic restriction. There are no NetworkPolicies in thestaging, prod, llmproxy, ai-inference, monitoring, external-secrets, or kube-system namespaces. Pod-to-pod traffic within each cluster is completely unrestricted by NetworkPolicy. Isolation is enforced at three other layers: the Cloudflare edge (no inbound ports on AWS; all external entry via Cloudflare Tunnel), Cloudflare Access (Google IdP authentication on every n1-research.com hostname), and the namespace boundary (each environment’s app services share a namespace; cross-environment communication is physically impossible because staging and production are separate clusters in separate VPCs that have no peering or routing link between them).


All service types are ClusterIP unless noted. Ports are listed as name:clusterPort→targetPort/proto.

NS-2.1 Staging cluster — namespace: staging (21 services)

Section titled “NS-2.1 Staging cluster — namespace: staging (21 services)”
Service ClusterIP Port(s) What it is
admin-dashboard 172.20.31.110 http:3000→3000/TCP Internal admin UI
api-backend 172.20.152.201 http:8080→8080/TCP Core Python API server
api-websocket-proxy 172.20.4.120 http:9999→http/TCP Go WebSocket proxy fronting api-backend
authentication-service 172.20.103.252 http:9000→9000/TCP Ory glue — auth, sessions, OAuth clients
automated-testing 172.20.58.109 http:8787→http/TCP Automated test runner (staging only)
billing-service 172.20.138.176 http:4444→http/TCP Stripe billing service
forge-agents-api 172.20.125.178 http:8080→8080/TCP Read-only agent/workflow catalog HTTP server
helix-parser 172.20.240.190 http:8080→8080/TCP Helix parser (staging only)
hydra-admin 172.20.253.6 http:4445→http-admin/TCP Ory Hydra admin API
hydra-public 172.20.201.101 http:4444→http-public/TCP Ory Hydra OAuth2 public endpoint
kratos-admin 172.20.232.148 http:4434→admin/TCP Ory Kratos admin API
kratos-public 172.20.31.183 http:4433→public/TCP Ory Kratos public (identity/login)
memgraph 172.20.149.41 bolt:7687→7687/TCP Memgraph graph database (staging only)
oathkeeper-api 172.20.248.102 http:4456→http-api/TCP Ory Oathkeeper management API
oathkeeper-metrics 172.20.187.60 http:80→http-metrics/TCP Oathkeeper Prometheus metrics
oathkeeper-proxy 172.20.205.38 http:4455→http-proxy/TCP Ory Oathkeeper decision/proxy gateway
pgbouncer 172.20.90.111 pgbouncer:6432→6432/TCP, metrics:9127→9127/TCP PgBouncer connection pool (Aurora front-end)
phoenix-parser 172.20.188.71 http:8080→8080/TCP Phoenix clinical data extractor (stream consumer)
phoenix-router 172.20.149.242 http:8080→8080/TCP Phoenix page classifier (stream consumer)
qdrant 172.20.235.42 http:6333→6333/TCP, grpc:6334→6334/TCP Qdrant vector database (staging only)
rosetta-grouper 172.20.241.57 http:8080→8080/TCP Rosetta BiomarkerDefinition grouper (stream consumer)

NS-2.2 Production cluster — namespace: prod (22 services)

Section titled “NS-2.2 Production cluster — namespace: prod (22 services)”
Service ClusterIP Port(s) What it is
admin-dashboard 172.20.23.227 http:3000→3000/TCP Internal admin UI
api-backend 172.20.81.96 http:8080→8080/TCP Core Python API server
api-proxy 172.20.8.86 http:8888→8888/TCP Cloudflare-side API traffic proxy (prod only)
api-websocket-proxy 172.20.226.240 http:9999→http/TCP Go WebSocket proxy fronting api-backend
auth-proxy 172.20.127.127 http:8888→8888/TCP Cloudflare-side auth traffic proxy (prod only)
authentication-service 172.20.227.179 http:9000→9000/TCP Ory glue — auth, sessions, OAuth clients
billing-proxy 172.20.209.58 http:8888→8888/TCP Cloudflare-side billing traffic proxy (prod only)
billing-service 172.20.173.213 http:4444→http/TCP Stripe billing service
celery-flower 172.20.242.67 http:5555→5555/TCP Celery task monitor (prod only)
forge-agents-api 172.20.4.36 http:8080→8080/TCP Read-only agent/workflow catalog HTTP server
hydra-admin 172.20.72.27 http:4445→http-admin/TCP Ory Hydra admin API
hydra-public 172.20.241.37 http:4444→http-public/TCP Ory Hydra OAuth2 public endpoint
kratos-admin 172.20.246.65 http:4434→admin/TCP Ory Kratos admin API
kratos-public 172.20.189.83 http:4433→public/TCP Ory Kratos public (identity/login)
oathkeeper-api 172.20.212.20 http:4456→http-api/TCP Ory Oathkeeper management API
oathkeeper-metrics 172.20.150.210 http:80→http-metrics/TCP Oathkeeper Prometheus metrics
oathkeeper-proxy 172.20.171.10 http:4455→http-proxy/TCP Ory Oathkeeper decision/proxy gateway
pdf-converter 172.20.204.203 http:9000→http/TCP PDF-to-image converter (prod only)
pgbouncer 172.20.22.246 pgbouncer:6432→6432/TCP, metrics:9127→9127/TCP PgBouncer connection pool (Aurora front-end)
phoenix-parser 172.20.32.221 http:8080→8080/TCP Phoenix clinical data extractor (stream consumer)
phoenix-router 172.20.194.182 http:8080→8080/TCP Phoenix page classifier (stream consumer)
rosetta-grouper 172.20.122.135 http:8080→8080/TCP Rosetta BiomarkerDefinition grouper (stream consumer)

NS-2.3 Both clusters — shared namespaces

Section titled “NS-2.3 Both clusters — shared namespaces”
Service Staging ClusterIP Prod ClusterIP Port(s) What it is
mineru 172.20.5.43 172.20.68.27 http:8000→http/TCP MinerU-2.5 PDF/page classifier
embeddinggemma 172.20.77.41 — (staging only) http:8000→http/TCP, metrics:9000→metrics/TCP Gemma embedding model
Service Staging ClusterIP Prod ClusterIP Port(s) What it is
litellm 172.20.208.172 172.20.199.239 http:4000→4000/TCP LiteLLM proxy (all LLM calls from all services)
Service Staging ClusterIP Prod ClusterIP Port(s) What it is
otel-collector 172.20.229.229 172.20.70.144 otlp-grpc:4317/TCP, otlp-http:4318/TCP, metrics:8888/TCP, statsd:8125/UDP OpenTelemetry collector

Namespace: argocd (both clusters identical shape)

Section titled “Namespace: argocd (both clusters identical shape)”
Service Staging ClusterIP Prod ClusterIP Port(s)
argocd-application-controller-metrics 172.20.155.45 172.20.66.54 http-metrics:8082→metrics/TCP
argocd-applicationset-controller 172.20.13.226 172.20.3.206 http-webhook:7000→webhook/TCP
argocd-dex-server 172.20.125.80 172.20.147.157 http:5556/TCP, grpc:5557/TCP
argocd-image-updater-metrics 172.20.155.121 172.20.24.31 metrics:8443→metrics/TCP
argocd-redis 172.20.238.53 172.20.180.76 redis:6379→redis/TCP
argocd-repo-server 172.20.50.176 172.20.91.51 tcp-repo-server:8081→repo-server/TCP
argocd-server 172.20.209.235 172.20.141.99 http:80→8080/TCP, https:443→8080/TCP
argocd-server-proxy 172.20.120.32 172.20.145.162 http:80→8888/TCP, https:443→8888/TCP

Namespace: keda (both clusters identical shape)

Section titled “Namespace: keda (both clusters identical shape)”
Service Staging ClusterIP Prod ClusterIP Port(s)
keda-admission-webhooks 172.20.64.9 172.20.15.103 https:443→9443/TCP
keda-event-notifier-kubernetes-event-exporter-metrics 172.20.99.248 172.20.247.163 http:2112→http/TCP
keda-operator 172.20.94.135 172.20.114.73 metricsservice:9666/TCP, metrics:8080/TCP
keda-operator-metrics-apiserver 172.20.59.28 172.20.227.38 https:443→6443/TCP, metrics:9022/TCP

Namespace: kube-system (both clusters identical shape)

Section titled “Namespace: kube-system (both clusters identical shape)”
Service Staging ClusterIP Prod ClusterIP Port(s)
eks-extension-metrics-api 172.20.86.209 172.20.54.88 metrics-api:443→10443/TCP
karpenter 172.20.17.91 172.20.138.139 http-metrics:8080→http-metrics/TCP
kube-dns 172.20.0.10 172.20.0.10 dns:53/UDP, dns-tcp:53/TCP, metrics:9153/TCP
metrics-server 172.20.103.130 172.20.112.139 https:443→https/TCP

Namespace: external-secrets (both clusters)

Section titled “Namespace: external-secrets (both clusters)”
Service Staging ClusterIP Prod ClusterIP Port(s)
external-secrets-webhook 172.20.119.9 172.20.24.179 webhook:443→webhook/TCP

Namespace: default — staging only (KEDA + Kubernetes in default ns)

Section titled “Namespace: default — staging only (KEDA + Kubernetes in default ns)”
Service ClusterIP Port(s)
keda-admission-webhooks 172.20.139.98 https:443→9443/TCP
keda-operator 172.20.55.228 metricsservice:9666/TCP, metrics:8080/TCP
keda-operator-metrics-apiserver 172.20.227.110 https:443→6443/TCP, metrics:9022/TCP
kubernetes 172.20.0.1 https:443→443/TCP

NS-3. Synchronous call graph (HTTP / gRPC / WebSocket)

Section titled “NS-3. Synchronous call graph (HTTP / gRPC / WebSocket)”

Each edge is caller ──proto:port──▶ callee. Ports are from the live service catalogue (§NS-2) except where marked (inferred).

NS-3.1 External-to-cluster entry (via Cloudflare Tunnel)

Section titled “NS-3.1 External-to-cluster entry (via Cloudflare Tunnel)”
[internet browser / React app @ app.n1.care (Cloudflare Worker)]
├─ WebSocket path ──WS:9999──▶ api-websocket-proxy.{staging|prod}
│ └──HTTP:8080──▶ api-backend
└─ HTTP path ─────HTTP:4455──▶ oathkeeper-proxy.{staging|prod}
└──HTTP:8080──▶ api-backend
[internet → auth hostnames]
└─ HTTP:4455──▶ oathkeeper-proxy → HTTP:4433──▶ kratos-public
→ HTTP:9000──▶ authentication-service
[internet → oauth hostname (direct to Hydra, NOT through Oathkeeper)]
└─ HTTP:4444──▶ hydra-public
[internet → billing hostname]
└─ HTTP:4455──▶ oathkeeper-proxy → HTTP:4444──▶ billing-service
[admin dashboard hostname → Access gated]
└─ HTTP:3000──▶ admin-dashboard
api-backend ──HTTP:8080──▶ forge-agents-api (catalog reads: /agents/skills/, /agents/workflows/ + N1-Api-Key header)
api-backend ──HTTP:4000──▶ litellm (all LLM calls from api-backend)
api-backend ──HTTP:6432──▶ pgbouncer (PgBouncer → Aurora n1-{env}-app :5432)
authentication-service ──HTTP:4433──▶ kratos-public (session/identity lookups) (inferred)
authentication-service ──HTTP:4434──▶ kratos-admin (admin ops) (inferred)
authentication-service ──HTTP:4445──▶ hydra-admin (OAuth client management) (inferred)
authentication-service ──HTTP:6432──▶ pgbouncer (auth DB ops — auth-{env} Aurora :5432) (inferred)
oathkeeper-proxy ──HTTP:4433──▶ kratos-public (session check for decision endpoint)
oathkeeper-proxy ──HTTP:9000──▶ authentication-service (custom authenticator)
billing-service ──HTTP:6432──▶ pgbouncer (billing-{env} Aurora :5432) (inferred)
billing-service ──HTTPS──▶ Stripe API (over NAT egress) (inferred)
admin-dashboard ──HTTP:8080──▶ api-backend (inferred)
admin-dashboard ──HTTP:4444──▶ billing-service (inferred)
phoenix-router ──HTTP:8000──▶ mineru.ai-inference (page classification during document routing)
phoenix-parser ──HTTP:8000──▶ mineru.ai-inference (content extraction) (inferred)
litellm ──HTTP:4000──▶ [Vertex AI | Bedrock | other LLM providers via NAT]
litellm ──HTTP:6432──▶ pgbouncer (litellm-{env} Aurora :5432) (inferred)
forge-runner (k8s Job) ──HTTP:8080──▶ api-backend (MCP tools call n1 api client → api-backend for patient data) (inferred)
forge-runner ──HTTP:4000──▶ litellm (LLM calls from CHR workflows) (inferred)
forge-runner ──HTTP:6432──▶ pgbouncer (forge-runner-{env} Aurora :5432 — agno session/memory/LangGraph checkpoints) (inferred)
[all services] ──otlp-grpc:4317 | otlp-http:4318──▶ otel-collector.monitoring (telemetry) (inferred)

In production, three additional proxy services sit between the Cloudflare Tunnel and the app namespace services. These are not present in staging.

[Cloudflare Tunnel → api-proxy.prod:8888] → api-backend.prod:8080 (inferred)
[Cloudflare Tunnel → auth-proxy.prod:8888] → authentication-service or kratos (inferred)
[Cloudflare Tunnel → billing-proxy.prod:8888] → billing-service.prod:4444 (inferred)

NS-4. Asynchronous stream topology (Valkey/Redis Streams)

Section titled “NS-4. Asynchronous stream topology (Valkey/Redis Streams)”

Workers are stateless stream consumers scaled by KEDA on queue depth. Stream names are taken directly from KEDA ScaledObject definitions; scale ranges are from the live pull.

NS-4.1 Active Phoenix pipeline (both clusters)

Section titled “NS-4.1 Active Phoenix pipeline (both clusters)”
api-backend
└─ PRODUCE ──▶ stream: phoenix:router:input
phoenix-router (KEDA: min=2, max=50, lag≥2)
├─ CONSUME phoenix:router:input (consumerGroup: router-group)
├─ calls mineru:8000 per page for classification
└─ PRODUCE ──▶ stream: phoenix:parser:input
phoenix-parser (KEDA: min=2, max=50, lag≥2)
├─ CONSUME phoenix:parser:input (consumerGroup: parser-group)
└─ PRODUCE ──▶ stream: phoenix:grouper:input
rosetta-grouper (KEDA: min=2, max=50, lag≥2)
├─ CONSUME phoenix:grouper:input (consumerGroup: rosetta-grouper)
└─ PRODUCE result → api-backend (via n1 api client HTTP:8080)

NS-4.2 CHR / Forge pipeline (both clusters)

Section titled “NS-4.2 CHR / Forge pipeline (both clusters)”
api-backend
└─ PRODUCE ──▶ stream: (forge-sentinel subscription stream) (inferred — stream name not in ScaledObjects)
forge-sentinel
├─ CONSUME stream
└─ LAUNCH ──▶ forge-runner k8s Job
├─ runs CHR workflow (agno framework)
├─ calls api-backend:8080 via MCP tools
├─ calls litellm:4000 for LLM steps
└─ saves report → S3 (n1-{env}-user-data) (inferred)

NS-4.3 Data validation stream (both clusters)

Section titled “NS-4.3 Data validation stream (both clusters)”
(upstream producer — not a separate K8s service, produced by api-backend or pipeline workers) (inferred)
└─ PRODUCE ──▶ stream: data-validation-input-queue
data-validation-service (KEDA: min=2, max=10, lag≥5)
└─ CONSUME data-validation-input-queue (consumerGroup: data-validation-consumer-group)

Three evaluation streams exist in staging only, driven by an evals framework:

Stream Consumer Scale
phoenix:router-evals:input router-evals-service (min=1, max=5) lagCount=5
phoenix:parser-evals:input parser-evals-service (min=1, max=5) lagCount=5
phoenix:grouper-evals:input grouper-evals-service (min=1, max=5) lagCount=5

NS-4.5 Orphaned ScaledObjects in production (4)

Section titled “NS-4.5 Orphaned ScaledObjects in production (4)”

Production contains 4 ScaledObjects whose target Deployments no longer exist. These are leftover from the Rosetta 1.0 / pre-Phoenix pipeline migration and use the legacy redis list trigger (not redis-streams).

ScaledObject name Target Deployment Legacy list name Trigger type
grouping-poller-service (gone) grouping_poller_queue redis list
grouping-service (gone) group_medical_records redis list
parser-service (gone) parse_medical_records redis list
router-service (gone) route_medical_records redis list

These ScaledObjects watch real Valkey lists on production-valkey.zc3ep9.ng.0001.use2.cache.amazonaws.com:6379 but scale nothing — the lists are empty and the Deployments do not exist.

ScaledObject Cluster Trigger Target min max Threshold
staging/phoenix-router staging redis-streams Deployment/phoenix-router 2 50 lagCount=2
staging/phoenix-parser staging redis-streams Deployment/phoenix-parser 2 50 lagCount=2
staging/rosetta-grouper staging redis-streams Deployment/rosetta-grouper 2 50 lagCount=2
staging/data-validation-service staging redis-streams Deployment/data-validation-service 2 10 lagCount=5
staging/router-evals-service staging redis-streams Deployment/router-evals-service 1 5 lagCount=5
staging/parser-evals-service staging redis-streams Deployment/parser-evals-service 1 5 lagCount=5
staging/grouper-evals-service staging redis-streams Deployment/grouper-evals-service 1 5 lagCount=5
staging/api-websocket-proxy staging metrics-api Deployment/api-websocket-proxy 2 5 targetValue=1000
staging/pgbouncer staging metrics-api Deployment/pgbouncer 2 3 targetValue=300
ai-inference/mineru (staging) staging metrics-api Deployment/mineru 1 5 targetValue=20
prod/phoenix-router prod redis-streams Deployment/phoenix-router 2 50 lagCount=2
prod/phoenix-parser prod redis-streams Deployment/phoenix-parser 2 50 lagCount=2
prod/rosetta-grouper prod redis-streams Deployment/rosetta-grouper 2 50 lagCount=2
prod/data-validation-service prod redis-streams Deployment/data-validation-service 2 10 lagCount=5
prod/api-websocket-proxy prod metrics-api Deployment/api-websocket-proxy 2 10 targetValue=2000
prod/pgbouncer prod metrics-api Deployment/pgbouncer 2 4 targetValue=500
ai-inference/mineru (prod) prod metrics-api Deployment/mineru 1 10 targetValue=20
prod/grouping-poller-service prod redis list Deployment/grouping-poller-service 2 3 ORPHANED — Deployment gone
prod/grouping-service prod redis list Deployment/grouping-service 2 10 ORPHANED — Deployment gone
prod/parser-service prod redis list Deployment/parser-service 3 10 ORPHANED — Deployment gone
prod/router-service prod redis list Deployment/router-service 2 8 ORPHANED — Deployment gone

Both clusters use the cloudflare-tunnel Deployment (2 replicas, kube-system). The tunnel token is fetched from AWS Secrets Manager via ExternalSecrets. Routing rules are stored in the Cloudflare dashboard (config_src=cloudflare, remote_config=True), not in any in-cluster ConfigMap. The tables below are derived from n1-helm-charts environment configs and PROD_CF_CUTOVER.md.

The full tunnel IDs are below for the network record; the canonical tunnel health/purpose list is in§6.7 (taken from the live Cloudflare API).

Tunnel name ID Status Purpose
EKS Staging 03dae21f-eb8d-4e44-ab5f-08a5969baa0b healthy Staging cluster
EKS Production 5a3b0a66-8ba9-4789-af12-f7433ca980b5 healthy Production cluster
EKS AI Cluster d7bf4a5c-e142-42ff-b6c8-0dae34220f29 healthy AI/LiteLLM cluster
N1 NexAI 2f9140fe-5321-4e31-8b3e-d24339346b4e healthy Internal chat (chat.n1-research.com)
signoz 4ad64177-3d69-47a4-92cc-d38fbdc5baa9 healthy SigNoz observability host
N1 Langfuse b4d155e5-2270-4f83-993c-297c490a81d5 down Langfuse (langfuse.n1-research.com)
N1 Local Dev e2fbdd23-150f-4126-9f05-acac2dfc4997 down cortex-demo (local dev)

NS-5.2 Staging — tunnel EKS Staging (03dae21f) — hostname → service:port

Section titled “NS-5.2 Staging — tunnel EKS Staging (03dae21f) — hostname → service:port”
Public hostname Path In-cluster service:port Notes
api-staging.n1.care /ws/* api-websocket-proxy.staging:9999 WebSocket; token via ?token= query param
api-staging.n1.care /* oathkeeper-proxy.staging:4455 All other paths; httpHostHeader=“”
auth-staging.n1.care /* oathkeeper-proxy.staging:4455
billing-staging.n1.care /* oathkeeper-proxy.staging:4455
oauth-staging.n1.care /oauth2/, /.well-known/ , /userinfo hydra-public.staging:4444 Direct to Hydra; NOT through Oathkeeper
oauth-staging.n1.care /login, /consent, /logout authentication-service.staging:9000
argocd-staging.n1-research.com /* argocd-server-proxy.argocd:443 Cloudflare Access gated
litellm-staging.n1-research.com /* litellm.llmproxy:4000
staging-admin.n1-research.com /* admin-dashboard.staging:3000 Cloudflare Access gated
automated-testing.n1-research.com /* automated-testing.staging:8787
ws-api.n1-research.com /* api-websocket-proxy.staging:9999 Staging WS endpoint

Oathkeeper dispatch (staging) — what oathkeeper-proxy.staging:4455 routes to:

Match URL pattern Upstream
api-staging.n1.care/ws/* api-websocket-proxy.staging:9999
api-staging.n1.care/* api-backend.staging:8080
auth-staging.n1.care/self-service/, /sessions/whoami, /.well-known/ kratos-public.staging:4433
auth-staging.n1.care/keys/, /oauth/clients/ , /sessions/_, /(auth recovery
billing-staging.n1.care/* billing-service.staging:4444

NS-5.3 Production — tunnel EKS Production (5a3b0a66) — hostname → service:port

Section titled “NS-5.3 Production — tunnel EKS Production (5a3b0a66) — hostname → service:port”
Public hostname Path In-cluster service:port Notes
api.n1.care /ws api-websocket-proxy.prod:9999 WebSocket; token via ?token=
api.n1.care /* oathkeeper-proxy.prod:4455
billing.n1.care /* oathkeeper-proxy.prod:4455
oauth.n1.care /oauth2/, /.well-known/ , /userinfo hydra-public.prod:4444 Direct to Hydra
oauth.n1.care /login, /consent, /logout authentication-service.prod:9000
auth.n1.care /.well-known/jwks.json authentication-service.prod:9000 Before Kratos .well-known
auth.n1.care /self-service/methods/oidc/callback/* kratos-public.prod:4433
auth.n1.care /self-service/*, /sessions/whoami, /.well-known/ kratos-public.prod:4433
auth.n1.care /* authentication-service.prod:9000 Catch-all
api-production.n1.care /* api-backend.prod:8080 Legacy hostname (rollback only)
billing-production.n1.care /* billing-service.prod:4444 Legacy hostname
auth-production.n1.care /self-service/*, /sessions/whoami, /.well-known/ kratos-public.prod:4433 Legacy
auth-production.n1.care /* authentication-service.prod:9000 Legacy catch-all
litellm-prod.n1-research.com /* litellm.llmproxy:4000
argocd.n1-research.com /* argocd-server-proxy.argocd:443 ArgoCD auth (no dedicated CF Access app)
admin.n1-research.com /* admin-dashboard.prod:3000 CF Access — named allowlist of 7 emails
(default/catchall) http_status:404

Oathkeeper dispatch (production) — what oathkeeper-proxy.prod:4455 routes to:

Match URL pattern Upstream
api.n1.care/ws/* api-websocket-proxy.prod:9999
api.n1.care/* api-backend.prod:8080
auth.n1.care/self-service/, /sessions/whoami, /.well-known/ kratos-public.prod:4433
auth.n1.care/keys/, /oauth/clients/ , /sessions/_, /(auth recovery
billing.n1.care/* billing-service.prod:4444

NS-5.4 Other tunnels (not staging/prod EKS)

Section titled “NS-5.4 Other tunnels (not staging/prod EKS)”
Tunnel Hostname Backend
EKS AI Cluster (d7bf4a5c) litellm.n1-research.com litellm.llmproxy:4000 (AI cluster)
signoz (4ad64177) signoz.n1-research.com localhost:8080 on SigNoz VM
signoz (4ad64177) ingest-signoz.n1-research.com localhost:4318 on SigNoz VM (OTLP HTTP)
N1 NexAI (2f9140fe) chat.n1-research.com localhost:3080 on NexAI host
N1 Langfuse (b4d155e5) langfuse.n1-research.com DOWN

All pod egress exits via the single NAT gateway per cluster VPC (in us-east-2a) → internet gateway. There are no VPC endpoints, so AWS API traffic (S3, ECR, Secrets Manager, STS) also egresses via NAT. See NETWORK.md §1 for the route table detail.

External target Protocol / port Consumers
Vertex AI (GCP) HTTPS:443 litellm (inferred)
Amazon Bedrock (AWS) HTTPS:443 litellm (inferred)
Stripe API HTTPS:443 billing-service (inferred)
Postmark (email) HTTPS:443 authentication-service, api-backend (inferred)
GitHub HTTPS:443 argocd-image-updater, CI (inferred)
Amazon ECR HTTPS:443 Karpenter node pulls (inferred)
Cloudflare R2 HTTPS:443 artifact storage (inferred)
dhi.io HTTPS:443 api-backend / pipeline workers (inferred)
Slack HTTPS:443 alerting/webhook consumers (inferred)
ClickUp HTTPS:443 internal tooling (inferred)
AWS S3 (n1-{env}-user-data) HTTPS:443 api-backend (file storage), forge-runner (report write) (inferred)
AWS Secrets Manager / STS HTTPS:443 external-secrets-operator (inferred)

NS-7. Database and cache access — routes and allow-lists

Section titled “NS-7. Database and cache access — routes and allow-lists”

All database and cache connections from cluster pods follow the same path:

pod (cluster VPC CIDR)
└─ pgbouncer.{staging|prod}:6432 ──▶ (TCP → VPC peering link pcx-…) ──▶ Aurora :5432 (database VPC)
pod
└─ Valkey endpoint :6379 ──▶ (TCP → VPC peering link) ──▶ Valkey (database VPC)

The peering links are:

  • Staging: pcx-0b0be34847a25cce8 — cluster VPC 10.10.0.0/16 ↔ database VPC 10.80.0.0/16
  • Production: pcx-043ae3b00da8e9703 — cluster VPC 10.30.0.0/16 ↔ database VPC 10.70.0.0/16

NS-7.2 Security group allow-lists (the authoritative source)

Section titled “NS-7.2 Security group allow-lists (the authoritative source)”

Both environments use a single “database” security group that covers Aurora AND Valkey. The allowed source is the entire cluster VPC CIDR — not a specific per-service or per-security-group source restriction.

Env SG ID SG name Port Protocol Allowed from Covers
Staging sg-0ec302e948493a190 n1-staging-database-rds-sg 5432 TCP 10.10.0.0/16 (staging cluster VPC CIDR) Aurora PostgreSQL
Staging sg-0ec302e948493a190 n1-staging-database-rds-sg 6379 TCP 10.10.0.0/16 (staging cluster VPC CIDR) Valkey
Production sg-09a9f6eba199245f6 n1-production-database-rds-sg 5432 TCP 10.30.0.0/16 (production cluster VPC CIDR) Aurora PostgreSQL
Production sg-09a9f6eba199245f6 n1-production-database-rds-sg 6379 TCP 10.30.0.0/16 (production cluster VPC CIDR) Valkey

There is no tighter per-service or per-security-group source restriction. Any pod in the cluster VPC with a route to the peering link can reach both Aurora and Valkey. The cluster’s flat pod network (§NS-1) means any pod in the cluster can in principle open a connection; the namespace boundary and application-level authentication are the actual enforcement layer.

NS-7.3 Aurora clusters — endpoints and consumers

Section titled “NS-7.3 Aurora clusters — endpoints and consumers”

All clusters run Aurora PostgreSQL 17.7 Serverless v2 on port 5432 , SG sg-0ec302e948493a190 (staging) / sg-09a9f6eba199245f6 (production). App services connect via pgbouncer.{ns}:6432.

Cluster ID Database name Env Writer endpoint Reader endpoint Primary consumer(s)
n1-staging-app app staging n1-staging-app.cluster-c3gc6ccoiwig.us-east-2.rds.amazonaws.com n1-staging-app.cluster-ro-c3gc6ccoiwig.us-east-2.rds.amazonaws.com api-backend, phoenix workers, rosetta-grouper
auth-staging n1_auth staging auth-staging.cluster-c3gc6ccoiwig.us-east-2.rds.amazonaws.com auth-staging.cluster-ro-c3gc6ccoiwig.us-east-2.rds.amazonaws.com authentication-service, kratos, hydra
billing-staging n1_billing staging billing-staging.cluster-c3gc6ccoiwig.us-east-2.rds.amazonaws.com billing-staging.cluster-ro-c3gc6ccoiwig.us-east-2.rds.amazonaws.com billing-service
litellm-staging litellm staging litellm-staging.cluster-c3gc6ccoiwig.us-east-2.rds.amazonaws.com litellm-staging.cluster-ro-c3gc6ccoiwig.us-east-2.rds.amazonaws.com litellm
forge-runner-staging forge_runner staging forge-runner-staging.cluster-c3gc6ccoiwig.us-east-2.rds.amazonaws.com forge-runner-staging.cluster-ro-c3gc6ccoiwig.us-east-2.rds.amazonaws.com forge-runner (agno session/memory/LangGraph)
n1-production-app app prod n1-production-app.cluster-c3gc6ccoiwig.us-east-2.rds.amazonaws.com n1-production-app.cluster-ro-c3gc6ccoiwig.us-east-2.rds.amazonaws.com api-backend, phoenix workers, rosetta-grouper
auth-production n1_auth prod auth-production.cluster-c3gc6ccoiwig.us-east-2.rds.amazonaws.com auth-production.cluster-ro-c3gc6ccoiwig.us-east-2.rds.amazonaws.com authentication-service, kratos, hydra
billing-production n1_billing prod billing-production.cluster-c3gc6ccoiwig.us-east-2.rds.amazonaws.com billing-production.cluster-ro-c3gc6ccoiwig.us-east-2.rds.amazonaws.com billing-service
litellm-production litellm prod litellm-production.cluster-c3gc6ccoiwig.us-east-2.rds.amazonaws.com litellm-production.cluster-ro-c3gc6ccoiwig.us-east-2.rds.amazonaws.com litellm
forge-runner-production forge_runner prod forge-runner-production.cluster-c3gc6ccoiwig.us-east-2.rds.amazonaws.com forge-runner-production.cluster-ro-c3gc6ccoiwig.us-east-2.rds.amazonaws.com forge-runner (agno session/memory/LangGraph)

NS-7.4 Valkey (ElastiCache) — endpoints and consumers

Section titled “NS-7.4 Valkey (ElastiCache) — endpoints and consumers”

Both clusters use Valkey 8.x (AWS open-source Redis fork). No transit encryption (transitEncryptionEnabled: false); at-rest encryption enabled.

Property Staging Production
Replication group staging-valkey production-valkey
Node type cache.r7g.xlarge ×2 cache.m7g.large ×2
Primary endpoint staging-valkey.zc3ep9.ng.0001.use2.cache.amazonaws.com:6379 production-valkey.zc3ep9.ng.0001.use2.cache.amazonaws.com:6379
Reader endpoint staging-valkey-ro.zc3ep9.ng.0001.use2.cache.amazonaws.com:6379 production-valkey-ro.zc3ep9.ng.0001.use2.cache.amazonaws.com:6379
Node 1 staging-valkey-001.zc3ep9.0001.use2.cache.amazonaws.com:6379 production-valkey-001.zc3ep9.0001.use2.cache.amazonaws.com:6379
Node 2 staging-valkey-002.zc3ep9.0001.use2.cache.amazonaws.com:6379 production-valkey-002.zc3ep9.0001.use2.cache.amazonaws.com:6379
Security group sg-0ec302e948493a190 sg-09a9f6eba199245f6
Transit encryption false false
At-rest encryption true true

Consumers that connect to the primary Valkey endpoint:

  • api-backend — stream producer for phoenix:router:input and CHR trigger stream
  • phoenix-router — stream consumer (phoenix:router:input), producer (phoenix:parser:input)
  • phoenix-parser — stream consumer (phoenix:parser:input), producer (phoenix:grouper:input)
  • rosetta-grouper — stream consumer (phoenix:grouper:input)
  • data-validation-service — stream consumer (data-validation-input-queue)
  • forge-sentinel — CHR job queue consumer (inferred)
  • router-evals-service, parser-evals-service, grouper-evals-service — eval stream consumers (staging only)
  • argocd-redis (separate — argocd namespace uses its own in-cluster Redis ClusterIP service argocd-redis:6379, not the Valkey cluster)

NS-7.5 Developer read-only access (staging only)

Section titled “NS-7.5 Developer read-only access (staging only)”

WARP-enrolled devices (@n1.healthcare domain) can reach staging databases via Cloudflare Gateway DNS overrides:

DNS alias Resolves to Reaches
db.staging.n1 n1-staging-app.cluster-c3gc6ccoiwig.us-east-2.rds.amazonaws.com Aurora staging app DB :5432
redis.staging.n1 staging-valkey.zc3ep9.ng.0001.use2.cache.amazonaws.com Valkey staging :6379

The DNS override returns the private endpoint; the device reaches it over the WARP tunnel’s private-network route into 10.80.0.0/16 (inferred). Production databases have no equivalent WARP DNS override.


Feature Service(s) Notes
Ingress proxy layer api-proxy, auth-proxy, billing-proxy (:8888 each) Sit between Cloudflare Tunnel and app services; not in staging
PDF converter pdf-converter (:9000) PDF-to-image conversion for document pipeline
Celery task monitor celery-flower (:5555) Celery task visibility
Higher KEDA maxima api-websocket-proxy (max=10 vs 5), pgbouncer (max=4 vs 3) Prod handles more traffic
Feature Service(s) Notes
Eval harness router-evals-service, parser-evals-service, grouper-evals-service 3 streams, KEDA min=1 max=5
Automated testing automated-testing (:8787) Exposes automated-testing.n1-research.com
Helix parser helix-parser (:8080) Staging-only experimental parser
Gemma embeddings embeddinggemma (:8000, metrics:9000) Staging ai-inference only
Graph database memgraph (:7687 Bolt) Graph DB, staging only
Vector database qdrant (:6333 HTTP, :6334 gRPC) Vector DB, staging only
Lighter KEDA See §NS-4.6 Lower maxima throughout
WARP DB access db.staging.n1 / redis.staging.n1 Developer read-only; no production equivalent

Every node with its namespace/port/type, grouped by environment and trust boundary.

External / internet

  • internet_users — clinicians, developers
  • react_frontend — Cloudflare Worker @ app.n1.care
  • warp_devices — @n1.healthcare developer devices

Cloudflare edge

  • cf_access — Cloudflare Access (Google IdP)
  • cf_waf — Cloudflare WAF (production/n1.care only)
  • tunnel_staging — EKS Staging tunnel 03dae21f
  • tunnel_prod — EKS Production tunnel 5a3b0a66

Staging cluster — namespace: staging

  • s_api_ws_proxy — api-websocket-proxy :9999
  • s_oathkeeper — oathkeeper-proxy :4455
  • s_api_backend — api-backend :8080
  • s_auth_svc — authentication-service :9000
  • s_kratos — kratos-public :4433 / kratos-admin :4434
  • s_hydra_pub — hydra-public :4444
  • s_hydra_adm — hydra-admin :4445
  • s_billing — billing-service :4444
  • s_admin_dash — admin-dashboard :3000
  • s_forge_agents — forge-agents-api :8080
  • s_phoenix_router — phoenix-router :8080
  • s_phoenix_parser — phoenix-parser :8080
  • s_rosetta_grouper — rosetta-grouper :8080
  • s_data_val — data-validation-service (KEDA only, no ClusterIP listed)
  • s_pgbouncer — pgbouncer :6432 / metrics :9127
  • s_automated_test — automated-testing :8787 (staging only)
  • s_helix — helix-parser :8080 (staging only)
  • s_memgraph — memgraph :7687 (staging only)
  • s_qdrant — qdrant :6333/:6334 (staging only)
  • s_oathkeeper_api — oathkeeper-api :4456
  • s_router_evals — router-evals-service (staging only)
  • s_parser_evals — parser-evals-service (staging only)
  • s_grouper_evals — grouper-evals-service (staging only)

Staging cluster — namespace: ai-inference

  • s_mineru — mineru :8000
  • s_embeddinggemma — embeddinggemma :8000 / metrics :9000 (staging only)

Staging cluster — namespace: llmproxy

  • s_litellm — litellm :4000

Staging cluster — namespace: monitoring

  • s_otel — otel-collector otlp-grpc:4317 / otlp-http:4318

Staging database VPC

  • s_aurora_app — n1-staging-app Aurora :5432
  • s_aurora_auth — auth-staging Aurora :5432
  • s_aurora_billing — billing-staging Aurora :5432
  • s_aurora_litellm — litellm-staging Aurora :5432
  • s_aurora_forge — forge-runner-staging Aurora :5432
  • s_valkey — staging-valkey :6379

Staging Valkey streams (logical nodes)

  • stream_router_inputphoenix:router:input
  • stream_parser_inputphoenix:parser:input
  • stream_grouper_inputphoenix:grouper:input
  • stream_data_valdata-validation-input-queue
  • stream_router_evalsphoenix:router-evals:input (staging only)
  • stream_parser_evalsphoenix:parser-evals:input (staging only)
  • stream_grouper_evalsphoenix:grouper-evals:input (staging only)

Production cluster — namespace: prod (same shape as staging plus prod-only)

  • p_api_proxy — api-proxy :8888 (prod only)
  • p_auth_proxy — auth-proxy :8888 (prod only)
  • p_billing_proxy — billing-proxy :8888 (prod only)
  • p_pdf_converter — pdf-converter :9000 (prod only)
  • p_celery_flower — celery-flower :5555 (prod only)
  • p_api_ws_proxy, p_oathkeeper, p_api_backend, p_auth_svc, p_kratos, p_hydra_pub, p_hydra_adm, p_billing, p_admin_dash, p_forge_agents, p_phoenix_router, p_phoenix_parser, p_rosetta_grouper, p_data_val, p_pgbouncer — same ports as staging counterparts

Production cluster — shared namespaces (same ports as staging)

  • p_mineru, p_litellm, p_otel

Production database VPC

  • p_aurora_app, p_aurora_auth, p_aurora_billing, p_aurora_litellm, p_aurora_forge
  • p_valkey — production-valkey :6379

External egress targets (both clusters)

  • ext_vertex_ai, ext_bedrock, ext_stripe, ext_postmark, ext_github, ext_ecr, ext_r2, ext_dhi, ext_slack, ext_clickup, ext_s3, ext_secrets_mgr

Format: from → to : proto/port : type

Ingress edges (staging)

  1. internet_users → cf_access : HTTPS : ingress
  2. cf_access → tunnel_staging : route : ingress
  3. tunnel_staging → s_api_ws_proxy : WS:9999 : ingress (path /ws/*)
  4. tunnel_staging → s_oathkeeper : HTTP:4455 : ingress (path /* excl /ws)
  5. tunnel_staging → s_hydra_pub : HTTP:4444 : ingress (oauth-staging.n1.care /oauth2/* etc.)
  6. tunnel_staging → s_auth_svc : HTTP:9000 : ingress (oauth-staging.n1.care /login,/consent,/logout)
  7. tunnel_staging → s_admin_dash : HTTP:3000 : ingress (staging-admin.n1-research.com, CF Access)
  8. tunnel_staging → s_litellm : HTTP:4000 : ingress (litellm-staging.n1-research.com)
  9. tunnel_staging → s_automated_test : HTTP:8787 : ingress (automated-testing.n1-research.com)
  10. warp_devices → s_aurora_app : TCP:5432 : ingress (db.staging.n1, WARP, read-only, inferred)
  11. warp_devices → s_valkey : TCP:6379 : ingress (redis.staging.n1, WARP, read-only, inferred)

Ingress edges (production) 12. internet_users → cf_access : HTTPS : ingress 13. cf_access → tunnel_prod : route : ingress 14. tunnel_prod → p_api_ws_proxy : WS:9999 : ingress (api.n1.care /ws) 15. tunnel_prod → p_oathkeeper : HTTP:4455 : ingress (api.n1.care /) 16.tunnel_prod → p_hydra_pub : HTTP:4444 : ingress (oauth.n1.care /oauth2/ etc.) 17. tunnel_prod → p_auth_svc : HTTP:9000 : ingress (oauth.n1.care /login,/consent,/logout) 18. tunnel_prod → p_admin_dash : HTTP:3000 : ingress (admin.n1-research.com, CF Access) 19. tunnel_prod → p_litellm : HTTP:4000 : ingress (litellm-prod.n1-research.com)

Synchronous call edges (staging) 20. s_api_ws_proxy → s_api_backend : HTTP:8080 : sync (WebSocket path forwarded) 21. s_oathkeeper → s_api_backend : HTTP:8080 : sync (all API calls after auth decision) 22. s_oathkeeper → s_kratos : HTTP:4433 : sync (session validation) 23. s_oathkeeper → s_auth_svc : HTTP:9000 : sync (custom authenticator) 24. s_api_backend → s_forge_agents : HTTP:8080 : sync (catalog reads) 25. s_api_backend → s_litellm : HTTP:4000 : sync (LLM calls) 26. s_api_backend → s_pgbouncer : TCP:6432 : sync (DB writes/reads) 27. s_auth_svc → s_kratos : HTTP:4433 : sync (inferred) 28. s_auth_svc → s_hydra_adm : HTTP:4445 : sync (inferred) 29. s_auth_svc → s_pgbouncer : TCP:6432 : sync (inferred) 30. s_billing → s_pgbouncer : TCP:6432 : sync (inferred) 31. s_litellm → s_pgbouncer : TCP:6432 : sync (inferred) 32. s_phoenix_router → s_mineru : HTTP:8000 : sync (page classification) 33. s_phoenix_parser → s_mineru : HTTP:8000 : sync (inferred) 34. s_admin_dash → s_api_backend : HTTP:8080 : sync (inferred)

Stream edges (staging) 35. s_api_backend → stream_router_input : write : stream (phoenix:router:input) 36. stream_router_input → s_phoenix_router : read/KEDA : stream 37. s_phoenix_router → stream_parser_input : write : stream (phoenix:parser:input) 38. stream_parser_input → s_phoenix_parser : read/KEDA : stream 39. s_phoenix_parser → stream_grouper_input : write : stream (phoenix:grouper:input) 40. stream_grouper_input → s_rosetta_grouper : read/KEDA : stream 41. s_rosetta_grouper → s_api_backend : HTTP:8080 : sync (result write-back) 42. s_api_backend → stream_data_val : write : stream (inferred) 43. stream_data_val → s_data_val : read/KEDA : stream 44. stream_router_evals → s_router_evals : read/KEDA : stream 45. stream_parser_evals → s_parser_evals : read/KEDA : stream 46. stream_grouper_evals → s_grouper_evals : read/KEDA : stream

DB/cache edges (staging) 47. s_pgbouncer → s_aurora_app : TCP:5432 : sync (via peering, app DB) 48. s_auth_svc → s_aurora_auth : TCP:5432 : sync (inferred, via peering, auth DB) 49. s_billing → s_aurora_billing : TCP:5432 : sync (inferred, via peering, billing DB) 50. s_litellm → s_aurora_litellm : TCP:5432 : sync (inferred, via peering) 51. forge_runner → s_aurora_forge : TCP:5432 : sync (inferred, via peering, agno state) 52. s_api_backend → s_valkey : TCP:6379 : stream (stream producer) 53. s_phoenix_router → s_valkey : TCP:6379 : stream 54. s_phoenix_parser → s_valkey : TCP:6379 : stream 55. s_rosetta_grouper → s_valkey : TCP:6379 : stream 56. s_data_val → s_valkey : TCP:6379 : stream

Egress edges (both clusters — shown once) 57. s_litellm → ext_vertex_ai : HTTPS:443 : egress (inferred, via NAT) 58. s_litellm → ext_bedrock : HTTPS:443 : egress (inferred, via NAT) 59. s_billing → ext_stripe : HTTPS:443 : egress (inferred, via NAT) 60. s_auth_svc → ext_postmark : HTTPS:443 : egress (inferred, via NAT) 61. [all pods] → ext_ecr : HTTPS:443 : egress (inferred, image pulls via NAT) 62. [all pods] → ext_secrets_mgr : HTTPS:443 : egress (inferred, ExternalSecrets via NAT) 63. s_api_backend → ext_s3 : HTTPS:443 : egress (inferred, file storage via NAT)

Production has the same sync/stream/DB/egress edge shape — substitute p_* node IDs and add edges for the prod-only proxy layer (api-proxy, auth-proxy, billing-proxy at :8888).

The versioned SVG overview above is the published diagram. The node and edge lists in §§NS-9.1–NS-9.2 remain the complete implementation record.


NS-10. Boundaries — what this document does not cover

Section titled “NS-10. Boundaries — what this document does not cover”

Edges in §NS-3 are derived from Kubernetes Service definitions, KEDA ScaledObject stream trigger definitions, and the verified call/stream narrative in 09-APP-ARCHITECTURE.md. Any edge not directly observable from those sources is marked (inferred). The node and edge lists are the retained historical source input for the versioned visual, not browser-rendered diagram code.

This document does not include: live packet captures or flow logs; exact per-pod ephemeral-port assignments; internal Ory mesh calls beyond the primary paths documented above; the AI/development cluster (n1-ai-cluster, account 083636777616), which is out of scope; or intra-ArgoCD, intra-KEDA, or intra-kube-system call graphs. For VPC/subnet/route-table/peering detail, see NETWORK.md. For the service repo/image mapping and dependency versions, see DEPENDENCIES/00-BOM.md.