Skip to content

AKS Architecture ​

This page describes the checked-in AKS deployment, not an attestation of a live cluster. For provisioning and deployment commands, see Deploy to AKS.

Deployed components ​

The application Gateway routes to Frontend, API, and MCP Services. Worker is a background control-plane workload, not another public Gateway backend. Its configured floor is two replicas; the HPA permits two to three using CPU 70% and memory 80%. API and Worker both read and write the same EF-backed PostgreSQL stores and use the shared workspace PVC. API/Worker use the privileged control-plane identity; AgentHost has a separate identity without Key Vault roles, and MCP mounts no secrets.

Preview browser traffic uses a separate preview Gateway, not the application Gateway or an API reverse proxy. The network diagram and credential diagram below show these boundaries.

AgentHost warm-pool lifecycle ​

Worker runs in pod-per-run: coordinator children execute in AgentHost pods rather than in-process on Worker. The shared agentweaver-agent-host warm pool keeps two pods pre-warmed (k8s/base/sandbox-warmpool-agenthost.yaml).

Warm pods boot without a RunId and enter standby. The executor creates a claim, persists its identity, and waits for pod binding. It probes /healthz for HTTP reachability: standby also returns 200. One-time POST /configure supplies run identity, bounded credentials, purpose, and the workspace contract. Successful configuration completes setup and marks IsReady before returning. A2A traffic is gated by that ready state; there is no second post-configuration health poll.

Before the first A2A request, dispatch is fenced to the run lifecycle generation, project, submitting user, agent, accepted provider snapshot, and an opaque dispatch identifier. Concurrent callers join the same launch. Readiness, configuration, or endpoint failure can replace the claim once while delivery is still known not to have started; after the streaming request begins, Agentweaver never replays the turn. A stale launch cannot satisfy a newer generation. Exhaustion records one retryable, credential-redacted agent_host_unavailable terminal outcome for that dispatch.

Shared execution uses /workspace. Assembly Build/Test uses LocalReadOnly: fetch an immutable source ref, verify base commit and tree, and check out detached into the disk-backed /local-workspace emptyDir. Its preview uses the same verified checkout. This mode forbids write-back, not local build output. Current Worker configuration also enables pod-local implementation work; it is not just a future seam. Assistant-purpose setup skips project checkout and ordinary agent setup.

The first valid /configure atomically binds the pod before setup finishes. Later valid attempts return 409, including after setup failure. Configuration cannot require the turn bearer it delivers; subsequent streamed turns require that per-run bearer. Network reachability and production mTLS are separate controls: the preview Gateway's allowed port range also includes 8088.

A successful Assistant turn retains its configured pod and renews MCP authorization separately for later turns. Failure/cancellation releases it. Ordinary release deletes the claim and revokes/unregisters run capabilities; an active preview can defer cleanup. Turn completion therefore does not always mean claim deletion.

The executor uses AgentHostWarmPoolRef (default agentweaver-agent-host), not per-run templates or warm pools. Grounding: KubernetesSandboxExecutor.cs claim/configuration and release paths, AgentHostReadinessProbe.cs, AgentHostStartupService.cs, and RemoteOperatorAssistantAgent.cs; detailed citations accompany the diagram review.

Networking flow ​

Inbound request path ​

Both TLS Gateways listen on 443 using approuting-istio. Each Gateway → HTTPRoute → Service → pod chain is explicit. API manages preview resources but is not a browser traffic hop. Exact paths and longer prefixes win over the frontend / catch-all.

RouteMatchesService → pod
APIPrefix /api, /auth, /openapi; exact /.well-known/oauth-authorization-server, /.well-known/openid-configuration, /oauth/authorize, /oauth/token, /oauth/register, /oauth/resume, /oauth/revoke, /oauth/jwksagentweaver-api:8080 → API:8080
MCPPrefix /mcp; exact /.well-known/oauth-protected-resource and /.well-known/oauth-protected-resource/mcpagentweaver-mcp:8080 → MCP:8080
MCP healthExact /mcp/health, rewritten to /healthzagentweaver-mcp:8080 → MCP:8080
FrontendPrefix /agentweaver-frontend:80 → Frontend:8080
PreviewDynamic {token}-preview.{zone} hostname on the separate Gateway; upstream hostname rewritten to localhostpreview-{token}:80 → run-labeled AgentHost target port

