Skip to main content

config.json Reference

This is the reference for ~/.open-ace/config.json, the application-configuration file of the Open ACE server. It covers every field of the current sample (config/config.json.sample) and the behavior notes from the former config/CONFIG_GUIDE.md (absorbed here).

Location and Precedence​

  • Default path: ~/.open-ace/config.json. The directory can be moved with the OPENACE_CONFIG_DIR environment variable (the Kubernetes manifests set it to /home/open-ace/.open-ace, a mounted PVC).
  • Configuration priority: environment variables > config.json > built-in defaults. Verified consumers:
    • DATABASE_URL (or the split set DB_HOST / DB_PORT / DB_NAME / DB_USER / DB_PASSWORD) overrides any database.* setting in config.json — the docker entrypoint and scripts/shared/config.py both resolve the database URL in that order.
    • SECRET_KEY set in the environment wins over the secret_key field.
    • DATA_FETCH_INTERVAL / DATA_FETCH_ENABLED override the data_fetch section.
  • In Docker, the entrypoint generates config.json on first start from the environment (PORT becomes server.web_port, SERVER_IP builds server.server_url, secrets are auto-generated and persisted). The container itself always listens on 19888; PORT only maps the host port.
  • Division of labor with ENV_REFERENCE.md: environment variables own deployment-level concerns (ports, database, security mode, secrets — see .env.example for Docker Compose), while config.json owns application behavior (workspace, alerts, integrations, feature switches). This document is the authoritative field table for config.json.
  • Application readers cache config.json for up to 60 seconds (app/utils/config.py), so most edits take effect within a minute without restart. Exceptions that require a restart: the autonomous scheduler is started once at boot (autonomous.enabled).

Top-Level Fields​

FieldDescriptionExample / default
host_nameHost identity used to attribute data from different machines. This is the only hostname field — all tools' data is attributed to it; do not duplicate hostnames under tools.*.localhost, server-01
secret_keyFlask session-signing key. The SECRET_KEY environment variable takes precedence. Rotate with care — rotation invalidates all logged-in sessions.random string

server.*​

FieldDescriptionDefault
server.upload_auth_keyUpload authentication key, used to authenticate data uploaded by remote machines (the X-Auth-Key header of /api/upload/batch)random string
server.server_urlServer address; remote machines must be configured with ithttp://192.168.1.100:19888
server.web_portWeb service port19888
server.web_hostWeb bind address0.0.0.0
server.events_ingest_keyShared secret for the scheduler → web SSE event ingest (autonomous activity panel). Must be at least 32 characters; shorter values are ignored""
server.events_ingest_urlIngest URL the scheduler forwards autonomous SSE events to""
server.events_ingest_trusted_sourcesList of trusted source specifications allowed to post ingest events[]

database.*​

FieldDescriptionDefault
database.typeDatabase type: sqlite or postgresqlsqlite
database.pathSQLite database path (SQLite only)~/.open-ace/ace.db
database.urlPostgreSQL connection URL (PostgreSQL only)null

Note: the DATABASE_URL environment variable takes precedence over the config file. If DATABASE_URL is set, the database settings in config.json are ignored.

SQLite example:

{
"database": {
"type": "sqlite",
"path": "~/.open-ace/ace.db"
}
}

PostgreSQL example:

{
"database": {
"type": "postgresql",
"url": "postgresql://user:password@localhost:5432/ace"
}
}

workspace.*​

FieldDescriptionDefault
workspace.enabledEnable the workspace featurefalse
workspace.urlWorkspace service addresshttp://localhost:8080
workspace.isolationIsolation between users: {"level": ..., "backend": ...}, see the table below and WORKSPACE_ISOLATION.md{"level": "none", "backend": "shared"}
workspace.port_range_startFirst port of the per-user webui port pool3100
workspace.port_range_endLast port of the per-user webui port pool3200
workspace.max_instancesMaximum concurrently running webui instances30
workspace.idle_timeout_minutesAuto-shutdown time for idle instances (minutes)30
workspace.cleanup_interval_minutesCleanup sweep interval for idle instances5
workspace.token_secretToken-signing secret (use a strong random string)""
workspace.webui_pathExplicit path to the qwen-code-webui installation (auto-detected when empty)""

In multi-user mode, Open ACE starts an independent qwen-code-webui process for each user, running as that user's system_account. This ensures:

  • Each user only sees their own qwen projects and conversation history
  • User actions are recorded in the qwen logs under the correct identity
  • Data isolation and audit traceability in multi-user environments

workspace.isolation: level and backend (each backend belongs to exactly one level; a mismatched pair, or any removed legacy key multi_user_mode / required_isolation_level / os_user_confinement / sandbox_tier / confinement_*, makes the server refuse to start and names the replacement):

