Skip to content

Environment Variables ​

All environment variables can be set in your shell, a .env file (loaded by python-dotenv if installed), or as Docker -e / Compose environment: entries.

Core server ​

VariableDefaultRequiredDescription
P8G_JWT_SECRETinsecure dev defaultYes (production)JWT signing secret — generate with python -c "import secrets; print(secrets.token_hex(32))". The server logs a warning and refuses to start in P8G_ENV=production with the default secret.
P8G_ADMIN_EMAIL—YesBootstrap admin email (used on first start to create the initial admin user)
P8G_ADMIN_PASSWORD—YesBootstrap admin password
P8G_ADMIN_USERNAME—NoBootstrap admin username (defaults derived from email if unset)
P8G_HOST0.0.0.0NoInterface the REST server binds to
P8G_PORT8000NoTCP port (the serve CLI subcommand and Docker images default to 8100 instead — check your entry point)
P8G_DATA_PATH./dataNoRoot directory for graph storage, licensing state, and CDC journal
WORKERS4 (via production.py) / unset (via secure_server.py, which defaults to core-count heuristics)NoNumber of Uvicorn worker processes. P8G_ALLOW_MULTI_WORKER=1 required to run more than 4
LOG_LEVELinfoNodebug / info / warning / error
P8G_CORS_ORIGINS*NoComma-separated list of allowed CORS origins
P8G_ENV—Nodevelopment / production / staging — gates dev-only conveniences (insecure default secret, verbose errors)
P8G_READONLY0No1 = start this instance as a read replica (rejects writes)

P8G_JWT_SECRET

Never use a short or guessable secret in production. Generate one with:

bash
python -c "import secrets; print(secrets.token_hex(32))"

LLM / embedding provider configuration ​

LLM and embedding providers are configured at runtime via PUT /rag/config, not via environment variables. The 39-model LLM registry and 21-model embedding registry (RAG Studio) are swapped live with no restart — see the RAG Studio guide. There is no LLM_PROVIDER / LLM_MODEL / ANTHROPIC_API_KEY / GOOGLE_API_KEY env-var scheme in this codebase.

A few narrow env vars remain as fallbacks/managed-proxy options, not the primary configuration path:

VariableDefaultDescription
OPENAI_API_KEY—Fallback key used by a small number of code paths (journey AI advisor, late chunking) when no per-request/per-config key is supplied
PURPLE8_OPENAI_KEY—Alternate OpenAI key override consulted by the RAG router
PURPLE8_MANAGED_LLM_KEY / PURPLE8_MANAGED_LLM_MODEL— / gpt-5.4-miniPurple8-managed LLM proxy credentials (used only when the managed-LLM feature is enabled)

Vector index ​

VariableDefaultDescription
P8G_EMBEDDING_DIMENSION1536Embedding vector dimension — must match your embedding model. Used as the fallback when not set explicitly on GraphEngine(embedding_dimension=...)
P8G_HNSW_M16HNSW M parameter — higher = better recall, more RAM
P8G_HNSW_EF_CONSTRUCTION100 (segmented engine index) / 200 (standalone VectorIndex)Build-time recall quality (higher = slower build, better index)
P8G_HNSW_SEARCH_WORKERSautoUpper bound on parallel segment workers (logical CPUs, capped at 32). Native hnswlib searches with Python eligibility predicates run segments inline to avoid callback contention; unfiltered and other-backend searches retain parallel fan-out. A limit of 1 runs inline without an executor.
P8G_HNSW_SEGMENT_SIZE50000Nodes per HNSW segment before a new segment is sealed
P8G_HNSW_MAX_HOT_SEGShardware-derivedMax segments kept hot in memory before NVMe tiering seals them
P8G_HNSW_STORAGE_PATH—Optional separate storage path for sealed (cold) HNSW segments
P8G_VECTOR_QUANTIZATIONoffSet to enable int8/binary quantization mode
P8G_VECTOR_BACKENDhnswlibVector index backend selector
AUTO_CONFIGn/aThere is no AUTO_CONFIG env var — pass GraphEngine(..., auto_config=True) in code instead. See Architecture for CortexAutoConfig.

CortexAutoConfig