There is no blanket /oauth prefix route. The same diagram covers the effective policy boundaries below; a second traffic diagram is unnecessary.

Security model ​

Network security — Cilium NetworkPolicy ​

The cluster uses Azure CNI Overlay and Cilium (--network-dataplane cilium). Application Routing uses an Istio-based gateway data plane; this does not mean workload pods have Istio sidecars or an ambient service mesh.

NetworkPolicy rules ​

BoundarySelector / permitted sourceEffect
Application ingressApplication Gateway pods or aks-istio-ingress namespaceAPI, MCP, Frontend pod TCP 8080
Application egressAPI, MCP, FrontendDeny by default, with explicit DNS/internal/external rules
AgentHost defaultapp=agentweaver-agent-hostDeny ingress except additive allows
A2A ingressSame-namespace API or Worker podsTCP 8088 to AgentHost
Preview ingressSame-namespace pods labeled gateway.networking.k8s.io/gateway-name=agentweaver-preview-gatewayTCP 3000–9000 inclusive to AgentHost
AgentHost internal egressDestination app=agentweaver-api or app=agentweaver-mcpTCP 8080 using pod selectors
AgentHost DNSkube-system + k8s-app=kube-dns, or 10.0.0.10/32UDP/TCP 53
AgentHost public-address HTTPSIPv4/IPv6 CIDR rules belowTCP 443, not a GitHub-only CIDR

Sandbox isolation ​

The selected policies are additive allows, not intersecting restrictions. The preview range includes 8088, so network policy does not make API/Worker the only sources able to reach the A2A listener. Production mTLS/client-certificate authentication is a separate control.

API ingress requires both app=agentweaver-agent-host and agentweaver.dev/sandbox=true; MCP ingress requires app.kubernetes.io/component=agent-host. The template carries these labels. Destination pod selectors permit API/MCP access without granting broad private network access. Under the documented Cilium path, CIDR/world permission does not replace cluster-pod identity permission.

Public-address HTTPS permits 0.0.0.0/0 except 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16, and ::/0 except fc00::/7, fe80::/10. These are the actual exclusions, not every nonpublic range: 100.64.0.0/10 is not listed. The manifests document the Kata DNS-hook limitation and explicit IP/port fallback. A narrower-looking FQDN policy does not make this effective union FQDN-only. HTTPS reachability does not grant Key Vault authorization.

Agent execution uses Kata VM-isolated pods (runtimeClassName: kata-vm-isolation) claimed through SandboxClaim (extensions.agents.x-k8s.io/v1beta1). The in-cluster API selects KubernetesSandboxExecutor when KUBERNETES_SERVICE_HOST is present. See Sandbox verification.

Non-root containers ​

API and Frontend run as UID 1000 with runAsNonRoot: true and dropped capabilities. API also sets allowPrivilegeEscalation: false.

Secrets management ​

Azure Workload Identity lets API/Worker use Key Vault without embedded Azure credentials. The trusted control-plane broker redeems a run's purpose-bound capability snapshot and fences authority before and after retrieval. It supplies copilotCredential through one-time /configure, or supplies the selected BYOK configuration. Repository credentials, A2A turn tokens, and Assistant MCP tokens remain separate. AgentHost does not resolve an ambient user's token or read Key Vault.

API and Worker ServiceAccounts federate through AKS OIDC to agentweaver-api-identity, which has Key Vault Secrets User and Secrets Officer grants. Their Kubernetes RBAC remains distinct; Worker does not inherit API preview-management permissions. agentweaver-agent-host federates to agentweaver-agenthost-identity, with no Key Vault roles. Provisioning removes its legacy federation to the privileged identity. The broker is trusted API/Worker application code, not a separate public service.

