Web’s System page shows the installation’s addresses, the default models, the sandbox configuration and, under Startup settings, the process settings read-only with the path of
config.json and the apply command. Secrets live in secrets/, one copy each. The files in generated/ are derived from config.json. No configuration file defines Projects or API keys.
Process settings: config.json
The installer writes every setting that applies to the installation’s mode, so the file shows each value. Installer flags listed in installation options only seed it. To change a setting, edit the file and apply it:How oac apply works
- It validates
config.jsonand changes nothing if a value is invalid.mode,native_coreandingressare fixed after installation; to change them, install into a new directory. It also checks the listeners that a changedhost, port or managed-ingresspublic_urladds (ports), and changes nothing ifhostis not an address of this machine or another program holds one of their ports; the installation’s own listeners do not count. - It writes the files Core, Web and Compose read into
generated/:compose.json,core.env,core-key-digests.json,settings.jsonand, when used,runtime-history.json, the managedCaddyfileand the native Core unit. Don’t edit them. A generated file edited by hand stopsapplyuntil you move the change intoconfig.jsonand runoac apply --discard-edits, which keeps the edited copy asgenerated/<file>.edited-<time>. - It compares what it wrote with what actually runs. Each container carries a digest of its inputs (the
io.oac.inputslabel; native Core carriesOAC_INPUTS), andapplyrecreates or restarts exactly the services whose inputs differ: Core first, then Web. The Restarts column below says which services a setting affects; see stop and restart for what a restart interrupts. - While any service runs,
applyalso starts the stopped ones. Afteroac stop, it only writes the files and the installation stays stopped. - If Core refuses a value at startup,
applyprints Core’s startup error. If every service was running with the previous files, it restores them and starts the services again; otherwise it reports the failure, and the nextapplyfinishes the work.
oac status reports changes to config.json that are not applied yet and generated files edited by hand.
Changing the public URL
public_url is the one origin that applications, nodes, sandboxes and self-hosted executors use. Core derives the daemon WebSocket URL, the self-hosted remote_url and each sandbox’s connection address from it. With null, Core uses its loopback origin. Until public_url is set, a managed installation serves only Web, over HTTP on the host’s IP address at ports.web; afterwards that address redirects to public_url.
With managed ingress, change it in Web (System → Configure domain and HTTPS) or with oac domain HOSTNAME. Both take the installation lock, verify the new certificate and address, then write config.json and apply it. With external ingress, update your reverse proxy first, then edit public_url and run oac apply.
When nodes, hosted sandboxes or self-hosted executors are bound to the current address, apply lists them and asks you to type the new URL (--confirm-public-url-change URL without a terminal). Afterwards:
- Nodes on the old address get no new sandboxes: remove them in Web and add them again.
- Existing sandboxes and executors keep working only while the old address still reaches this Core. A managed domain change replaces the previous domain route.
- Self-hosted executors must restart with the new
remote_url, and their installer refuses an installation made for the old address: create new self-hosted Sessions and connect their hosts again.
Settings
core.runtime_history.headers may hold export credentials. They stay in the 0600 config.json and the generated file Core reads, and never appear in oac output or in Core’s settings snapshot. Model providers are not process settings; see Default models.
The schema is
deploy/install/config.schema.json; each installation keeps a copy in generated/config.schema.json for editors. Core serves the non-secret settings snapshot, with the path of config.json and the apply command, at GET /core/v1/installation. How Core collects and keeps Runtime history is in retained history.
Runtime settings: Web
Runtime settings live in Core’s database. Change them in Web; scripts use the same Core API with the Core key.
Which harnesses are enabled, and the default one, are process settings (
core.harnesses, core.default_harness); System shows them read-only. The Core administration API lists every Core API route, and the deployment contract defines the sandbox fields, limits and change rules.
Node capacity
Core approves a node’s capacity when you generate its Add node command: Sandboxes at once (max_active, default 2) and, for microsandbox only, Retained sandboxes (max_retained, default 8), with max_retained >= max_active >= 1. Docker never suspends sandboxes, so Web doesn’t ask for it and Core keeps max_retained equal to max_active. Change them later with Edit node. Reservations and cleanup that is not confirmed count against capacity; lowering a limit stops no running sandbox. A node’s own files can’t change its capacity, size or Runtime.
core.execution_concurrency is unrelated: it limits concurrent execution work in Core.
Default models
Set a default in System → Default model configuration, or usePUT /core/v1/harnesses/{harness}/model-configuration. Core encrypts provider keys with secrets/credential.key and never returns them. Model execution owns the request fields and replacement rules, and precedence says which Sessions use a default.
Docker node configuration
The node installer writes Docker’s provider configuration into the node’s configuration file; these fields are separate from Core’sconfig.json. Deployment resources, Runtime images and capacity remain in Core’s database.
The Docker adapter owns container isolation, volume layout and lifecycle behavior.
Installation directory
The installer creates the installation directory,~/.oac/core by default, with mode 0700; the files in secrets/ are 0600.
A Web-only installation has only
secrets/core.key, a copy of its Core’s key, and no state/ or native-installers/. A Core-only installation has no node-payload/. Only managed ingress has ingress/. With native Core, the installation directory and the bundle must be canonical absolute paths without control characters, quotes, backslashes or wildcards.
In Docker, the Compose project is named oac-<10 hex digits> (project in state.json). Its services are database, migrate, core and web, plus gateway and installation with managed ingress. gateway routes to Core and Web and publishes ports.web, plus 80 and 443 once HTTPS is on; installation applies domain changes from Web and uses the Docker socket to do so. The volume <project>_database holds all data. Native Core runs Core as the systemd user unit <project>-core.service instead of a container. Apart from Docker’s storage, nothing is written outside your home directory.
Appendix: Core environment without the installer
Core reads only its environment. The installer rendersgenerated/core.env from config.json; if you run Core yourself (see the service guide), set these variables. Compose loads the file with env_file and systemd with EnvironmentFile, so Compose must be 2.26.0 or newer.
Core logs the file paths it loads, never environment values or file contents.
Invalid explicit OAuth trusted origins stop Core at startup. Entries must be HTTPS origins without credentials, query or a non-root path; the installer validates
core.oauth_trusted_origins before generating them. Vaults owns refresh and network policy. A private issuer also needs a trusted CA: independently managed Unix Core can use Go’s SSL_CERT_FILE PEM CA-bundle override, which preserves certificate verification. Managed installation has no custom-CA setting or mount; do not edit generated/core.env.
Appendix: Web environment without the installer
The installer sets these variables fromconfig.json; set them yourself only when you run the console without the installer. Of the installation’s secrets, the installer gives the console only secrets/core.key.
Defaults apply when a variable is absent; an explicitly empty value is validated as supplied. An invalid
OAC_WEB_* value stops the console at startup with a message naming the variable. The console also reads OAC_LOG_LEVEL, OAC_LOG_FORMAT and OAC_LOG_ADD_SOURCE (Core environment); unknown values fall back to their defaults. Use HTTPS for any browser that is not on the same machine.