GraphEngine(..., auto_config=True) enables CortexAutoConfig, which probes available RAM at startup and derives (M, ef_construction, segment_size, batch_size) such that peak process RSS never exceeds ~75% of available RAM. This is a constructor argument, not an environment variable — set it in your GraphEngine(...) call.

Construction settings are read when a new index is created, not when the vector module is imported. Auto-config overrides the environment for new indexes; explicit vector-index constructor arguments take precedence over environment settings. Loading an existing index retains its saved construction settings: changing M or ef_construction requires rebuilding the index to affect existing vectors. Hardware sizing is not a measured recall guarantee; validate retrieval quality on representative queries separately.

KMS / Encryption at rest ​

VariableRequiredDescription
KMS_PROVIDERWhen encryptinglocal | vault | aws | gcp | azure
KMS_KEY_IDWhen provider is externalProvider-specific key identifier
KMS_LOCAL_KEYSTORENo (local provider)Path to the local keystore directory (default: ./data/kms)
VAULT_ADDRVaultHashiCorp Vault server URL (default: http://127.0.0.1:8200)
VAULT_TOKENVaultVault token
VAULT_MOUNTNoVault transit engine mount path (default: transit)
AWS_DEFAULT_REGIONAWSAWS region (e.g. us-east-1) — not AWS_REGION
AWS_KMS_ENDPOINTNoOverride KMS endpoint (e.g. for LocalStack testing)
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEYAWS (key auth)Standard AWS SDK credential vars — falls back to IAM role/instance profile if unset
GCP_PROJECTGCPGCP project ID
GCP_KMS_LOCATIONNoKMS key ring location (default: global)
GCP_KMS_KEYRINGNoKMS key ring name (default: purple8)
GOOGLE_APPLICATION_CREDENTIALSGCPStandard Google Cloud SDK var — path to service account JSON, read implicitly by the google-cloud client library
AZURE_VAULT_URLAzureAzure Key Vault URL
AZURE_TENANT_ID / AZURE_CLIENT_ID / AZURE_CLIENT_SECRETAzure (SP auth)Standard azure-identity SDK vars, read implicitly by DefaultAzureCredential — not read directly by Purple8 code

Multi-tenancy, write admission & backups (Six-Sigma operational controls) ​

Tenancy mode (shared key-prefix vs. dedicated per-tenant storage path) is configured programmatically through tenancy.py / the admin REST API. The following operational environment variables control sharding, write-admission safety gates, and streaming backup archives:

VariableDefaultDescription
P8G_SHARD_COUNT1Number of horizontal shards for tenant data distribution
P8G_WRITE_ADMISSION_LANES4Concurrent write-admission lanes
P8G_WRITE_ADMISSION_RSS_LIMIT_MB0.85 × available_ramMaximum process RSS (in MB) before the write admission controller rejects incoming writes with 503 + Retry-After
P8G_WRITE_ADMISSION_DISK_MAX_PCT95.0Six-Sigma disk high-watermark gate: rejects writes before the underlying storage volume hits ENOSPC (default 95.0%; set 0 to disable)
P8G_BACKUP_MAX_ARCHIVE_MB2048Six-Sigma restore safety ceiling: maximum backup archive size in MB accepted during restore_backup (default 2048 MB; raises ValueError if exceeded)
P8G_BACKUP_JSONL0Six-Sigma streaming backup mode: set P8G_BACKUP_JSONL=1 to write and restore backup archives line-by-line in streaming JSONL format without materializing a monolithic JSON payload in RAM

Online Storage Scrub

In addition to backup and write-admission controls, operators can trigger an online, non-destructive bit-rot and CRC32 integrity verification across BrickWAL frames and cold BrickCoreStorage slabs via POST /admin/storage/scrub.

DocIntel integration ​

VariableDefaultDescription
PURPLE8_DOCINTEL_URL—URL of the Purple8 DocIntel service (e.g. http://localhost:8200)
PURPLE8_DOCINTEL_KEY—API key for the DocIntel service
PURPLE8_DOCINTEL_URL_{SUFFIX} / PURPLE8_DOCINTEL_KEY_{SUFFIX}—Per-suffix overrides for multi-instance DocIntel routing

WAL / durability ​

There is no P8G_WAL_SYNC toggle — WAL fdatasync is unconditional (durability-by-default; see the Architecture guide on the Cortex seal-and-evict cycle). The tunables that do exist:

VariableDefaultDescription
P8G_WAL_DIR_FSYNC_INTERVAL64How often (in writes) the containing directory itself is fsync'd
P8G_WAL_CHECKPOINT_RECORDS1000000WAL record count between checkpoints
P8G_WAL_REJECT_NFS01 = refuse to start if the data path is on an NFS mount (NFS does not guarantee fdatasync semantics)

JWT / auth token TTL ​

There are no JWT_ACCESS_TOKEN_EXPIRE_MINUTES / JWT_REFRESH_TOKEN_EXPIRE_DAYS environment variables in the current codebase — token TTLs are fixed in code, not environment-configurable today.

OpenTelemetry (optional) ​

VariableDefaultDescription
OTEL_EXPORTER_OTLP_ENDPOINT—OTLP endpoint (e.g. http://jaeger:4317) — enables tracing when set
OTEL_SERVICE_NAMEpurple8-hyper-graphService name reported to the OTEL collector

Alerting (optional) ​

VariableDefaultDescription
P8G_ALERT_MIN_LEVELERRORMinimum severity that triggers an alert dispatch
P8G_SLACK_WEBHOOK_URL—Slack incoming webhook URL
P8G_PD_KEY—PagerDuty integration key
P8G_OG_KEY / P8G_OG_TEAM—OpsGenie API key / team
P8G_ALERT_WEBHOOK_URL—Generic webhook fallback

Replication (optional) ​

VariableDefaultDescription
P8G_REPLICATION_ROLEstandalonestandalone | primary | follower
P8G_REPLICATION_MODEasyncasync | sync
P8G_PRIMARY_HOST / P8G_PRIMARY_PORT— / 8101Primary node address (follower config)
P8G_FOLLOWER_ADDRESSES—Comma-separated follower addresses (primary config)
P8G_REPLICATION_SYNC_REPLICAS1Number of replicas that must ack before a sync write returns
P8G_REPLICATION_AUTH_TOKEN—Shared auth token between primary and followers. Also authorises automated POST /replication/promote via the X-Replication-Token header
P8G_REPLICATION_TLS0Set to 1 for active replication; authentication and TLS are required unless the explicit loopback development exception applies
P8G_REPLICATION_BIND_HOST127.0.0.1Primary listener address; explicitly configure a network interface for cross-host replication
P8G_REPLICATION_TLS_CERT / P8G_REPLICATION_TLS_KEY—Server certificate and key; configure on followers that may be promoted too
P8G_REPLICATION_TLS_CASystem trust storeCA bundle for follower certificate verification and automated HTTPS promotion
P8G_REPLICATION_ALLOW_INSECURE_LOCAL0Explicit plaintext/tokenless WAL development exception; requires P8G_ENV=development and loopback binding/primary destination. Never permits insecure cross-host replication

Automated failover (follower nodes, optional) ​

VariableDefaultDescription
P8G_FAILOVER_ENABLED01 = run the failover watchdog on this follower. Ignored on primary/standalone
P8G_FAILOVER_PRIMARY_ADDRESSP8G_PRIMARY_HOST:P8G_FAILOVER_HTTP_PORTPrimary HTTP address (host:port) probed at /health
P8G_FAILOVER_HTTP_PORTP8G_PORT or 8080HTTP port used when deriving addresses
P8G_NODE_ADDRESS<hostname>:portThis node's HTTP address; the promote call is sent here
P8G_NODE_IDhostnameRegistry member ID for this node
P8G_FAILOVER_PRIMARY_IDprimary@<address>Registry member ID for the primary
P8G_FAILOVER_UNHEALTHY_THRESHOLD3Consecutive failed probes before promotion
P8G_FAILOVER_INTERVAL_S5Seconds between probes
P8G_FAILOVER_PROBE_TIMEOUT_S3Per-probe HTTP timeout
P8G_FAILOVER_COOLDOWN_S60Minimum seconds between two failovers
P8G_FAILOVER_STARTUP_GRACE_S300Probe failures are not counted until the primary has been seen healthy once, or this many seconds have elapsed since the watchdog started. Prevents a follower from promoting itself against a primary that is merely still booting (image pull, WAL replay). 0 disables the gate
P8G_FAILOVER_MAX_LAG10000Max replication_lag (ops) for a node to be eligible for promotion
P8G_FAILOVER_TARGET_BACKENDnoopnoop (log only) | elbv2 (AWS ALB/NLB target group swap; requires boto3)
P8G_FAILOVER_WRITE_TG_ARN—elbv2: target group receiving write traffic
P8G_FAILOVER_READ_TG_ARN—elbv2: optional target group receiving GET/HEAD
P8G_FAILOVER_TARGET_PORTport from addresselbv2: port registered on the target group
P8G_NODE_TARGET_ID / P8G_FAILOVER_PRIMARY_TARGET_IDhost from addresselbv2: target Id override (EC2 instance ID for instance-type target groups)

Slot-based role discovery (rebuild-safe; set on every node) ​

A slot is a stable identity for an Auto Scaling group / launch-template position (e.g. a for AZ-a, b for AZ-b). Unlike an instance ID or hostname it survives instance replacement. Recording which slot is primary durably is what lets an instance rebuilt in the old primary's ASG boot as a follower after a failover, instead of re-asserting itself as primary from a hard-coded launch template.

VariableDefaultDescription
P8G_NODE_SLOT—This node's slot. Stored as ClusterMember.metadata["slot"]. Required for every hook below
P8G_FAILOVER_PRIMARY_SLOT—Follower only: the slot the current primary occupies (read from the slot parameter at boot)
P8G_FAILOVER_PRIMARY_SLOT_PARAM—AWS SSM Parameter Store name (e.g. /purple8/<instance>/primary-slot). Follower: on promotion the watchdog writes its own slot here (SsmPrimarySlotRecorder). Primary: starts PrimarySlotFence — polls the parameter every P8G_FAILOVER_INTERVAL_S and freezes all writes (503) the moment it no longer names this node's slot. Read errors never fence
P8G_FAILOVER_PRIMARY_ALIAS_ZONE_ID—Route 53 hosted zone containing the stable primary alias
P8G_FAILOVER_PRIMARY_ALIAS_FQDN—The CNAME to keep pointing at the primary, e.g. primary.<instance>.purple8.internal. Used by consumers configured with a fixed hostname rather than the load balancer (e.g. DocIntel GRAPH__BASE_URL)
P8G_FAILOVER_PRIMARY_ALIAS_TARGET_TEMPLATE—CNAME target with a {slot} placeholder, e.g. slot-{slot}.<instance>.purple8.internal. All three _ALIAS_* vars must be set to activate Route53PrimaryAliasRecorder

All hooks are cumulative: the load-balancer swap, the slot record and the alias update run on every promotion, and one hook's failure does not skip the others. Required IAM: ssm:GetParameter, ssm:PutParameter on the parameter; route53:ChangeResourceRecordSets on the zone. Inside a container on EC2 set the launch template's IMDSv2 HttpPutResponseHopLimit to 2, otherwise boto3 cannot obtain instance-role credentials and every hook fails.

With more than one follower, enable the Raft coordination backend (P8G_RAFT_ENABLED) so the election guard and STONITH fencing apply; with a single follower it self-promotes.

Licensing (self-hosted deployments) ​

Self-hosted deployments use a two-tier licensing model:

  • Developer (Self-Hosted Free): $0, up to 50K nodes, 1 MCP agent, full local engine for development, prototyping, and evaluation (no license key required).
  • Enterprise / Custom (Self-Hosted): The single commercial self-hosted tier — tailored to customer capacity, cluster topology, HA, and SLA.
VariableDefaultDescription
PURPLE8_LICENSE_JWT / PURPLE8_LICENSE_DATA / PURPLE8_LICENSE_FILE—License lookup order: JWT string → base64 data → file path
PURPLE8_INSTALL_TYPE—Deployment channel hint (affects license enforcement gating)
PURPLE8_DEV_MODE01 = skip license enforcement entirely (development only)
LICENSE__ENFORCEtruefalse = disable enforcement even in non-dev environments

Purple8 Hyper Graph v0.72.0 · AI-Native Execution Infrastructure · NVIDIA Inception Member · Red Hat Technology Partner.