Resources and Secrets
Integration resources, cluster secrets, and how they reach running flows.
Two stores configure what a deployed integration runs with: resources — env files and templates authored per integration, versioned with its tags — and cluster secrets — sensitive values stored once per cluster and bound to deployments by reference. Together with per-deployment env bindings they supply everything a definition's env declarations need.

Integration resources
Resources are the platform counterpart of the files the standalone runtime reads from its config directory. Each resource belongs to one integration and has:
kind—env(a.env-convention file combined into the runtime environment) ortemplate(a text template rendered by flows — see Resources).name— the id the definition references. Names are path-like (they may contain/, for future bundle uploads) but must stay relative: no leading/, no.., no empty segments.content— the raw text.
The working copy of a resource is mutable through the editor or MCP; the REST surface is POST/GET /integrations/{id}/resources and GET/PUT/DELETE /integrations/{id}/resources/{resourceId}. A name is unique per integration.
Resources are versioned with tags
Creating a version tag freezes a copy of the integration's resources alongside its definition, in the same transaction. A deploy ships the tag's frozen resources — later edits to the working copy don't touch running deployments.
How resources reach a running pod
A deployed pod carries its snapshot id (OCTO_SNAPSHOT_ID). At load time, the runtime's resource loader fetches each declared resource from the orchestrator's frozen-resource endpoint (GET /snapshots/{id}/resources/content) — env resources are folded into the environment, templates are served to template-resource blocks and the templateResource() function.
Cluster secrets
Cluster secrets hold sensitive values — API keys, connection strings — once per cluster:
- Values live only in Kubernetes, as keys of a single shared Secret (
octo-secrets) in the platform namespace. The database keeps a catalog of names and timestamps only; no API ever returns a value. - Set with
PUT /secrets/{name}(creating or overwriting), list names withGET /secrets, delete withDELETE /secrets/{name}. - Deletion is guarded: deleting a secret that a deployment still references is refused (it would break that workload on its next restart), unless forced.
At deploy time you bind a declared env var to a secret by name. The orchestrator validates the secret exists, then injects it into the pod as a secretKeyRef env var — the deployment record stores only the secret's name, never its value. A pod referencing a since-deleted key fails to start visibly rather than running without the value.
Cluster secrets are for deploy-time configuration. Secrets that flows write at runtime (e.g. rotating tokens) go through the runtime secret store, which the platform backs with encrypted KV namespaces — see KV Store and Persistence.
How values reach flows, and precedence
A deployed runtime resolves each declared env var with the standard precedence — the platform just supplies the sources:
- Container environment — always wins. This is where deploy-time bindings land: literal values and secret references both become container env vars, alongside the orchestrator-managed
HTTP_PORT/HTTP_HOST. - Env resources — the tag's frozen
.envfiles, loaded by the runtime in declared order. - Declared
default— the fallback in the definition itself.
Consequences worth knowing:
- A binding left empty in the deploy dialog injects nothing — so an env-resource value (or a default) still applies instead of being clobbered by a blank.
- A
requiredvariable must be provided by a binding or a frozen env resource; a default does not satisfy it. The deploy (or rollout) is rejected up front when one is missing. HTTP_PORTandHTTP_HOSTare orchestrator-managed and cannot be bound.
The deploy dialog reflects all of this: it lists the tag's declared variables, marks the ones its frozen .env resources already satisfy, and prompts for the rest.