Air-gapped
Run Agent Memory with no outbound network access — local models, API-key authentication and a start-up guard that refuses any dependency that would leave the perimeter.
The air-gapped profile runs Agent Memory with no route to the internet: PostgreSQL, Redis, a local OpenAI-compatible model server and the Agent Memory hosts, reachable only through one ingress proxy. The source repository ships it as a reference kit in deploy/airgap/ (compose file, environment template, ingress configuration and an acceptance script).
Two layers of enforcement
- Configuration guard. With
Deployment__AirGapped=true, the hosts refuse to start while any configured dependency would leave the network, and the error lists every offending key. At runtime a tenant cannot route around it either: a tenant's LLM override uses the platform's local endpoint, and a non-OpenAI provider override is ignored. - Network. Every service sits on an internal Docker network with no route out. The only way in is the ingress proxy, the only service attached to a second network, which forwards to the API and nothing else.
What the guard refuses
| Configured | Why |
|---|---|
Stripe__SecretKey, Stripe__WebhookSecret | Billing calls out to Stripe. |
Auth__Google__ClientId | Sign-in redirects to Google. |
Email__Smtp__Password, Email__WebhookSecret | External email relay. |
Ops__SubscriptionId | Cloud operations reads. |
Llm__Provider=anthropic | Calls the Anthropic API. |
Llm__Provider=openai without a local Llm__OpenAI__BaseUrl | Calls the OpenAI API. |
Embedding__Provider=bedrock, or openai without a local Embedding__OpenAI__BaseUrl | Calls AWS or OpenAI. |
Allowed: onnx and hashing embeddings, any OpenAI-compatible base URL you set (Ollama, vLLM, LM Studio, LocalAI) and an OpenTelemetry collector inside the perimeter.
Identity
There is no identity provider to federate to, so the OAuth server stays off (OAuth__Enabled=false) and API keys are the only authentication. The web console's browser sign-in is not available in this profile; agents and operators use keys.
Bring-up
Stage images and models on a connected machine
Pull and docker save the images — pgvector/pgvector:pg17, redis:7-alpine, ollama/ollama, nginx:alpine and your Agent Memory image. Pull the model(s) once into an Ollama volume (ollama pull <model>, plus an embedding model if you use Embedding__Provider=openai). Copy the tarballs and the volume across.
Load and configure on the air-gapped host
docker load the images and restore the Ollama volume. Copy env.template to .env and fill it in. The essential keys:
Deployment__AirGapped=true
IMAGE=agent-memory:1.0
PG_OWNER_USER=postgres
PG_OWNER_PASSWORD=<secret>
APP_RUNTIME_PASSWORD=<secret>
CONTROL_PLANE_PASSWORD=<secret>
ConnectionStrings__SharedDb=Host=postgres;Database=tenant_shared;Username=app_runtime;Password=${APP_RUNTIME_PASSWORD}
ConnectionStrings__SharedDbMigrations=Host=postgres;Database=tenant_shared;Username=${PG_OWNER_USER};Password=${PG_OWNER_PASSWORD}
ConnectionStrings__ControlPlaneDb=Host=postgres;Database=agentmemory;Username=control_plane;Password=${CONTROL_PLANE_PASSWORD}
ConnectionStrings__ControlPlaneDbMigrations=Host=postgres;Database=agentmemory;Username=${PG_OWNER_USER};Password=${PG_OWNER_PASSWORD}
ConnectionStrings__PlatformDb=Host=postgres;Database=agentmemory_platform;Username=app_runtime;Password=${APP_RUNTIME_PASSWORD}
ConnectionStrings__PlatformDbMigrations=Host=postgres;Database=agentmemory_platform;Username=${PG_OWNER_USER};Password=${PG_OWNER_PASSWORD}
ConnectionStrings__Redis=redis:6379
OAuth__Enabled=false
Auth__Dev__Enabled=false
DataProtection__KeyEncryptionCertificate=<base64 PKCS#12> # a self-signed certificate is fine
Llm__Provider=openai
Llm__OpenAI__BaseUrl=http://ollama:11434/v1
Llm__OpenAI__ApiKey=local # any non-empty value; Ollama ignores it
Llm__OpenAI__Model=llama3.1
Embedding__Provider=openai # or onnx / hashing (no model server needed)
Embedding__OpenAI__BaseUrl=http://ollama:11434/v1
OpenAI__ApiKey=local
Embedding__TargetDimensions=1536
Otel__Enabled=falseStart the stack
docker compose -f docker-compose.airgap.yml up -dThe migrate service creates the roles and databases; the API and the worker start only after it succeeds. The ingress publishes the API on 127.0.0.1:5199.
Mint the first key
docker compose -f docker-compose.airgap.yml run --rm --no-deps api \
--bootstrap-key --tenant-name acme --agents support-botThis creates a tenant and a workspace and prints one key — shown once — bound to the named agents and allowed to delete, so erasure is possible with the only credential there is. Each run creates a new tenant.
Check health
curl http://127.0.0.1:5199/health/readyTrade-offs
- Retrieval quality follows your local model. Reranking (in
assistedmode), compression and other LLM features use whateverLlm__OpenAI__Modelis. Token budgets are counted with the cl100k tokenizer, which is within roughly 15% of Llama-family tokenizers. - No email, so no invite or notification mail, and no console sign-in.
- The repository's
acceptance.shrepeats the reference acceptance run on any Docker host (internet is needed only to stage images): it checks start-up, the guard, key minting, retrieval with a local rerank and that egress from every service is blocked.
Configuration
Configuration reference for self-hosted Agent Memory — connection strings, authentication, model providers, limits, background jobs and sign-up.
Operations
Health checks, upgrades, backups and restores, erasure replay, embedding model changes and other maintenance for self-hosted Agent Memory.