One static SecretProviderClass, agentweaver-secrets, configures CSI app-secret delivery for API and Worker. It is not the vault itself. It mounts files and syncs a Kubernetes Secret. The manifest includes the internal API key, provider-key signing key, telemetry connection string, and Repo/Copilot App configuration.

ValueConsumption
mcp-api-keyStartup wrapper reads /mnt/secrets-store/mcp-api-key for internal API authentication; not a hosted MCP bearer key
ai-execution-provider-key-signing-keySynchronized Kubernetes secretKeyRef supplies AiExecution__ProviderKeySigningKey
OAuth signing/encryption certificate familiesAPI runtime SecretClient loads usable Key Vault versions with active/previous overlap; not CSI delivery

The CSI mount triggers synchronization; do not describe all values as file-only. MCP mounts no secrets and accepts only Agentweaver-minted broker JWTs for the exact /mcp audience and mcp:invoke scope. Worker does not host the API OAuth certificate loading path.

CSI app-secret rotation polling is two minutes. Create the provider-key signing key once with high-entropy material and rotate only with a coordinated API rollout: serving replicas must agree, and rotation invalidates prepared execution contexts. AgentHost receives no OAuth-client-secret mount. See Configuration for credential import, migration, and recovery procedures.

Authentication ​

Microsoft Entra ID provides browser identity; end users are not issued API keys.

  1. The user selects Sign in with Microsoft Entra ID.
  2. API redirects to the configured Entra application.
  3. Entra returns to https://<host>/auth/entra/callback; API establishes platform identity and roles.
  4. Repository discovery and GitHub project creation use a separate Repo App handoff and opaque selection code.
  5. Model access follows the project versus personal provider hierarchy.

The renderer derives Auth__Entra__RedirectUri and Auth__Entra__FrontendUrl from the public host, without localhost fallback. Register the exact callback under the Entra app's publicClient platform; npm run azure:setup-entra-app -- --redirect-uri https://<host>/auth/entra/callback prepares registration. Do not change a production identity registration without its owner's approval.

MCP authentication ​

MCP forwards authorized caller context to API at http://agentweaver-api:8080. MCP OAuth, repository authorization, and model capabilities are separate boundaries. See MCP connection and Authentication.

External dependencies ​

ServicePurposeBoundary
GitHub APIsApp capability and permitted repository operationsControl-plane HTTPS; AgentHost public-address HTTPS is not FQDN-only
GitHub browser originRepo/Copilot consent handoffsBrowser connectivity, not pod network authorization
Azure Key VaultCSI and trusted runtime credentials/certificatesReachability plus privileged workload identity; no AgentHost vault grant
Azure Container RegistryImage pullsKubelet/cluster ACR authorization, not pod credential delivery
PostgreSQLDurable application stateTCP 5432; private subnet or rendered public-access FQDN policy according to deployment
Telemetry endpointMonitoring exportDeployment-specific telemetry configuration; see Operations

Storage model ​

PostgreSQL (primary data store) ​

API and Worker use EF-backed application stores via MemoryDbContext, including projects, runs, revisions, workflow state, memory, decisions, OAuth state, and durable events. This is neither an API-read/Worker-write split nor a production Dapper/EF partition. Provisioning stores connection configuration in agentweaver-postgres, not in images.

Connection string keyPrecedenceUsed by
ConnectionStrings__PostgresFirstShared EF stores
ConnectionStrings__MemoryDbFallbackSame EF stores
Database__ConnectionStringFinal fallbackSame EF stores

PostgreSQL supports multiple API replicas with RollingUpdate, without SQLite's single-writer deployment constraint.

Workspace volume ​

