Skip to content

Network Architecture & Firewall Configuration

This guide covers how to deploy TapPass in enterprise networks with firewalls, proxies, TLS inspection, and restricted egress.


TapPass runs inside your corporate network as an internal service. It is not a SaaS. no inbound connections from the internet are required for the data plane.

┌──────────────────────────────────────────────────────────────────┐
│ CORPORATE NETWORK │
│ │
│ ┌──────────┐ ┌──────────────┐ ┌────────────────────┐ │
│ │ AI Agent │───▶│ TapPass │───▶│ Corporate Egress │─────┼──▶ LLM Providers
│ │ │ │ (internal) │ │ Proxy (Zscaler / │ │ (api.openai.com,
│ └──────────┘ │ │ │ Palo Alto / etc.) │ │ api.anthropic.com)
│ ▲ └──────┬───────┘ └────────────────────┘ │
│ │ │ │
│ │ ┌──────┴───────┐ │
│ │ │ OPA sidecar │ │
│ │ └──────────────┘ │
│ │ │
│ Internal only. No inbound from internet. │
│ Dashboard accessible via Cloudflare Tunnel or VPN. │
└──────────────────────────────────────────────────────────────────┘
#SourceDestinationPortProtocolDirectionPurpose
1AI AgentTapPass9620/tcpHTTPS (mTLS)InternalGoverned LLM calls
2TapPassOPA8181/tcpHTTPlocalhost / sidecarPolicy decisions
3TapPassPostgreSQL5432/tcpTCP+TLSInternalAudit trail, state
4TapPassRedis6379/tcpTCPlocalhost / sidecarRate limits, sessions
5TapPassLLM Provider443/tcpHTTPSOutbound (egress)OpenAI, Anthropic, etc.
6TapPassSPIRE Server8081/tcpgRPC+mTLSInternalCertificate issuance
7SPIRE AgentSPIRE Server8081/tcpgRPC+mTLSInternalAttestation
8BrowserTapPass443/tcpHTTPSInbound (dashboard)Admin UI (optional)

Minimal Rules (Internal Only: No Dashboard Exposure)

Section titled “Minimal Rules (Internal Only: No Dashboard Exposure)”

Only outbound HTTPS to LLM providers is required. Everything else is internal.

# ── Inbound: NONE required ──────────────────────────────────────
# TapPass is internal-only. Agents connect within the corporate network.
# ── Internal (agent → TapPass) ──────────────────────────────────
ALLOW tcp/9620 FROM agent-subnet TO tappass-subnet # Governed calls
# ── Internal (TapPass → infrastructure) ─────────────────────────
ALLOW tcp/5432 FROM tappass-subnet TO db-subnet # PostgreSQL
ALLOW tcp/6379 FROM tappass-subnet TO redis-subnet # Redis (if external)
ALLOW tcp/8081 FROM tappass-subnet TO spire-subnet # SPIRE Server
# ── Outbound (TapPass → LLM providers via egress proxy) ─────────
ALLOW tcp/443 FROM tappass-subnet TO proxy-subnet # Corporate proxy
# OR direct egress (if no proxy):
ALLOW tcp/443 FROM tappass-subnet TO 0.0.0.0/0 # LLM providers

Firewall Rule Template (CSV. Palo Alto / Fortinet Import)

Section titled “Firewall Rule Template (CSV. Palo Alto / Fortinet Import)”

Save as tappass-firewall-rules.csv and import into your firewall management console:

name,source_zone,source_address,destination_zone,destination_address,destination_port,protocol,action,description
tappass-agent-inbound,trust,agent-subnet,trust,tappass-subnet,9620,tcp,allow,AI agents to TapPass governance
tappass-to-postgres,trust,tappass-subnet,trust,db-subnet,5432,tcp,allow,TapPass to PostgreSQL
tappass-to-redis,trust,tappass-subnet,trust,redis-subnet,6379,tcp,allow,TapPass to Redis
tappass-to-spire,trust,tappass-subnet,trust,spire-subnet,8081,tcp,allow,TapPass to SPIRE Server
tappass-llm-egress,trust,tappass-subnet,untrust,any,443,tcp,allow,TapPass to LLM providers (HTTPS)

If your proxy filters by domain, allowlist these endpoints:

