# How HolaOS Manages Configuration Settings: A Layered Runtime System Explained

> Discover how HolaOS manages configuration settings with its layered runtime system. Learn about JSON documents, environment variable overrides, and a three-layer precedence for flexible deployments.

- Repository: [holaboss.ai/holaOS](https://github.com/holaboss-ai/holaOS)
- Tags: internals
- Published: 2026-08-15

---

**HolaOS centralizes runtime configuration in a JSON document with environment variable overrides, providing a three-layer precedence system (file → env → defaults) for flexible, container-ready deployments.**

The HolaOS configuration system, implemented in `runtimeConfigPath()` and related utilities in [`runtime/api-server/src/runtime-config.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/api-server/src/runtime-config.ts), gives operators two ways to control application behavior: a persistent JSON file for reproducible state and environment variables for dynamic, containerized environments. This article examines the complete configuration flow from disk to strongly-typed runtime object.

## How Configuration Loading Works

HolaOS loads configuration through three distinct stages that progressively merge sources and validate the result.

### Stage 1: Loading the Raw JSON Document

The `loadRuntimeConfigDocument()` function determines where to look for configuration by calling `runtimeConfigPath()`. This path resolver checks the `HOLABOSS_RUNTIME_CONFIG_PATH_ENV` environment variable first, then falls back to the default sandbox state directory. If the file exists, it parses the JSON; otherwise, it returns an empty document structure.

```typescript
// Internal implementation detail from runtime/api-server/src/runtime-config.ts#L70-L78
// Path resolution prioritizes HOLABOSS_RUNTIME_CONFIG_PATH_ENV
const configPath = runtimeConfigPath(); // → sandbox/state/runtime-config.json or custom path
const rawDocument = loadRuntimeConfigDocument(configPath);

```

### Stage 2: Merging with Environment Variables

The `loadRuntimeConfigPayload()` function extracts nested sections (`runtime`, `providers`, `integrations`, `capabilities`) and normalizes each field. For every property, it applies **precedence-based resolution**: JSON value first, then environment variable fallback, finally hard-coded default.

Key environment variables include:

- `HOLABOSS_SANDBOX_AUTH_TOKEN_ENV`
- `HOLABOSS_USER_ID_ENV`
- `HOLABOSS_MODEL_PROXY_KEY_ENV`

The `firstEnvValue()` helper implements this fallback chain. Boolean and list values receive specialized normalization through `normalizeBool()` and `normalizeStringList()` to handle string representations consistently.

```typescript
// From runtime/api-server/src/runtime-config.ts#L122-L158
// Environment variables override JSON values only when JSON is absent
const mergedPayload = loadRuntimeConfigPayload({
  preferEnv: false, // JSON takes precedence
});

```

### Stage 3: Building the Typed Config Object

The `resolveProductRuntimeConfig()` function constructs a `ProductRuntimeConfig` instance from the merged payload. This stage performs **runtime validation**: when `requireAuth: true`, the function throws if no authentication token is present; similarly for `requireUser`.

```typescript
// From runtime/api-server/src/runtime-config.ts#L103-L112
const config = resolveProductRuntimeConfig({
  requireAuth: true,   // Validates HOLABOSS_SANDBOX_AUTH_TOKEN presence
  requireUser: true,   // Validates HOLABOSS_USER_ID presence
});

```

## Accessing Configuration in Application Code

Components retrieve configuration through two patterns depending on their architecture.

### Direct Function Calls

Simple utilities call `resolveProductRuntimeConfig()` directly. The `runtimeConfigHeaders()` function uses this approach to build HTTP headers for downstream services, ensuring updates propagate immediately to outgoing requests.

```typescript
import { runtimeConfigHeaders } from "@/runtime/api-server/src/runtime-config";

const headers = runtimeConfigHeaders({ requireAuth: true });
// Produces: { "X-API-Key": "...", "X-Holaboss-User-Id": "..." }

fetch("https://model-proxy.example/api", { headers });

```

### Injectable Service Pattern

API handlers use `FileRuntimeConfigService`, which encapsulates loading, status checking, and updating behind a clean interface. This class abstracts the underlying file operations and re-loading logic.

```typescript
import { FileRuntimeConfigService } from "@/runtime/api-server/src/runtime-config";

const configService = new FileRuntimeConfigService();

// Read-only access to current configuration
const current = await configService.getConfig();

// Check if configuration exists on disk
const exists = await configService.status(); // → { exists: boolean }

```

## Updating Configuration at Runtime

The `updateRuntimeConfigDocument()` function receives partial payloads from client requests, merges them into the existing JSON structure while **preserving unknown fields**, and persists the result via `writeRuntimeConfigDocument()`.

After saving, the service calls `resolveProductRuntimeConfig()` to refresh the in-memory view, ensuring subsequent reads reflect the updated state.

```typescript
// From runtime/api-server/src/runtime-config.ts#L88-L97
await configService.updateConfig({
  desktop_browser_enabled: true,
  desktop_browser_url: "https://my-browser.local",
  unknown_field: "preserved", // Not in TypeScript interface but kept in JSON
});

```

## Configuration Precedence Explained

HolaOS implements deterministic, predictable layering:

| Precedence | Source | Typical Use Case |
|------------|--------|----------------|
| 1 (Highest) | [`runtime-config.json`](https://github.com/holaboss-ai/holaOS/blob/main/runtime-config.json) | Reproducible deployments, version-controlled defaults |
| 2 | Environment variables (`HOLABOSS_*`) | Container secrets, dynamic cloud assignments |
| 3 (Lowest) | Hard-coded defaults | `DEFAULT_MODEL = "gpt-5.4"` |

This design satisfies two operational modes: **static file management** for development and GitOps workflows, and **environment injection** for Kubernetes, Docker, and serverless platforms.

## Complete Configuration Example

```typescript
// Full workflow: load, inspect, modify, and apply configuration
import {
  resolveProductRuntimeConfig,
  FileRuntimeConfigService,
  runtimeConfigHeaders,
} from "@/runtime/api-server/src/runtime-config";

// 1. Resolve with validation
const cfg = resolveProductRuntimeConfig({
  requireAuth: true,
  requireUser: true,
});

console.log(cfg.model);           // → "gpt-5.4" (from JSON or default)
console.log(cfg.authToken);       // → from HOLABOSS_SANDBOX_AUTH_TOKEN_ENV if JSON absent

// 2. Service-based updates
const service = new FileRuntimeConfigService();
await service.updateConfig({ model: "gpt-5.5" });

// 3. Headers automatically reflect changes
const headers = runtimeConfigHeaders({ requireAuth: true });

```

## Summary

- **Configuration lives in [`runtime-config.json`](https://github.com/holaboss-ai/holaOS/blob/main/runtime-config.json)** under the sandbox state directory, with path override via `HOLABOSS_RUNTIME_CONFIG_PATH_ENV`
- **Three-stage loading**: raw document → env merging → typed validation via `resolveProductRuntimeConfig()`
- **Environment variables provide fallback values** when JSON fields are absent, not override
- **`FileRuntimeConfigService`** encapsulates read, status-check, and update operations for dependency injection
- **Updates preserve unknown JSON fields** and immediately refresh the resolved configuration
- **`runtimeConfigHeaders()`** ensures downstream service calls always use current settings

## Frequently Asked Questions

### How do I override a HolaOS setting without modifying the JSON file?

Set the corresponding environment variable. HolaOS checks `HOLABOSS_*` variables after reading the JSON document, using `firstEnvValue()` to apply fallbacks. For example, `export HOLABOSS_MODEL_PROXY_KEY_ENV=sk-...` provides the API key without touching [`runtime-config.json`](https://github.com/holaboss-ai/holaOS/blob/main/runtime-config.json).

### What happens if [`runtime-config.json`](https://github.com/holaboss-ai/holaOS/blob/main/runtime-config.json) does not exist?

`loadRuntimeConfigDocument()` returns an empty document structure, and all configuration resolves from environment variables and hard-coded defaults. The system does not fail; it operates in "env-only" mode until a configuration file is created.

### How does HolaOS handle configuration updates without restarting?

The `FileRuntimeConfigService.updateConfig()` method writes changes to disk and immediately calls `resolveProductRuntimeConfig()` to rebuild the typed configuration object. Components reading through the service or calling `runtimeConfigHeaders()` receive updated values on their next access—no restart required.

### Where is the configuration file located by default?

`runtimeConfigPath()` returns [`sandbox/state/runtime-config.json`](https://github.com/holaboss-ai/holaOS/blob/main/sandbox/state/runtime-config.json) relative to the working directory unless `HOLABOSS_RUNTIME_CONFIG_PATH_ENV` is set. This default path supports HolaOS's sandbox isolation model while remaining overrideable for custom deployments.