Operator Guide

Environment Variables

Operator-controlled env layers, 1Password integration, and host-env forwarding for agent containers

jackin lets you set environment variables for agent containers at four scopes — global, per role, per workspace, and per (workspace × role). Values can be literal strings, references to host env vars, or references to 1Password items resolved through the op CLI.

Operator env vars are managed through jackin config env, jackin workspace env, or the Environments tab in the operator console's workspace editor (workspace and per-(workspace × role) scopes). You should not need to hand-edit any configuration file — the global scope is CLI-only today; the workspace scopes are reachable from both the CLI and the console.

Why operator env

Role manifests declare the env shape — what keys a role expects, what's interactive, what has a default. Operator env scopes declare the values for a specific operator on a specific workspace with a specific role. Keeping shape and values in different places means:

  • Third-party roles never see your secrets in their git history.
  • The same role can run with different credentials in different workspaces (personal laptop vs company monorepo).
  • You can override a manifest default without forking the role.

Scopes

Four scopes are merged with later-wins semantics — most-specific values take priority:

  1. Global — applies to every agent launch.
  2. Role — applies whenever this role is loaded.
  3. Workspace — applies whenever this workspace is loaded.
  4. Workspace × Role — applies only for this specific (workspace, role) cell.

Keys present in multiple scopes take the value from the highest-priority scope (4 > 3 > 2 > 1). Keys unique to any scope are preserved.

Setting values from the CLI

Use jackin config env for global and per-role values, and jackin workspace env for per-workspace and per (workspace × role) values:

# Global — applies to every agent launch
jackin config env set OPERATOR_ORG "acme-corp"

# Role scope — only when loading agent-smith
jackin config env set API_TOKEN "op://Personal/acme-api/token" --role agent-smith

# Workspace scope — only when launching in big-monorepo
jackin workspace env set big-monorepo ARTIFACT_REGISTRY '${COMPANY_REGISTRY_URL}'

# Workspace × Role — most specific, wins on conflict
jackin workspace env set big-monorepo API_TOKEN "op://Work/shared-smith/token" --role agent-smith

Values are stored verbatim — whatever you pass is what jackin resolves at launch time. List or remove values with jackin config env list / jackin config env unset (and the matching jackin workspace env subcommands).

Value syntax

Each value is one of:

SyntaxResolution
op://VAULT/ITEM/FIELDResolved via the 1Password CLI (op read "<ref>"). Requires op on PATH and an authenticated session.
$NAME or ${NAME}Read from the host's environment at launch time. Errors if the host var is unset.
Anything elseLiteral string.

When you load an agent with the example above in big-monorepo:

  • OPERATOR_ORG = "acme-corp" (literal; from global)
  • API_TOKEN = <resolved via op read "op://Work/shared-smith/token"> (workspace × role wins over role layer)
  • ARTIFACT_REGISTRY = <value of $COMPANY_REGISTRY_URL on host> (from workspace layer)

Reserved names

These names are owned by the jackin runtime and are rejected if set from any operator env scope (global, role, workspace, or workspace × role):

  • JACKIN
  • JACKIN_DIND_HOSTNAME
  • JACKIN_CONTAINER_NAME
  • JACKIN_INSTANCE_ID
  • JACKIN_AGENT
  • JACKIN_AGENT_CODENAME
  • JACKIN_ROLE
  • JACKIN_WORKDIR
  • JACKIN_GIT_COAUTHOR_TRAILER
  • JACKIN_GIT_DCO
  • DOCKER_HOST
  • DOCKER_TLS_VERIFY
  • DOCKER_CERT_PATH
  • TESTCONTAINERS_HOST_OVERRIDE
  • JACKIN_NETWORK_MODE
  • JACKIN_ALLOWED_HOSTS
  • JACKIN_FIREWALL_INSTALLED
  • JACKIN_NETWORK_ENFORCEMENT
  • JACKIN_SUDO

Trying to set one of these is rejected before the agent launches.

JACKIN_AGENT is scoped to an agent session, not the whole container. jackin passes the initial agent to the PID 1 multiplexer as an argv value, then sets JACKIN_AGENT only when spawning a real agent pane. Shell panes do not receive it.

