Editing the Golem Application Manifest (golem.yaml)
The golem.yaml file in the project root is the Golem Application Manifest. It defines the entire application: components, agents, build steps, environments, HTTP/MCP deployments, and more.
Manifest version: The manifestVersion field at the top of the file identifies the application manifest document version. Do not change it.
Top-Level Structure
manifestVersion: "1.5.0" # Manifest document version — do not change
app: my-app # Application name
includes: # (optional) Glob patterns for additional manifest fragments
- "components/*/golem.yaml"
componentTemplates: # Reusable property layers (build, env, plugins, files)
<template-name>: { ... }
components: # Component definitions by name (namespace:name)
<ns:name>: { ... }
tools: # Canonical tool implementation declarations
<tool-name>: { ... }
agents: # Agent type definitions by PascalCase name
<AgentName>: { ... }
environments: # Deployment environments (local, cloud, custom)
<env-name>: { ... }
version: # (optional) Logical version attached to each deployment
git: { ... } # git: | env: <VAR> | "1.2.3" (literal)
httpApi: # HTTP API domain deployments
deployments: { ... }
mcp: # MCP (Model Context Protocol) deployments
deployments: { ... }
bridge: # Bridge SDK generation configuration
ts: { ... }
rust: { ... }
customCommands: # User-defined CLI commands
<command-name>: [...]
clean: # Extra paths for `golem clean`
- "path/to/clean"
secretDefaults: # Secret defaults per environment
<env-name>: {...}
retryPolicyDefaults: # Retry policy defaults per environment
<env-name>: {...}
resourceDefaults: # Quota resource defaults per environment
<env-name>: {...}Components
Components are keyed by namespace:name (e.g., my-app:billing).
components:
my-app:billing:
dir: billing # Base directory (relative to golem.yaml). Use "." for single-component apps
templates: # Parent template names (inherit build, env, plugins, files)
- rust
componentWasm: target/wasm32-wasip2/debug/billing.wasm # Path to built WASM
outputWasm: golem-temp/billing.wasm # Path to final output WASM
build: # Build commands (see Build Commands below)
- command: cargo build --target wasm32-wasip2
env: # Environment variables
LOG_LEVEL: info
tools: # Owner authorization; inherited by the component's agents
search: {}
plugins: # Plugin installations
- name: otlp-exporter
version: "0.1.0"
files: # Initial filesystem entries
- sourcePath: ./data/config.json
targetPath: /etc/config.json
clean: # Extra clean paths
- target/
presets: # Named presets with overrides
debug:
default: true
env:
LOG_LEVEL: debug
release:
env:
LOG_LEVEL: warnKey component fields
| Field | Type | Description |
|---|---|---|
dir | string | Base directory for resolving paths. "." for single-component apps |
templates | string or string[] | Parent template name(s) to inherit from |
componentWasm | string | Path to the built WASM component |
outputWasm | string | Path for the final output WASM ready for upload |
build | array | Build commands (see Build Commands) |
env | map | Environment variables (string → string) |
envMergeMode | enum | upsert (default), replace, or remove |
tools | map | Tool bindings authorized for component owners and inherited by the component’s agents |
toolsMergeMode | enum | upsert (default), replace, or remove |
plugins | array | Plugin installations |
pluginsMergeMode | enum | append (default), prepend, or replace |
files | array | Initial filesystem entries |
filesMergeMode | enum | append (default), prepend, or replace |
config | any | Arbitrary configuration passed to agent |
wasiConfig | map | WASI configuration variables (string → string) |
wasiConfigMergeMode | enum | upsert (default), replace, or remove |
customCommands | map | Component-level custom commands |
clean | string[] | Extra clean paths |
presets | map | Named presets (see Presets) |
Component Templates
Templates define reusable property layers. Components reference them via templates:.
componentTemplates:
my-rust:
templates: [rust] # Inherits the built-in "rust" template (build, guestLanguage)
env:
RUST_LOG: info
components:
my-app:service:
templates: [my-rust] # Inherits from "my-rust" and, through it, from "rust"
dir: serviceTemplates support the same fields as components except dir. Templates can themselves reference other templates via templates:, but a template may be inherited only through a single path: using two templates that both inherit the same template (e.g. templates: [my-ts, ts-extra] where both inherit ts) is rejected. The same applies to the templates lists of agents and tools. The built-in templates (rust, ts, effect, scala and moonbit) are provided by the CLI; don’t define templates with these names.
Templates can declare the guest language of the components built with them via guestLanguage (ts, effect, rust, scala or moonbit). The built-in templates declare it, so templates inheriting them don’t need to. A custom template that builds a component on its own (without inheriting a built-in template) should declare it, otherwise language-specific CLI features (dependency checks, bridge generation, REPL) are unavailable for its components. The templates applied to a component must not declare different languages.
Agents
Agent types are keyed by PascalCase name. They support the same cascading property fields as components (env, plugins, files, config, wasiConfig) but NOT build-related fields. Agents can also inherit from templates via templates:.
agents:
MyAgent:
templates: [shared-runtime] # Inherit env/plugins/files from a template
env:
CACHE_TTL: "300"
plugins:
- name: otlp-exporter
version: "0.1.0"
files:
- sourcePath: ./agent-data/model.bin
targetPath: /data/model.bin
presets:
debug:
default: true
env:
CACHE_TTL: "60"Config and WASI Config
The config field accepts arbitrary YAML values (objects, arrays, scalars) passed as typed configuration to the agent at runtime. The wasiConfig field is a string-to-string map of WASI-level configuration variables.
components:
my-app:service:
config:
model: gpt-4o-mini
temperature: 0.2
features:
- summarize
- translate
wasiConfig:
WASI_FLAG: enabled
agents:
MyAgent:
config:
max_retries: 3
wasiConfig:
AGENT_WASI_OPT: "true"Both fields follow the cascade hierarchy and support merge modes (wasiConfigMergeMode for wasiConfig).
Cascade / Merge System
Properties cascade from general to specific:
componentTemplates → components → agents → presetsEach level can override or merge with its parent using merge modes:
| Property | Merge Mode Field | Type | Default | Options |
|---|---|---|---|---|
env | envMergeMode | map | upsert | upsert, replace, remove |
wasiConfig | wasiConfigMergeMode | map | upsert | upsert, replace, remove |
plugins | pluginsMergeMode | vec | append | append, prepend, replace |
files | filesMergeMode | vec | append | append, prepend, replace |
build | buildMergeMode | vec | append | append, prepend, replace |
tools | toolsMergeMode | map | upsert | upsert, replace, remove |
Component tool bindings authorize fresh component owners (including tools-only MCP calls) and default into real agents exported by that component. An agent-only binding does not authorize a fresh component owner. To opt an agent out of an inherited tool, remove it explicitly:
components:
my-app:service:
tools:
search: {}
agents:
RestrictedAgent:
toolsMergeMode: remove
tools:
search: {}When agents should not receive the defaults, prefer a separate component with no agents as the tool owner.
Presets
Both components and agents support presets — named configurations that can override the properties allowed at that level. Component presets can override component-layer fields (build, env, plugins, files, config, wasiConfig, clean, customCommands); agent presets can override agent-layer fields (env, plugins, files, config, wasiConfig). Presets cannot override structural fields like dir or templates. Mark one preset as default with default: true.
components:
my-app:service:
presets:
debug:
default: true # Selected by default
env:
LOG_LEVEL: debug
release:
env:
LOG_LEVEL: warnBuild Commands
The build array contains commands executed during golem build. Each entry is one of:
External command (most common)
build:
- command: cargo build --target wasm32-wasip2
dir: . # Optional working directory
env: # Optional extra env vars
RUSTFLAGS: "-C opt-level=2"
rmdirs: [target/old] # Directories to delete before running (runs before mkdirs)
mkdirs: [target/new] # Directories to create before running (runs after rmdirs)
sources: ["src/**/*.rs"] # Inputs for up-to-date checks
targets: ["target/wasm32-wasip2/debug/*.wasm"] # Outputs for up-to-date checksTypeScript/QuickJS-specific commands
build:
- generateQuickjsCrate: golem-temp/quickjs-crate # Generate QuickJS Rust crate
wit: wit
jsModules: { "main.js": "esm" }
world: my-world # Optional WIT world
- generateQuickjsDts: golem-temp/bindings.d.ts # Generate TypeScript declarations
wit: wit
- injectToPrebuiltQuickjs: golem-temp/quickjs.wasm # Inject JS into prebuilt QuickJS
module: dist/bundle.js
into: golem-temp/output.wasm
- preinitializeJs: golem-temp/output.wasm # Pre-initialize JS runtime
into: golem-temp/preinit.wasmCustom Commands
Define CLI commands at the application or component level:
customCommands:
test:
- command: cargo test --target wasm32-wasip2
dir: .
lint:
- command: cargo clippy --target wasm32-wasip2Run with golem exec <name> (e.g., golem exec test).
customCommands can only contain command:-style external commands; they do not support generateQuickjsCrate, injectToPrebuiltQuickjs, or other build-specific command types.
Environments
Environments configure where and how the application is deployed.
environments:
local:
default: true # First environment is default if not specified
server: local # Built-in local server
cli:
format: text
autoConfirm: true
cloud:
server: cloud # Golem Cloud
staging:
server: # Custom server
url: https://staging.example.com
auth:
oauth2: true # or: staticToken: "my-token"
workerUrl: https://staging-workers.example.com # Optional separate worker URL
allowInsecure: false # Optional, allow insecure connections
componentPresets: [release] # Preset names to activate
cli:
format: json
redeployAgents: true # Delete and recreate agents; agent state is lost
deployment:
compatibilityCheck: true
versionCheck: true
securityOverrides: falseServer options
| Value | Description |
|---|---|
local | Built-in local Golem server |
cloud | Golem Cloud |
{ url, auth, ... } | Custom server (see Custom Server below) |
Custom server auth
# OAuth2 (interactive login)
auth:
oauth2: true
# Static token
auth:
staticToken: "my-secret-token"CLI options
| Field | Description |
|---|---|
format | Default output: text, json, yaml, pretty, pretty-json, pretty-yaml, toon |
autoConfirm | Auto-confirm prompts (true) |
redeployAgents | Equivalent to --redeploy-agents: delete and recreate agents; agent state is lost |
reset | Equivalent to --reset: delete existing agents for the deployed components after deployment, losing their state, and enable incompatibility-replacement fallbacks; the environment itself is retained |
Configure at most one destructive default. If both are enabled, reset takes precedence.
When format: toon is used, structured stdout is emitted as framed TOON documents. Parse exact @toon and @end marker lines, and treat the content between them as one TOON document. Stderr may still contain progress or diagnostics and should not be parsed as the structured payload.
Deployment options
| Field | Type | Description |
|---|---|---|
compatibilityCheck | bool | Check component compatibility before deploying |
versionCheck | bool | Reject a deploy whose logical version already exists in the environment (enforce version uniqueness). Default false |
securityOverrides | bool | Allow security scheme overrides |
Deployment Version
version: (top-level) and environments.<name>.version: (per-environment override) configure the
logical version attached to each deployment — derived from a git tag, the git commit hash, a static
string, or an environment variable. This is orthogonal to versionCheck above (which enforces
uniqueness of that version).
version: # application-wide default
git:
tagPattern: "v*" # required for git tag mode; "*" = all tags
hashFallback: true # untagged repo → short commit hash
staticFallback: "v0.0.0" # no git / not a repo → this value
environments:
local:
version:
git:
allowDirty: true # partial override; inherits the rest from the rootLoad golem-deployment-version for the full field reference (git tag/hash modes, commitInfo,
hashFallback, staticFallback, allowDirty, per-environment overrides, and how the version
interacts with versionCheck).
HTTP API Deployments
Configure HTTP API domain deployments per environment.
Each deployment must define exactly one of:
subdomain: a single DNS label resolved through the target environment server (my-app.localhost:9006locally by default,my-app.apps.golem.cloudon built-in cloud).domain: a full custom domain such asapi.example.comfor custom DNS or custom server environments.
The optional scheme field is the public http or https scheme advertised in OpenAPI. Omission defaults to http for built-in local and implicit local environments and https for built-in cloud. Explicit values override these defaults. Custom server environments require an explicit value; the management URL scheme is not inferred. This does not configure the listener.
httpApi:
deployments:
local:
- subdomain: my-app # resolves to my-app.localhost:9006 by default
webhookUrl: /webhooks/ # Optional webhook path prefix
agents:
TaskAgent: {} # No auth
SecureAgent:
securityScheme: my-oidc # OIDC security scheme name
DevAgent:
testSessionHeaderName: X-Test-Auth # Test auth header
cloud:
- subdomain: my-app # resolves to my-app.apps.golem.cloud
agents:
TaskAgent: {}
SecureAgent:
securityScheme: prod-google-oidcAgent names use PascalCase matching the agent type name in code.
MCP Deployments
Configure MCP (Model Context Protocol) deployments per environment.
Each deployment must define exactly one of:
subdomain: a single DNS label resolved through the target environment server (my-mcp.localhost:9007locally by default,my-mcp.mcps.golem.cloudon built-in cloud).domain: a full custom domain such asmcp.example.comfor custom DNS or custom server environments.
components:
my-app:search-implementation:
componentWasm: build/search-implementation.wasm
my-app:tool-owner:
componentWasm: build/tool-owner.wasm
tools:
search: {}
tools:
search:
component: my-app:search-implementation
mcp:
deployments:
local:
- subdomain: my-mcp # resolves to my-mcp.localhost:9007 by default
tools:
search:
ownerComponent: my-app:tool-owner
include: [query]The MCP tool must also have a top-level implementation declaration and a components.my-app:tool-owner.tools.search binding. No agent is required. The implementation and owner components may differ; include/exclude selects exported commands. A remote declaration requires an environment grant, which application deployment automatically reconciles when the deploy actor has permission.
Bridge SDK Generation
Generate typed client SDKs for calling agents from external code. The agents field accepts "*" (all agents), or a list of agent type names or component names (namespace:name).
bridge:
ts:
external:
agents: "*" # Generate for all agents
outputDir: ./bridge-sdk/ts # Optional custom output directory
rust:
external:
agents:
- MyAgent # Agent type name
- my-app:billing # Component name (all agents in that component)
outputDir: ./bridge-sdk/rust
additionalDerives:
- '^Order.*=PartialEq,Eq'
- 'Response$=custom_derive::ApiType'
additionalDependencies:
anyhow: "1"
custom_derive:
path: ./crates/custom-derive # Relative to this manifest file
package: custom-derive-macros
features: [api]
defaultFeatures: false
git_derive:
git: https://github.com/example/derive-macros
tag: v1.2.3 # Use at most one of branch/tag/revadditionalDerives entries are <regex>=Trait,Trait; every matching final generated Rust type name receives the merged, deduplicated derives. additionalDependencies accepts a version string or one source (version, path, or git) plus package, features, and defaultFeatures; git accepts one of branch, tag, or rev. Workspace and optional dependencies are not supported. These Rust-only fields are valid under bridge.rust.external and bridge.rust.internal for agent bridges only. An internal entry using them must select agents; tool bridge generation is unchanged.
The low-level equivalent uses repeatable options and parses each dependency as Cargo TOML:
golem generate-bridge --language rust \
--derive-rule '^Order.*=PartialEq,Eq' \
--rust-dependency 'custom_derive = { package = "custom-derive-macros", path = "./crates/custom-derive", features = ["api"], default-features = false }'CLI paths are relative to the invocation directory; manifest paths are relative to the directory containing the bridge declaration.
Plugin Installations
Plugins are installed at any cascade level (template, component, agent, preset).
plugins:
- name: otlp-exporter
version: "0.1.0"
account: golem # Optional account
parameters: # Optional key-value config
endpoint: http://localhost:4317
protocol: grpcInitial Files
Mount files into the agent’s virtual filesystem.
files:
- sourcePath: ./data/config.json # Local path or URL
targetPath: /etc/app/config.json # Absolute path in agent filesystem
permissions: read-only # read-only (default) or read-write
- sourcePath: ./static-assets/ # Directory — recursively included
targetPath: /var/www/static/
- sourcePath: https://example.com/model.bin # Remote URL
targetPath: /data/model.binTemplate Substitution
Environment variable values support {{ VAR_NAME }} syntax. At deploy time, these resolve against the host machine’s environment:
env:
API_KEY: "{{ MY_API_KEY }}"
DB_URL: "prefix-{{ DB_HOST }}-suffix"Missing host variables cause deployment failure.
Secret Defaults
Secret defaults per environment use the same nested object style as config:
secretDefaults:
local:
apiKey: "test-key-123"
prod:
apiKey: "{{ PROD_API_KEY }}"Retry Policy Defaults
Named retry policies created in the environment during deployment:
retryPolicyDefaults:
local:
default-retry:
priority: 10
predicate: "true" # Always match
policy:
countBox:
maxRetries: 3
inner:
exponential:
baseDelay: { secs: 1, nanos: 0 }
factor: 2.0Retry policy types
| Type | Fields | Description |
|---|---|---|
"immediate" | — | Retry immediately |
"never" | — | Never retry |
periodic | { secs, nanos } | Fixed delay between retries |
exponential | { baseDelay, factor } | Exponentially increasing delay |
fibonacci | { first, second } | Fibonacci-sequence delays |
countBox | { maxRetries, inner } | Limit total retry count |
timeBox | { limit, inner } | Limit total retry time |
clamp | { minDelay, maxDelay, inner } | Clamp delay range |
addDelay | { delay, inner } | Add fixed delay to inner policy |
jitter | { factor, inner } | Add random jitter |
filteredOn | { predicate, inner } | Apply only when predicate matches |
andThen | [policy1, policy2] | Sequential composition |
union | [policy1, policy2] | Union of two policies |
intersect | [policy1, policy2] | Intersection of two policies |
Retry predicates
| Type | Fields | Description |
|---|---|---|
"true" | — | Always matches |
"false" | — | Never matches |
propEq | { property, value } | Property equals value |
propNeq | { property, value } | Property not equal |
propGt / propGte | { property, value } | Greater than / greater or equal |
propLt / propLte | { property, value } | Less than / less or equal |
propExists | string | Property exists |
propIn | { property, values } | Property in set |
propMatches | { property, pattern } | Regex match |
propStartsWith | { property, prefix } | Starts with prefix |
propContains | { property, substring } | Contains substring |
and | [pred1, pred2] | Logical AND |
or | [pred1, pred2] | Logical OR |
not | predicate | Logical NOT |
Predicate values are typed: { text: "..." }, { integer: 42 }, or { boolean: true }.
Resource Quota Defaults
Quota resource definitions created during deployment:
resourceDefaults:
local:
api-calls:
limit:
type: Rate
value: 100
period: minute
max: 1000
enforcementAction: reject # reject, throttle, or terminate
unit: request
units: requests
storage:
limit:
type: Capacity
value: 1073741824 # 1 GB
enforcementAction: reject
unit: byte
units: bytes
connections:
limit:
type: Concurrency
value: 50
enforcementAction: throttle
unit: connection
units: connectionsResource limit types
| Type | Required Fields | Description |
|---|---|---|
Rate | value, period, max | Rate limit per time period. period: second/minute/hour/day/month/year |
Capacity | value | Total capacity limit |
Concurrency | value | Concurrent usage limit |
Enforcement actions
| Action | Description |
|---|---|
reject | Reject requests exceeding the limit |
throttle | Slow down requests exceeding the limit |
terminate | Terminate the agent when limit is exceeded |
Common Edit Patterns
Add a new component
Insert a new key under components::
components:
my-app:new-service:
dir: new-service
templates: [rust]Add environment variables to an agent
agents:
MyAgent:
env:
NEW_VAR: "value"Add a plugin to a component
components:
my-app:service:
plugins:
- name: my-plugin
version: "1.0.0"
parameters:
key: valueAdd a new environment
environments:
staging:
server:
url: https://staging.example.com
auth:
staticToken: "{{ STAGING_TOKEN }}"Add HTTP API deployment for a new environment
httpApi:
deployments:
staging:
- domain: api-staging.example.com
scheme: https
agents:
MyAgent: {}Add clean paths
Root-level clean paths apply to golem clean globally; component-level clean paths are scoped to that component:
clean:
- golem-temp/
- dist/
components:
my-app:web:
clean:
- node_modules/.cache/
- build/Field Scope Matrix
This table shows where each property can be defined:
| Field | Root | Component Template | Component | Agent | Component Preset | Agent Preset |
|---|---|---|---|---|---|---|
templates | — | ✅ | ✅ | ✅ | — | — |
guestLanguage | — | ✅ | — | — | — | — |
build | — | ✅ | ✅ | — | ✅ | — |
env | — | ✅ | ✅ | ✅ | ✅ | ✅ |
wasiConfig | — | ✅ | ✅ | ✅ | ✅ | ✅ |
plugins | — | ✅ | ✅ | ✅ | ✅ | ✅ |
files | — | ✅ | ✅ | ✅ | ✅ | ✅ |
config | — | ✅ | ✅ | ✅ | ✅ | ✅ |
tools | — | ✅ | ✅ | ✅ | ✅ | ✅ |
customCommands | ✅ | ✅ | ✅ | — | ✅ | — |
clean | ✅ | ✅ | ✅ | — | ✅ | — |
dir | — | — | ✅ | — | — | — |
componentWasm | — | ✅ | ✅ | — | ✅ | — |
outputWasm | — | ✅ | ✅ | — | ✅ | — |
Related Guides
- Load
golem-profiles-and-environmentsfor detailed guidance on CLI profiles, app environments, component presets, and how they interact - Load
golem-deployment-versionfor theversion:source (git tag/hash, static, env var) and theversionCheckuniqueness policy
Edit Guardrails
- Do not invent fields: most manifest objects use
additionalProperties: false— only use fields documented above. - Preserve
manifestVersion: never change the manifest document version. - Agent names use PascalCase: matching the class/trait name in code (e.g.,
MyAgent, notmy-agent). - Component names use
namespace:nameformat (e.g.,my-app:billing). - Only one
default: truepreset per preset map. - Merge modes are intentional:
env,wasiConfig,plugins,files, andbuildrespect merge modes. Don’t silently replace arrays/maps unless a merge mode ofreplaceis set. - Template substitution (
{{ VAR }}) in env values resolves from host environment at deploy time. Missing variables cause deployment failure.