Self-Hosting & Deployment

The backend's container image, required external services, and the full environment-variable configuration surface for operators running their own instance.

This page documents what the ArmorIQ backend actually needs to run - its container image, its external dependencies, and its full environment-variable surface - so you can host it on your own infrastructure. It does not describe a specific Docker Compose or Kubernetes setup, because the backend repository does not ship one.

ArmorIQ's own hosted deployment runs on Google Cloud Run, built and migrated through Cloud Build. There is no production docker-compose.yml or Kubernetes manifest in the backend repository - only a Dockerfile and a local-development Docker Compose file for running OPA alongside Postgres during development. If you self-host, you are responsible for your own container orchestration, TLS termination, and secret management around the image and environment variables described below.

Container image

The backend ships a two-stage Dockerfile: a build stage that installs dependencies, generates the Prisma client, and compiles the NestJS app, and a slim runtime stage that copies only the compiled output and production dependencies. The runtime image:

  • listens on port 8080 (PORT env var, defaults to 8080),
  • runs as a non-root user,
  • starts with node dist/main.js,
  • does not run database migrations on startup - migrations (prisma migrate deploy) are expected to run as a separate step before you deploy a new image, against a Prisma-CLI-capable build (the runtime image strips dev dependencies including the Prisma CLI).

No global route prefix is set - routes are served directly at the paths documented in the API Reference, and Swagger UI is available at /api-docs outside production.

Required external services

ServiceWhy it's required
PostgreSQLPrimary datastore via DATABASE_URL. Prisma manages the schema.
An OPA (Open Policy Agent) Policy Decision PointPolicy evaluation calls out to OPA_PDP_URL; the backend throws if this isn't configured when OPA evaluation is invoked. ArmorIQ's own deployment runs OPA as a sidecar container next to the backend; local development runs it via Docker Compose instead.
A Google Cloud projectUsed for Cloud KMS (encrypting certificate private keys and other secrets at rest) and Certificate Authority Service (issuing certificates). Not required if you don't use the certificate feature.
SMTPTransactional email - OTP verification, password reset, invitations.

Two more services are optional depending on which features you enable: a CSRG service for building Merkle-verified reasoning graphs on intent plans, and a PAP gateway service for the pre-flight plan-refinement step described in Plans Governance.

Environment variables

These are grouped by the concern they configure. Values shown are the shipped example defaults, not requirements - set real values for anything you run in production.

Core

VariableDefaultNotes
PORT3000Container listens on 8080 in the shipped image
NODE_ENVdevelopment
APP_ENVlocallocal | dev | staging | prod
APP_NAMEArmorIQ
FRONTEND_URL-Dashboard origin, used in emails and redirects
CORS_ORIGIN-Allowed origin for browser requests
CONMAP_AUTO_URL / CONMAP_AUTO_INTERNAL_URL-The backend's own public and internal URLs
CONMAP_AUTO_API_KEY-Internal service-to-service key
CONMAP_SCANNER_URL-URL of the separate MCP-scanning service used by Quick Scan and server scans
NODE_TLS_REJECT_UNAUTHORIZED1Set to 0 only for local self-signed TLS; never in production

Database

VariableNotes
DATABASE_URLRequired. Postgres connection string.
PGSSLMODEOptional libpq SSL mode, e.g. require for a managed Postgres instance.

Authentication and secrets

VariableNotes
JWT_SECRETRequired. Signs dashboard session JWTs.
ENCRYPTION_KEYRequired. 64-hex-char symmetric key for encrypting secrets at rest.
PROXY_JWT_SECRET, PROXY_SECRETRequired if you run the separate enforcement proxy - shared secrets between it and the backend.
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_CALLBACK_URLOptional, enables Google OAuth sign-in.
GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, GITHUB_CALLBACK_URLOptional, enables GitHub OAuth sign-in.
ALLOW_SELF_APPROVALfalse by default. Allows a user to approve their own delegation request from the dashboard - see the caveat in Plans Governance.