Role identity, workspace workdir, supported agent slugs, and manifest model overrides are handed to Capsule through a generated launch config instead of being duplicated as container-wide environment variables. Runtime metadata needed by Capsule is injected by jackin at launch time and is not read from operator env scopes. The Capsule reference documents the internal handoff.

Telemetry

These variables control direct OTLP delivery; see Run Telemetry for setup examples and Application observability for the full contract.

VariableEffect
OTEL_EXPORTER_OTLP_ENDPOINTEnables direct OTLP export for traces, logs, and metrics through one base gRPC endpoint. The backend owns history; jackin does not write a local telemetry file.
OTEL_EXPORTER_OTLP_{TRACES,LOGS,METRICS}_ENDPOINTOverrides the endpoint per signal. jackin still exports over gRPC only.
OTEL_EXPORTER_OTLP_PROTOCOL / OTEL_EXPORTER_OTLP_{TRACES,LOGS,METRICS}_PROTOCOLMust be grpc or unset when an endpoint is configured; any other value stops startup with E016.
OTEL_EXPORTER_OTLP_HEADERS / OTEL_EXPORTER_OTLP_{TRACES,LOGS,METRICS}_HEADERSAdds standard comma-separated key=value gRPC metadata. Per-signal values override the generic value. Invalid names, empty values, malformed percent encoding, and non-ASCII metadata are rejected before providers start. Header values are credentials: they are never printed or added to telemetry.
OTEL_EXPORTER_OTLP_COMPRESSION / OTEL_EXPORTER_OTLP_{TRACES,LOGS,METRICS}_COMPRESSIONMust be gzip or unset. Other values are rejected before providers start.
OTEL_EXPORTER_OTLP_TIMEOUT / OTEL_EXPORTER_OTLP_{TRACES,LOGS,METRICS}_TIMEOUTPositive integer timeout in milliseconds. Per-signal values override the generic value; jackin caps each exporter deadline at five seconds.
OTEL_EXPORTER_OTLP_CERTIFICATE / OTEL_EXPORTER_OTLP_{TRACES,LOGS,METRICS}_CERTIFICATECA certificate path for TLS. Per-signal paths override the generic path. Paths are treated as sensitive configuration and are never telemetry fields.
OTEL_EXPORTER_OTLP_CLIENT_KEY + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE and per-signal variantsOptional mutual-TLS identity. Key and certificate must be configured together for each effective signal configuration; values and paths are never printed or exported.
OTEL_TRACES_SAMPLERMay be unset or parentbased_always_on. A conflicting sampler is rejected because jackin owns the fixed sampling contract.
OTEL_SERVICE_NAME / OTEL_RESOURCE_ATTRIBUTESValidated before provider startup, but they do not override the stable jackin service identity or inject arbitrary Resource attributes. Empty service names and malformed key=value resource entries are rejected; exported Resources remain allowlisted and process-stable.
OTEL_SDK_DISABLEDSet to true to disable OpenTelemetry provider and exporter activity explicitly.
JACKIN_DEBUGBacks the host --debug flag for operator-facing troubleshooting output. It does not enable delivery or create telemetry files.
JACKIN_TELEMETRY_LEVELOverrides [telemetry].level from config.toml: info (default), debug, or trace. Every level remains governed by the schema and privacy allowlist.
JACKIN_TELEMETRY_CATEGORIESOverrides [telemetry].categories from config.toml with a comma-separated debug-category allowlist such as docker,launch; * allows every registered debug category.

The host never forwards OTLP headers, client credentials, certificate paths, or arbitrary Resource attributes into a Capsule. Capsule export receives only routing and explicitly safe launch context when the network policy permits it; network.mode=none disables Capsule telemetry egress. jackin diagnostics validate requires a new exporter success for each signal, no new exporter failure or facade rejection, and a successful shared bounded flush. Host and Capsule daemon protocols expose typed sanitized telemetry health.

Host attach validation

JACKIN_HOST_ATTACH=1 is an opt-in host-side launch flag. Set it on the command that starts or attaches to an instance when testing host affordances:

JACKIN_HOST_ATTACH=1 jackin load <role>
JACKIN_HOST_ATTACH=1 jackin hardline <instance>

With this flag, the jackin host process owns the interactive attach loop instead of using the in-container docker exec -it /jackin/runtime/jackin-capsule client. That enables explicit host actions such as clipboard image staging, GitHub PR/CI opening, and file export. See Host Affordances for the current behavior and validation checklist.

JACKIN_PASTE_IMAGE_PATHS controls auto-staging of pasted host image paths under host attach. It is on by default: when a single paste's entire content is one absolute host path or file:// URL that resolves to a real image file, jackin stages the image and inserts the container path, which makes a normal Cmd+V paste work for screenshot tools that copy a file path. Set it to 0, false, no, or off to disable that and keep every paste as ordinary text:

JACKIN_HOST_ATTACH=1 JACKIN_PASTE_IMAGE_PATHS=0 jackin load <role>

JACKIN_OPEN_LINKS=deny disables jackin host browser-open actions while leaving ordinary terminal output and OSC 8 passthrough under their separate policies:

JACKIN_HOST_ATTACH=1 JACKIN_OPEN_LINKS=deny jackin load <role>

The same opt-out also accepts off and no. It suppresses explicit jackin actions such as GitHub Open PR, GitHub Open CI, visible URL modified-click, and Open link under cursor; it does not rewrite agent output or block native terminal hyperlink rendering.

Pane terminal defaults

Every shell and agent pane receives a stable terminal capability baseline:

TERM=xterm-256color
COLORTERM=truecolor

TERM=xterm-256color keeps the pane tied to a conservative terminfo entry that remains safe when a long-lived container is reattached from a different terminal app. COLORTERM=truecolor tells agent CLIs and TUIs that 24-bit color output is available by default. jackin sets this value directly instead of copying the host's COLORTERM, so a pane launched from Ghostty, Kitty, iTerm, Warp, SSH, or another xterm-compatible client sees the same deterministic environment.

1Password CLI setup

  1. Install the 1Password CLI.

  2. Sign in: eval $(op signin) (or unlock the desktop-app integration).

  3. Set values with op://... references — for example:

    jackin config env set ANTHROPIC_API_KEY "op://Personal/Anthropic/key"

Each jackin load that references op://... values shells out to op read <ref> per key. 1Password values are resolved concurrently, and op failures (missing item, expired session, binary not on PATH) are reported in a single message that names every failing key. Each launch-time op invocation has a 120-second timeout so cold 1Password app and daemon wakeups can finish without turning into false credential failures.

Prefer references picked through the 1Password picker in jackin or otherwise backed by 1Password IDs. The 1Password CLI can resolve human-readable vault and item names, but ID-backed references are the stable and efficient form for launch-time automation. jackin does not persist resolved secret values; it stores the reference metadata and asks op again when the value is needed.

Launch diagnostic

jackin prints a compact diagnostic line on launch when operator env is non-empty, so you can confirm at a glance which keys flowed into the container:

[jackin] operator env: 3 resolved (2 op://, 1 host ref, 0 literal)

In --debug mode, the diagnostic expands to per-key reference strings and scope attribution. Resolved secret values are never printed.

Interaction with manifest env

A role's manifest can declare env vars the role expects — including interactive prompts. Operator env is resolved first and pre-seeds matching manifest variables, so a configured value skips the manifest prompt. Manifest env fills in the remaining values, then operator env is overlaid on top: operator wins on key conflict. This lets you pin a value that the manifest would otherwise prompt for, or swap a manifest default for a workspace-specific secret.

Built-in agent credential keys stay selected-runtime scoped. If a manifest declares a sibling runtime credential such as OPENAI_API_KEY during a Claude Code launch, jackin leaves that prompt/value lazy unless the selected runtime's auth mode needs that exact key. Generic manifest env vars still resolve normally.

See Authentication Forwarding for the companion mechanism that forwards Claude Code credentials from host to container. Env scopes and auth forwarding are orthogonal — use both.

On this page