The shared agentweaver-workspace PVC is 50 GiB RWX Azure Files, with StorageClass azurefile-csi-premium-uid1000, mounted at /workspace. AgentHost separately mounts an 8 GiB disk-backed execution-scratch emptyDir at /local-workspace; it is not durable shared state.

text
PVC: agentweaver-workspace (Azure Files, RWX)
  storageClass: azurefile-csi-premium-uid1000
  mountPath: /workspace
  |
  +-- .home/                (shared app/runtime state; no GitHub token mirror)
  +-- worktrees/            (git worktrees per run)
  +-- <project workspaces>  (project working directories)

EF Core migrations ​

API and Worker init containers (migrate-memory-db) run /app/efbundle --verbose -- --postgres-migrations before their main containers start. They use the API image and injected ConnectionStrings__MemoryDb / ConnectionStrings__Postgres from agentweaver-postgres. No connection string is embedded in the image or manifest. Local design-time commands default to SQLite; use --postgres-migrations only with configured PostgreSQL credentials.

For release-candidate acceptance, deploy the committed candidate with npm run azure:deploy-from-commit -- <candidate-sha> and run representative integration plus feature-specific API/UI tests against that exact-SHA deployment before preparing or publishing the release. See RELEASING.md.

Ephemeral storage for testing ​

For throwaway SQLite testing, set Database__Provider=Sqlite and replace the shared workspace volume with:

yaml
volumes:
  - name: workspace
    emptyDir: {}

Data is lost on pod restart. SQLite requires one replica and Recreate strategy to avoid write contention; this is not a production storage migration procedure.

