obelisk 0.41.2

Deterministic workflow engine
## Server configuration
## The API, webui, and external HTTP server are all enabled by default on localhost.
## To disable any of them, set `enabled = false`. To change the address, override `listening_addr`.
# api.enabled = true                             # Disable the API server (enabled by default).
# api.listening_addr = "127.0.0.1:5005"          # Address and port on which the API server will listen.
# webui.enabled = true                           # Disable the webui (enabled by default).
# webui.listening_addr = "127.0.0.1:8080"        # Address and port on which the webui will listen.
# external.enabled = true                        # Disable the external HTTP server (enabled by default).
# external.listening_addr = "127.0.0.1:9090"     # Address and port on which the external HTTP server will listen.
# Note: the external HTTP server (webhooks) has no auth; listening on all interfaces using [::]:port is not advised.

## API authentication. The API port denies requests without a valid `Authorization: Bearer <token>` header.
## An ephemeral startup token is always generated and printed to the console.
## Persistent tokens are configured as sha256 hashes of the token text; hashes are not secrets,
## so this file stays safe to commit. Add an entry with
## `obelisk generate token --server-config <this file>`, which prints the token to stdout.
# api.token_hashes = [
#   "sha256:...",   # agent
#   "sha256:...",   # laptop
# ]
## Plaintext accepted token, intended for env injection only (`OBELISK__API__TOKEN`);
## do not write it into this file.
# api.token = "..."

## Semver version requirement for the Obelisk binary.
## If set, the server will fail to start if the binary version doesn't match.
# obelisk-version = 0.1

## Operator-owned secret registry. Maps a logical secret name to a source.
## Only `{ env = "VAR" }` is supported today. At startup, before the runtime starts, each
## env-backed secret is read into memory and its source variable is removed from the process
## environment, so no deployment or worker thread can read it. Deployments reference these
## names (never the raw env var) in `activity_exec.secrets` and `allowed_host.secrets`;
## they cannot interpolate a registered secret via `${...}`.
# [secrets]
# OPENAI_KEY     = { env = "OPENAI_API_KEY" }   # logical name may differ from the source
# DB_PASSWORD    = { env = "DB_PASSWORD" }

## Per-file size limit (in bytes) for deployment-owned blobs attached to a submit request.
## Defaults to 20 MiB.
# max_deployment_file_bytes = 20971520

## Exec activities run host processes outside the WASM sandbox and are disabled by default.
## Allow any exec activity (logs a warning):
# allow_exec_activities = true
## Or allow only reviewed scripts, pinned by name and the digest of the exact script text.
## A rejected deployment logs the entry to copy here after review:
# [allow_exec_activities]
# greet = "sha256:..." # reviewed 2026-07-13

## Global outbound HTTP policy. Component-originated requests must be allowed by both
## this operator-owned allowlist and the component's deployment.toml `allowed_host` entry.
## If no `[[outbound_http.allowed_host]]` entries are defined, all component outbound
## HTTP is denied. To migrate, copy the deployment entries here, then narrow them.
##
## Entries use the same fields as deployment.toml:
## - `pattern` matches scheme, host, and port. HTTPS and its default port are implied.
## - `methods = "*"` allows all methods; a list restricts them.
## - `request_url_regex` optionally matches `METHOD URL` without query parameters.
## - `secrets` names entries from `[secrets]`.
## - `replace_in` allows each named secret in "headers", "params", and/or "body".
##
## A destination must match an entry in both files. A secret placeholder is replaced
## at a request location only when matching entries in both files list that exact
## secret and replacement target.
# [[outbound_http.allowed_host]]
# pattern = "api.openai.com"
# methods = ["POST"]
# request_url_regex = "^POST https://api\\.openai\\.com/v1/"
# secrets = ["OPENAI_KEY"]
# replace_in = ["headers"]

## SQLite configuration (enabled by default)
# database.sqlite.directory = "${DATA_DIR}/obelisk-sqlite" # Path to sqlite directory. Supports path prefixes.
## Customize PRAGMA statements.
## Defaults are in `crates/db-sqlite/src/sqlite_dao.rs`.
# database.sqlite.pragma = { "cache_size" = "3000" }

## Postgres configuration, keys support environment variable interpolation.
# database.postgres.host =     "${POSTGRES_HOST}"
# database.postgres.user =     "${POSTGRES_USER}"
# database.postgres.password = "${POSTGRES_PASSWORD}"
# database.postgres.db_name =  "${POSTGRES_DATABASE}"
# database.postgres.provision_policy = "never" # One of "auto"|"never". If `auto` is selected, missing database will be created on startup.