Delegation and IAP

VariableDefaultNotes
DELEGATION_EXPIRY_SECONDS3600How long an unapproved delegation request stays valid
IAP_MAX_DEFERRAL_DEPTH3Max nested deferrals before an intent plan is auto-blocked
IAP_JWT_SECRET-Legacy HS256 signing secret for intent tokens; kept for verify-only backward compatibility
IAP_TOKEN_ED25519_PRIVATE_KEY-PKCS#8 Ed25519 private key (PEM or base64) for signing intent tokens - see How It Works
IAP_TOKEN_ED25519_PUBLIC_KEY-SPKI Ed25519 public key (PEM or base64); also served unauthenticated at GET /iap/public-key

OPA policy engine

VariableDefaultNotes
OPA_PDP_URLhttp://localhost:8181Required if OPA evaluation is enabled
OPA_ENFORCE_MODEstrictstrict | permissive
OPA_SHADOW_MODEfalseLog-only, does not enforce
OPA_COMPILATION_ENABLEDfalse
OPA_TIMEOUT_MS / EXTERNAL_OPA_TIMEOUT_MS5000 / 10000
OPA_BUNDLE_GCS_BUCKET, OPA_BUNDLE_PUBLISH_DIR-Optional, for publishing compiled OPA bundles

GCP (certificates and KMS)

VariableNotes
GCP_PROJECT_ID, GCP_LOCATION_IDProject and region ArmorIQ uses for IAP's KMS key lookups
GOOGLE_APPLICATION_CREDENTIALSPath to a service-account JSON credential
CERT_KMS_KEY_NAMENot present in the shipped .env.example - set this yourself to encrypt certificate private keys at rest. See Certificates.

CSRG / reasoning-graph service

VariableDefaultNotes
CSRG_ENABLED, CSRG_IAP_ENABLEDfalseEnable the CSRG-backed reasoning graph and intent token
CSRG_IAP_REQUIREDfalseReject requests that lack a valid CSRG-issued token
CSRG_IAP_URLhttp://localhost:8771CSRG service URL
CSRG_IAP_TIMEOUT_MS5000

PAP gateway

VariableDefaultNotes
PAP_GATEWAY_URLhttp://127.0.0.1:8770Forwards the plan pre-flight refinement step to a separate PAP gateway service
PAP_GATEWAY_API_KEY-Auth for that service

Email (SMTP)

VariableNotes
SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, SMTP_FROMOutbound mail transport
SUPPORT_EMAILDisplayed as the support contact
EMAIL_SECRET_KEY64-hex-char secret for signing action links in emails

Other

VariableDefaultNotes
OBLIGATION_STORE_BACKENDmemoryA Redis backend is referenced as planned but not implemented
OBLIGATION_STORE_TTL_SECONDS3600
TRUST_BROADCAST_ENABLED, TRUST_NOTIFY_CHANNELfalseOptional trust-delta broadcast channel
AUDIT_DRIFT_WORKER_ENABLED, AUDIT_DRIFT_WORKER_INTERVAL_MS, AUDIT_DRIFT_WORKER_BATCHfalse / 60000 / 100Background audit-consistency worker
HYBRID_TOKEN_ENABLED, HYBRID_TOKEN_WRITE_THROUGHfalseDual JWT + API-key token mode
AIQGRAPH_BACKEND_URL-Data source the AIQraph feature reads from - normally the backend's own URL
DEFAULT_MCP_TARGET_URL, SMITHERY_API_KEY-Optional MCP tool-discovery configuration
LLM_PROVIDER, LLM_MODEL, ANTHROPIC_API_KEY, OPENAI_API_KEY-Model provider for AI-assisted policy drafting and AIQraph chat

Set all of these as real environment variables or secrets in your own infrastructure - ArmorIQ's own deployment injects them through Google Secret Manager rather than shipping an .env file to production.

On this page