Skip to main content

Network & Proxy Configuration

Enterprise environments often require that all outbound traffic from applications passes through a corporate proxy, firewall, or API gateway. Align provides two layers of network control for self-hosted deployments.

Layer 1: HTTP Proxy (Network-Level)

Route all outbound traffic through a corporate HTTP/HTTPS proxy. This applies to every pod in the Align deployment.

Configuration

global:
proxy:
# Forward proxy for HTTPS traffic (most common)
httpsProxy: "http://proxy.corp.example.com:3128"
# Forward proxy for HTTP traffic (optional, usually same as above)
httpProxy: "http://proxy.corp.example.com:3128"
# Additional hosts to bypass the proxy (comma-separated)
# Internal Align services are automatically excluded
noProxy: "*.internal.corp.com,10.0.0.0/8"

When configured, every Align pod receives HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables (both uppercase and lowercase for compatibility). Internal service-to-service traffic is automatically added to NO_PROXY.

How It Works

  • Connectors (Slack, Teams, Jira, GitHub, Linear) use undici.fetch which respects HTTPS_PROXY automatically
  • Teams Bot Framework SDK has explicit proxy agent support wired in - all token acquisition and proactive messaging traffic is routed through the proxy
  • Brain service (Python/FastAPI) respects HTTPS_PROXY via httpx and aiohttp
  • Gateway respects proxy vars for any outbound calls (credential exchange, etc.)

Backward Compatibility

When no proxy values are configured, no environment variables are injected. Existing deployments are unaffected.

Layer 2: API Base URL Overrides (Application-Level)

For more granular control, you can redirect each connector's API traffic to a specific endpoint - for example, a corporate API gateway, reverse proxy, or custom MCP server that wraps the upstream API.

Per-Connector Configuration

connectors:
slack:
# Route all Slack API calls through your corporate gateway
apiBaseUrl: "https://api-gateway.corp.example.com/slack/api"

teams:
# Route all Microsoft Graph API calls through your corporate gateway
graphApiBaseUrl: "https://api-gateway.corp.example.com/graph"

jira:
# Route all Jira/Atlassian API calls through your corporate gateway
apiBaseUrl: "https://api-gateway.corp.example.com/atlassian/ex/jira"

github:
# GitHub Enterprise Server or corporate gateway
apiBaseUrl: "https://github.corp.example.com/api/v3"

linear:
# Route Linear API calls through your corporate gateway
apiBaseUrl: "https://api-gateway.corp.example.com/linear/graphql"

Environment Variables

Each override maps to an environment variable:

ConnectorHelm ValueEnvironment VariableDefault
Slackconnectors.slack.apiBaseUrlSLACK_API_BASE_URLhttps://slack.com/api
Teamsconnectors.teams.graphApiBaseUrlTEAMS_GRAPH_API_BASE_URLhttps://graph.microsoft.com
Jiraconnectors.jira.apiBaseUrlJIRA_API_BASE_URLhttps://api.atlassian.com/ex/jira
GitHubconnectors.github.apiBaseUrlGITHUB_API_BASE_URLhttps://api.github.com
Linearconnectors.linear.apiBaseUrlLINEAR_API_BASE_URLhttps://api.linear.app/graphql
tip

You can also set these via extraEnv on each connector if you prefer managing environment variables directly.

note

For Jira, the base URL must include the /ex/jira path prefix. The connector appends /{cloudId}/rest/api/3/... to this base. If routing through a gateway, ensure it proxies to api.atlassian.com/ex/jira with the correct path structure.

Kubernetes NetworkPolicy

For defense-in-depth, enable Kubernetes NetworkPolicies to apply a default-deny ingress posture and restrict egress at the network level.

What enabled: true ships

Ingress (default-deny + allow-list):

  • Every Align pod denies ingress by default.
  • Align pods may receive traffic from other Align pods in the same namespace (so gateway↔brain, ui→gateway, and connectors↔gateway keep working).
  • Only the public-facing components (gateway, ui, connector-align) accept external ingress, and only from the source you configure (below).

Egress:

  • Pod-to-pod within the namespace and DNS (UDP/TCP 53, when allowDNS: true).
  • External egress to allowedExternalCIDRs (empty = allow all external).
  • The cloud metadata endpoint (169.254.169.254, AWS IPv6 equivalent) is always blocked.

Configuration

networkPolicies:
enabled: true
ingress:
# Selector-routable controllers (e.g. ingress-nginx)
fromIngressController:
enabled: true
namespaceSelector:
kubernetes.io/metadata.name: ingress-nginx
podSelector: {}
# ALB/NLB with target-type=ip: traffic arrives from VPC IPs, not a pod.
# Allow your VPC / load-balancer subnet CIDR(s) instead.
allowedIngressCIDRs:
- 10.0.0.0/16
allowDNS: true
allowedExternalCIDRs:
- 10.0.0.0/8
- 172.16.0.0/12
Choose the right ingress source for your load balancer

With an AWS ALB/NLB using target-type: ip (the default in this chart), requests reach pods directly from the load balancer's VPC IPs - a podSelector will not match. Use allowedIngressCIDRs with your VPC CIDR. Use fromIngressController only for in-cluster, selector-routable controllers like ingress-nginx. If you configure neither, the public components accept no external ingress (internal-only).

Rollout

NetworkPolicies are only enforced under a policy-capable CNI (Calico, Cilium, EKS VPC-CNI with policy enabled); on other clusters they are silently ignored. Because a too-tight allow-list can break ingress, enable on a non-prod environment first, confirm the app is reachable and gateway↔brain works, then promote to prod.

Pod-to-pod encryption (mTLS)

NetworkPolicies restrict who can talk to whom, not whether traffic is encrypted. In-cluster gateway↔brain traffic is plain HTTP. For encryption in transit between pods, run Align inside a service mesh that provides automatic mTLS - Linkerd (simplest) or Istio in mTLS STRICT mode. Both wrap the existing services with no application changes; combine the mesh's mTLS with these NetworkPolicies for full transit hardening.

Required Outbound Domains

If you need to configure a firewall allowlist, here are the external domains Align connects to:

DomainUsed ByPurpose
slack.comSlack connectorSlack API, OAuth
graph.microsoft.comTeams connectorMicrosoft Graph API
login.microsoftonline.comTeams connectorAzure AD authentication
login.botframework.comTeams connectorBot Framework token service
smba.trafficmanager.netTeams connectorTeams bot messaging
api.atlassian.comJira connectorJira Cloud API
api.github.comGitHub connectorGitHub API
api.linear.appLinear connectorLinear GraphQL API
api.openai.comBrain serviceOpenAI LLM (if configured)
api.anthropic.comBrain serviceAnthropic LLM (if configured)

Combining Both Layers

For maximum security, use both layers together:

global:
proxy:
httpsProxy: "http://squid.corp.example.com:3128"

connectors:
slack:
apiBaseUrl: "https://api-gw.corp.example.com/slack/api"
teams:
graphApiBaseUrl: "https://api-gw.corp.example.com/graph"
jira:
apiBaseUrl: "https://api-gw.corp.example.com/atlassian/ex/jira"
github:
apiBaseUrl: "https://api-gw.corp.example.com/github"

networkPolicies:
enabled: true
allowDNS: true
allowedExternalCIDRs:
- 10.0.0.0/8

This ensures:

  1. All outbound HTTP traffic routes through your proxy (Layer 1)
  2. Each connector's API calls go through your API gateway (Layer 2)
  3. Kubernetes network policy blocks any unexpected egress (defense-in-depth)