## Global WASM Configuration
# [wasm]
## WASM Cache dir
## Path to directory where downloaded or transformed WASM files are stored. Supports path prefixes.
## By default "${CACHE_DIR}/wasm" or "./cache/wasm" if no valid home directory path could be retrieved from the operating system.
# cache_directory = "${CACHE_DIR}/wasm"
# allocator_config = "auto"                      # One of "auto"|"on_demand"|"pooling"
# global_executor_instance_limiter = "unlimited" # If set to an integer, limits the number of concurrent workflow and activity executions.
# global_webhook_instance_limiter = "unlimited"  # If set to an integer, limits the number of concurrent webhook requests.
# fuel = "unlimited"                             # If set to an integer, WASM instances consume fuel, details: https://docs.wasmtime.dev/api/wasmtime/struct.Store.html#method.set_fuel
# build_semaphore = "unlimited"                  # If set to an integer, limit the number of AOT compilations that can run in parallel
# parallel_compilation = true                    # Enable (default) or disable parallel AOT compilation of each WASM component.
# debug = false                                  # Enable debugging of WASM components: Instruct wasmtime to emit DWARF debug info and disable cranelift optimizations.

## Global Workflow Configuration
# [workflows]
# lock_extension_leeway.milliseconds = 100 # Deprecated, removed in 0.42: set `lock_extension_leeway` on each `[[workflow_wasm]]` / `[[workflow_js]]` instead. While set, it overrides the per-workflow value for every workflow.
# subscription_interruption.seconds = 1    # Interrupts listening for notifications periodically, needed for Postgres with a local-only subscription mechanism. Value can be "none" or a duration.
# max_replay_captured_writes = 100         # Max captured writes a single replay pass returns; on reaching it replay stops and returns that many as an advanceable prefix (advance them, then replay again to resume). Keeps a non-terminating workflow (e.g. an unresolved `joinNextTry` poll loop) advanceable in bounded batches.
# max_events_per_run = 100                 # Max history events a real workflow run writes before yielding and unlocking. Replay uses max_replay_captured_writes instead.
# response_refresh_interval = 32           # Refresh responses from the database after this many newly written non-blocking events while a workflow remains running. Usually set lower than max_events_per_run. Replay ignores it.

# [wasm.codegen_cache]
## Defaults:
# enabled = true
# directory = "${CACHE_DIR}/codegen" # Path to directory where AOT generated code is cached. Supports path prefixes.

## Timers Watcher Configuration
# [timers_watcher]
# enabled = true
# leeway.milliseconds = 500
# tick_sleep.milliseconds = 100


## Additional HTTP server definitions.
## Named HTTP servers can be referenced by webhook endpoint components (in deployment.toml) via `http_server = "name"`.
## The built-in "external" server (enabled by default at 127.0.0.1:9090) is always available without an explicit entry.
# [[http_server]]
# name = "my_server"
# listening_addr = "0.0.0.0:9000"
# max_inflight_requests = "unlimited" # If set to an integer, limits the number of inflight requests


### Send spans via gRPC to an OTLP collector.
# [otlp]
## Run `docker run --rm -it  -p 4317:4317 -p 16686:16686 jaegertracing/all-in-one:1.60` to start collecting traces.
# enabled = true
## Defaults:
# level = "info,app=debug"
# service_name = "obelisk-server"
# otlp_endpoint = "http://localhost:4317"

### Console logging configuration, by default logs INFO and above.
# [log.console]
## Defaults:
# enabled = true
# level = "info,app=trace"
# style = "plain_compact" # One of "plain","plain_compact","json"
# span = "none" # One of "none","new","enter","exit","close","active","full"
# target = false

### Sample (rolling) file configuration
# [log.file]
# enabled = true
# level = "info,obeli=debug,app=debug"
# style = "plain"                           # One of "plain","plain_compact","json"
# span = "none"                             # One of "none","new","enter","exit","close","active","full"
# target = false
# rotation = "daily"                        # One of "minutely"|"hourly"|"daily"|"never"
# directory = "."
# prefix = "obelisk_server_daily" # File name prefix

# [log.file]
# enabled = true
# target = true
# directory = "."
# prefix = "obelisk.log"

## Appendix: Path fields
# Path fields (sqlite/wasm/codegen directories) are `${VAR}` templates. A leading `~/` is
# expanded to the current user's home directory. Otherwise, `${NAME}` resolves the synthetic
# path variables below first, then process environment variables (synthetic names win on a
# collision). `${NAME:-default}` / `${NAME-default}` provide a fallback. A reference to an
# unset variable with no fallback fails at startup instead of creating a literal `${NAME}` dir.
#
# | Synthetic variable      | Default path           | Details
# | ${DATA_DIR}             | ~/.local/share/obelisk | https://docs.rs/directories/6.0.0/directories/struct.ProjectDirs.html#method.data_dir
# | ${CACHE_DIR}            | ~/.cache/obelisk       | https://docs.rs/directories/6.0.0/directories/struct.ProjectDirs.html#method.cache_dir
# | ${CONFIG_DIR}           | ~/.config/obelisk      | https://docs.rs/directories/6.0.0/directories/struct.ProjectDirs.html#method.config_dir
# | ${SERVER_CONFIG_DIR}    | N/A                    | Directory where the server.toml file is located
# | ${TEMP_DIR}             | /tmp                   | https://doc.rust-lang.org/std/env/fn.temp_dir.html

## Appendix: Environment variable interpolation
# Keys that support environment variable interpolation can use `${SOME}` to get the value of environment variable `SOME`.