Diagram details and constraints
ElementContract
titleAKS network: two ingress planes
takeawayRoutes select Services; additive policies bound AgentHost access, not a vault credential path.
n-app-titleAPPLICATION ORIGIN • EXACT MATCHES / LONGER PREFIXES BEAT /
n-preview-titlePREVIEW ORIGIN • API MANAGES RESOURCES, NOT BROWSER TRAFFIC
n-egress-titleEFFECTIVE AGENTHOST POLICY UNION
ClientClient
ClientBrowser / MCP
ClientPublic app origin
App GatewayApp Gateway
App Gatewayagentweaver-gateway
App GatewayTLS :443
HTTPRoutesHTTPRoutes
HTTPRoutesAPI / MCP / /
HTTPRoutesExact OAuth routes below
ServicesServices
ServicesAPI/MCP :8080
ServicesFrontend :80
App podsApp pods
App podsAPI / MCP / web
App podsAll target :8080
BrowserBrowser
Browser{token}-preview
BrowserSeparate hostname
Preview GWPreview GW
Preview GWpreview-gateway
HTTPRouteHTTPRoute
HTTPRoutepreview-{token}
HTTPRouteHost rewrite: localhost
ServiceService
Servicepreview-{token}:80
ServiceRun-label selector
AgentHostAgentHost
AgentHostPreview target port
AgentHostGateway: 3000–9000
API / MCPAPI / MCP
API / MCPSelector-based TCP 8080
API / MCPDNS: UDP/TCP 53 separately
Public HTTPSPublic HTTPS
Public HTTPSTCP 443, IPv4 + IPv6
Public HTTPSPrivate/link-local exclusions
Additive allowsAdditive allows
Additive allowsAPI/Worker → A2A :8088
Additive allowsPreview range includes 8088
n-internalTCP 8080
n-publicTCP 443
n-routes-headingAPP ROUTES
n-routes-bodyAPI: /api, /auth, /openapi + exact OAuth/discovery. MCP: /mcp + resource metadata; /mcp/health → /healthz.
n-exclusions-headingEGRESS EXCLUSIONS
n-exclusions-body10/8, 172.16/12, 192.168/16, 169.254/16; fc00::/7, fe80::/10. Not FQDN-only; no vault authority implied.
notes[object Object]; [object Object]
groups[object Object]; [object Object]; [object Object]
Diagram details and constraints
ElementContract
titleAgentHost: bind once, serve ready
takeawayHTTP reachability is not setup readiness; claim lifetime can span Assistant turns.
l-launch-title01 CONTROL-PLANE LAUNCH
l-setup-title02 PURPOSE-BOUND SETUP
l-turns-title03 TURN AND CLAIM LIFETIME
Claim warm podClaim warm pod
Claim warm podPersist claim; wait for binding
Claim warm podShared pool: 2 warm pods
Probe listenerProbe listener
Probe listener/healthz success: reachable
Probe listener200 can mean standby
Configure onceConfigure once
Configure onceRun, purpose and capabilities
Configure oncePOST /configure
Select workspaceSelect workspace
Select workspaceShared or verified local checkout
Select workspaceLocalReadOnly: no write-back
Finish setupFinish setup
Finish setupAssistant skips project checkout
Finish setupAccepted binding stays consumed
Ready for A2AReady for A2A
Ready for A2ASetup finished before response
Ready for A2AIsReady gates traffic
Stream a turnStream a turn
Stream a turnRun-bound bearer authentication
Stream a turnmessage:stream
Retain AssistantRetain Assistant
Retain AssistantSuccessful turn keeps its pod
Retain AssistantRenew MCP token, not configure
Release claimRelease claim
Release claimUnregister and revoke capabilities
Release claimActive preview defers cleanup
l1bound
l2reachable
l3accepted
l4prepare
l5complete
l6dispatch
l7success
l8next turn
l9run ends / failure
l-409-headingCONFIGURATION BOUNDARY
l-409-bodyLater valid configure attempts return 409, even after accepted setup fails.
notes[object Object]
groups[object Object]; [object Object]; [object Object]
Diagram details and constraints
ElementContract
titleCredentials: authority stays in the control plane
takeawaySeparate Azure identities; separate Copilot, repository, turn and MCP capabilities.
s-control-titleTRUSTED CONTROL PLANE
s-host-titleISOLATED AGENTHOST
s-delivery-titleDISTINCT DELIVERY CHANNELS
API + Worker SAsAPI + Worker SAs
API + Worker SAsSeparate Kubernetes RBAC
API + Worker SAsAKS OIDC federation
API managed identityAPI managed identity
API managed identitySecrets User + Secrets Officer
API managed identityagentweaver-api-identity
Azure Key VaultAzure Key Vault
Azure Key VaultCredential and app-secret authority
Azure Key VaultRuntime and CSI consumers
Capability brokerCapability broker
Capability brokerFence run + purpose before/after read
Capability brokerNo ambient user-token lookup
AgentHost identityAgentHost identity
AgentHost identitySeparate ServiceAccount federation
AgentHost identityNo Key Vault role assignments
AgentHost runtimeAgentHost runtime
AgentHost runtimeOne-time /configure delivery
AgentHost runtimeCopilot or BYOK; repo separate
CSI app secretsCSI app secrets
CSI app secretsSecretProviderClass configuration
CSI app secretsFiles + synced secretKeyRef
OAuth certificatesOAuth certificates
OAuth certificatesAPI runtime SecretClient
OAuth certificatesUsable active / previous versions
MCP resource serverMCP resource server
MCP resource serverAgentweaver broker JWT only
MCP resource serverExact /mcp + mcp:invoke
s1federate
s2authorize
s3credential
s4configure
s5pod identity
s6app secrets
s7cert versions
s8Assistant JWT
s-separation-headingNO AGENTHOST → VAULT EDGE
s-separation-bodyNetwork reachability is not authorization. Repository, A2A and MCP tokens are not Copilot credentials.
notes[object Object]
groups[object Object]; [object Object]; [object Object]

Visual model ​

AKS deployment ​

Deployment view showing Azure Kubernetes Service, application and preview gateways, API, worker, MCP, and frontend deployments, Sandbox custom resources and Kata AgentHost pods, PostgreSQL, Azure Files, Key Vault, managed identities, and observability.

Structured source · Editable draw.io