levelbackendWhat it needsAvailable in the Docker install
nonesharedNothing (default)✅
os_userplainPer-user system accounts + the openace-webui-launch wrapper (provided by the install script)✅ (root overlay)
os_userbwrapLinux + systemd + bubblewrap >= 0.8 + webui_callback_url + the confinement wrapper❌
sandboxedlocal-gvisorSame as bwrap + Docker + the gVisor runtime + the local-gvisor section of the root policy file❌
sandboxedlocal-kataSame as bwrap + Docker + /dev/kvm + Kata >= 3.32 + the local-kata section of the root policy file❌
sandboxedopensandboxOpenSandbox on Kubernetes + webui_image from sandbox-backends.json + webui_callback_url✅

Optional keys: tier (opensandbox only); limits (memory / cpu_percent / tasks) and egress_allow (bwrap / local-gvisor / local-kata only); container_webui (local-gvisor / local-kata only).

Single-user example:

{
"workspace": {
"enabled": true,
"url": "http://localhost:8080",
"isolation": {"level": "none", "backend": "shared"}
}
}

Multi-user example:

{
"workspace": {
"enabled": true,
"url": "http://localhost",
"isolation": {"level": "os_user", "backend": "plain"},
"port_range_start": 3100,
"port_range_end": 3200,
"max_instances": 30,
"idle_timeout_minutes": 30,
"token_secret": "generate-a-strong-random-secret-key-here"
}
}

Other Sections​

FieldDescriptionDefault
data_fetch.intervalData fetch interval in seconds (minimum 60)300
data_fetch.enabledEnable the in-app data fetch schedulertrue
quota_enforcement.intervalQuota enforcement sweep interval in seconds60
quota_enforcement.enabledEnable quota enforcementtrue
autonomous.enabledEnable the AI autonomous development feature (restart required)true
autonomous.acceptance_verification_enabledEnable post-merge acceptance verification in the autonomous workflowtrue
run_timeline.enabledPersist remote-session run timelinesfalse
model_gateway.enabledEnable the LiteLLM-compatible model gatewayfalse
policy.enabledEnable the central policy & approval featurefalse
policy.approval_ttl_secondsDefault lifetime of a policy approval (a rule may override it)3600
insights.temperature / insights.max_tokensSampling parameters for insight generation0.3 / 4096

data_fetch.* and quota_enforcement.* can be overridden by the DATA_FETCH_INTERVAL / DATA_FETCH_ENABLED and QUOTA_ENFORCEMENT_INTERVAL / QUOTA_ENFORCEMENT_ENABLED environment variables, following the precedence above.

alerts.*​

FieldDescriptionDefault
alerts.allow_private_webhook_urlsWhether alert webhooks may target private-network / loopback / link-local addresses. Off by default, blocking SSRF risk.false
alerts.dingtalk_webhook_secretGlobal signing secret for DingTalk custom robots. Empty sends as a plain webhook; when set, timestamp / sign are appended before sending. Users may also set their own secret in "alert preferences" (stored encrypted in the webhook URL as openace_dingtalk_secret=<secret>), which takes precedence over this global value.""
alerts.webhook_secretHMAC-SHA256 shared secret for generic (non-Feishu, non-DingTalk) webhooks. When set, request bodies are signed and the signature is sent in the X-OpenACE-Signature header so receivers can verify origin; empty means no signing.""

By default, alert webhooks only allow publicly reachable http(s) URLs. Feishu / Lark and DingTalk group-robot webhooks work directly; if you really need to push to an intranet address, explicitly turn on alerts.allow_private_webhook_urls and control access at the network layer.

tools.*​

FieldDescriptionDefault
tools.openclaw.enabledEnable OpenClawtrue
tools.openclaw.token_envEnvironment variable name for the OpenClaw API tokenOPENCLAW_TOKEN
tools.openclaw.gateway_urlOpenClaw Gateway addresshttp://localhost:18789
tools.claude.enabledEnable Claudetrue
tools.qwen.enabledEnable Qwentrue

feishu.* and dingtalk.*​

Both integrations support user/group name resolution in imported sessions, manual or scheduled organization-structure sync, and (DingTalk) alert-center robot pushes. Neither includes Feishu SSO login. The full field tables, setup steps, and troubleshooting live in the dedicated guides:

  • Feishu: feishu.app_id, feishu.app_secret, feishu.org_sync_enabled (default false), feishu.org_sync_tenant_id (default 1), feishu.org_sync_interval_minutes (default 60) — see FEISHU_CONFIG.md
  • DingTalk: dingtalk.app_key, dingtalk.app_secret, dingtalk.org_sync_enabled (default false), dingtalk.org_sync_tenant_id (default 1), dingtalk.org_sync_interval_minutes (default 60), dingtalk.org_sync_root_dept_id (default "1") — see DINGTALK_CONFIG.md

Getting Started​

  1. Copy the sample configuration file:

    cp config/config.json.sample ~/.open-ace/config.json
  2. Edit ~/.open-ace/config.json:

    • Set host_name to the machine's hostname
    • Generate a random upload_auth_key
    • Configure other optional parameters as needed
  3. Start the service:

    python3 server.py