# LLM Providers (enable only the ones you use)
api.openai.com
api.anthropic.com
generativelanguage.googleapis.com
api.mistral.ai
api.deepseek.com
api.groq.com
# TapPass infrastructure (if using managed services)
*.supabase.co # Managed PostgreSQL (if Supabase backend)
# SPIFFE/SPIRE (internal only. should not need external access)
# No external DNS entries required

TapPass Server → LLM Providers (Outbound Proxy)

Section titled “TapPass Server → LLM Providers (Outbound Proxy)”

If your corporate network routes outbound HTTPS through a proxy, configure TapPass:

Terminal window
# In .env.prod or docker-compose environment:
HTTP_PROXY=http://proxy.corp.internal:8080
HTTPS_PROXY=http://proxy.corp.internal:8080
NO_PROXY=localhost,127.0.0.1,opa,redis,postgres,spire-server,.internal
# TapPass-specific (takes precedence over HTTP_PROXY for LLM calls):
TAPPASS_PROXY_URL=http://proxy.corp.internal:8080

TapPass uses httpx internally, which respects standard HTTP_PROXY / HTTPS_PROXY environment variables. The NO_PROXY setting is critical. internal sidecar traffic (OPA, Redis) must not go through the proxy.

If agents run in a different network segment and need to reach TapPass through a proxy:

from tappass import Agent
import os
# Standard proxy env vars. httpx respects these automatically
os.environ["HTTPS_PROXY"] = "http://proxy.corp.internal:8080"
os.environ["NO_PROXY"] = "localhost,127.0.0.1"
agent = Agent("https://tappass.internal:9620")

Or in the shell:

Terminal window
export HTTPS_PROXY=http://proxy.corp.internal:8080
export NO_PROXY=localhost,127.0.0.1
python my_agent.py

Many enterprises run TLS-inspecting proxies (Zscaler, Palo Alto, Fortinet) that perform man-in-the-middle (MITM) decryption of all HTTPS traffic. This breaks mTLS because the proxy replaces the client certificate.

Does your network have a TLS-inspecting proxy?
├─ NO → Standard deployment. mTLS works. Done.
└─ YES → Does it inspect ALL traffic, or can you exempt by SNI/IP?
├─ Can exempt → Add a TLS bypass rule for TapPass traffic.
│ See "Bypass Rule" below.
└─ Cannot exempt → Use Cloudflare Tunnel for the dashboard.
Deploy TapPass in the same network segment
as agents (no proxy between them).
Use API key auth instead of mTLS for
cross-segment agent traffic.

Add a TLS inspection bypass for agent-to-TapPass traffic:

Zscaler:

SSL Inspection Policy → Add Exception:
Destination: tappass.internal (or IP range of TapPass subnet)
Action: Bypass SSL Inspection
Reason: mTLS required for agent governance

Palo Alto:

Decryption Policy → Add No-Decrypt Rule:
Source Zone: trust
Destination: tappass-subnet
Service: tcp/9620
Action: No Decrypt

Fortinet:

SSL/SSH Inspection → Exemptions:
Address: tappass-subnet
Exempt from SSL Inspection: Yes

If your security policy does not allow TLS bypass for any traffic:

  1. Deploy TapPass in the same subnet as agents. no proxy needed for internal traffic.
  2. Use API key authentication instead of mTLS for agent identity. Set TAPPASS_ADMIN_API_KEY and use tp_ prefixed keys.
  3. The proxy only applies to outbound TapPass → LLM provider traffic, which is standard HTTPS and works through TLS inspection.

The production Docker Compose includes a Cloudflare Tunnel for exposing the dashboard without opening inbound firewall ports.

# In deploy/docker-compose.prod.yml
tunnel:
image: cloudflare/cloudflared:latest
command: tunnel --protocol http2 run
environment:
- TUNNEL_TOKEN=${TUNNEL_TOKEN}

Important: The Cloudflare Tunnel is for the dashboard/admin UI only. Agent traffic should stay internal and never traverse the tunnel. This separation is critical:

TrafficPathWhy
Agent → TapPassInternal network (direct)Low latency, no internet dependency
Admin → DashboardCloudflare TunnelZero inbound firewall rules, Zero Trust access
TapPass → LLMOutbound HTTPS (via proxy)Standard egress, auditable

SPIRE uses gRPC for all communication. Required flows:

SourceDestinationPortProtocolPurpose
SPIRE AgentSPIRE Server8081/tcpgRPC + mTLSAttestation, SVID issuance
TapPassSPIRE AgentUnix socketLocalWorkload API (cert retrieval)
spiffe-helperSPIRE AgentUnix socketLocalCert rotation signaling

Key point: The SPIRE Agent runs as a sidecar or DaemonSet on the same node. Communication between TapPass and SPIRE Agent uses a Unix domain socket (/tmp/spire-agent/public/api.sock), not a network connection. No firewall rule is needed for this path.

SPIRE Server ↔ Agent communication (port 8081) is the only network flow. This is internal and uses mutual TLS with its own trust bundle.


The Helm chart includes a NetworkPolicy resource (networkPolicy.enabled: true in values.yaml):

values.yaml
networkPolicy:
enabled: true
egressAllowCIDRs:
- 10.0.0.0/8 # Internal services (DB, Redis, SPIRE)
# Add LLM provider IPs or use proxy CIDR:
- 192.168.1.0/24 # Corporate proxy

For strict egress control, use your cloud provider’s IP ranges for LLM providers:

# Example: OpenAI uses Cloudflare, so you need Cloudflare IP ranges
# Alternatively, route through your corporate proxy (recommended)
networkPolicy:
enabled: true
egressAllowCIDRs:
- 10.0.0.0/8 # Internal
- 172.16.0.0/12 # Internal
- 192.168.0.0/16 # Internal
# Proxy egress only:
- 10.100.1.50/32 # Corporate proxy IP

TapPass supports SSE (Server-Sent Events) for streaming LLM responses. Some corporate proxies and load balancers kill connections that are idle or long-lived.

ComponentMinimum TimeoutReason
Load balancer → TapPass120sLLM responses can take 60s+ for complex queries
Proxy (agent → TapPass)120sSame: streaming SSE connections
TapPass → LLM provider120sProvider-side timeout (configured in TapPass)

NGINX Ingress:

nginx.ingress.kubernetes.io/proxy-read-timeout: "120"
nginx.ingress.kubernetes.io/proxy-send-timeout: "120"
nginx.ingress.kubernetes.io/proxy-buffering: "off" # Required for SSE

AWS ALB:

idle_timeout.timeout_seconds = 120

Cloudflare Tunnel: Cloudflare Tunnel natively supports long-lived connections. No special configuration needed.


For environments without internet access:

  1. Container images: Export as tarballs and import into your private registry.

    Terminal window
    docker save ghcr.io/cogniqor/tappass:0.2.0 -o tappass.tar
    docker save openpolicyagent/opa:0.71.0-static -o opa.tar
    docker save redis:7-alpine -o redis.tar
    docker save postgres:16-alpine -o postgres.tar
    # Transfer tarballs to air-gapped network, then:
    docker load -i tappass.tar
  2. LLM provider: Use a locally-hosted model (Ollama, vLLM) instead of cloud APIs.

    Terminal window
    TAPPASS_LLM_JUDGE_MODEL=ollama/llama3.1
    TAPPASS_OLLAMA_API_BASE=http://ollama.internal:11434
  3. Presidio NLP models: Pre-packaged in the Docker image. No runtime download needed.

  4. OPA policies: Bundled in the ConfigMap. No external bundle server needed.


”Connection refused” from agent to TapPass

Section titled “”Connection refused” from agent to TapPass”
Terminal window
# From the agent's host/pod:
curl -v http://tappass:9620/health
# Expected: {"status": "healthy", ...}
# If using mTLS:
curl -v --cert /run/spire/certs/svid.pem \
--key /run/spire/certs/svid_key.pem \
--cacert /run/spire/certs/bundle.pem \
https://tappass:9620/health

Symptom: ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED]

This means a TLS-inspecting proxy is replacing the TapPass certificate. See TLS Inspection Compatibility above.

Terminal window
# From the TapPass pod:
curl -v --proxy $HTTPS_PROXY https://api.openai.com/v1/models
# Should return a JSON response (even if 401: that means connectivity works)
Terminal window
# Check SPIRE Agent health:
docker compose exec spire-agent /opt/spire/bin/spire-agent healthcheck
# Check logs:
docker compose logs spire-agent
agent = Agent("http://tappass:9620")
print(agent.resilience_status)
# Returns circuit breaker state, cache size, buffered audit entries