F
Flowman docsWorkflow SDK
Back to app
All docs

Environment variables

Per-project secrets and configuration live in the Flowman app — not in a checked-in .env file for tenant workflows. In the project sidebar, open Environment variables (key icon, between Activity and Settings). There you can add, edit, or remove keys. Values stay hidden by default until you reveal them; use the copy control when you need the raw value.

URL in the app

The page route is /p/<project-slug>/environment. Replace <project-slug>with your active project's slug (same segment as in the address bar for Dashboard, Workflow Runs, etc.).

How they reach a workflow

When a workflow run starts, createWorkflowRoute loads every key you saved for that project and attaches them to the record as record.env — a snapshot for this run only. If you change project env in the UI later, runs that already started keep their original snapshot.

Your orchestrator receives a FlowmanRunRecord with record.env: a plain object Record<string, string>of uppercase keys to string values. Host deployment environment variables (e.g. Flowman's own Convex wiring) remain separate — use project env for anything each customer should supply (API keys, IMAP passwords, etc.).

Cloud Cursor coding sessions also receive this run snapshot in the remote agent shell, so tools and scripts running inside the Cursor cloud VM can read the same keys (for example STAGING_API_TOKEN) without checking them into the repository.

Codex cloud also receives the complete run snapshot. Flowman uploads it as a private shell environment file inside each OpenAI Hosted Shell container and requires agent commands to source it. Values marked sensitive remain subject to Flowman output redaction. The container is ephemeral, and the snapshot is deleted when the container expires.

Local Codex sessions receive the same immutable run snapshot through the app-server thread environment policy, including when a persisted thread is resumed. Local Cursor applies that snapshot to the coding-agent runtime process for the duration of each Cursor call so local tool and skill commands can read the same keys. Keys prefixed with CURSOR_stay excluded. Cursor Local calls that touch process env run one at a time so one project's secrets are not visible to another concurrent Cursor turn. Flowman restores the previous process values when the call ends.

For Codex cloud networking, any key named CONVEX_DEPLOYMENT or ending in _CONVEX_DEPLOYMENT automatically contributes its Convex cloud hostname. For example, dev:chatty-ibex-315 allows chatty-ibex-315.convex.cloud. Do not repeat inferred Convex deployment domains in OPENAI_CLOUD_ALLOWED_DOMAINS; keep that variable for other project-specific domains.

Naming keys

Keys are normalized to match ^[A-Z][A-Z0-9_]*$ (for example OPENAI_API_KEY, IMAP_HOST). Align names with what built-in step actions expect, or with your own code.

Jira intake keys

The coding board's Intake and Refined columns reads its Jira credentials from this page: JIRA_BASE_URL, JIRA_EMAIL, JIRA_API_TOKEN (mark this one sensitive), and JIRA_QUEUE_ID. Qualify every queue with its Jira project key, for example FS:53,CA:13. Flowman trims whitespace, ignores empty entries, uppercases project keys, and deduplicates exact project-and-queue pairs. Bare numeric queue IDs are invalid because the same number can identify different queues in different service desks. Optional: JIRA_INTAKE_MAX_ISSUES. Until all four required keys are valid, the Intake column shows the missing keys or configuration error and its refresh control stays disabled. The maximum applies once across the combined, issue-ID-deduplicated refresh. Successful queues are still applied when another project or queue fails, while uncertain tickets are preserved and the Intake feedback reports the qualified failure or truncation.

Intake refinement also uses these values on the selected Codex Local or Cursor Local runtime. The Jira account must be a service-desk agent in every configured project and be able to list request types and their fields, raise requests on behalf of recognized Jira customers, upload public request attachments, read protected attachments, add internal (non-customer-visible) comments, edit issue labels, and edit issue summary and description from the Intake detail drawer. Flowman does not invite Jira customers automatically: every Flowman member or customer who creates a ticket must already be recognized as a customer by the selected Jira service project. The project portion of each configured queue also determines the Jira projects offered on the New Ticket page; customer accounts and Customer View are restricted to assigned queues. Flowman verifies the posted comment and Refined label with Jira before moving a ticket out of Intake.

Using env inside a workflow

Shared helpers readEmails and aiInvoke already read from record.env — configure the matching keys in the UI (readEmails, aiInvoke). For custom steps, import from @/workflows/shared/env:

typescript
import type { FlowmanRunRecord } from "@/lib/flowman-route";
import { requireEnv, optionalEnv } from "@/workflows/shared/env";

async function callExternalApi(record: FlowmanRunRecord<{ q?: string }>) {
  "use step";

  const apiKey = requireEnv(record, "MY_API_KEY");
  const baseUrl = optionalEnv(record, "MY_API_BASE_URL") ?? "https://api.example.com";
  // use apiKey, baseUrl ...
}
  • requireEnv(record, "KEY") — throws if missing or empty (step fails clearly in the timeline).
  • optionalEnv(record, "KEY") — returns undefined if unset.

Always pass the same record your workflow received into step helpers so every step sees the same snapshot.

Env key params

Some workflows accept a parameter whose value is the name of an environment variable. For example, a workflow can accept tokenEnvKey with a value like FYVE_API_TOKEN. The workflow resolves that key from record.env when the run starts. This lets manual runs and triggers choose test or production credentials without storing secret values in workflow input. Parameters registered with lookup: "projectEnvKey" use a searchable picker backed by this project's env keys.

Connection profile secrets

HTTP connection profiles under /p/<project-slug>/connections store reusable base URLs, headers, retry settings, and auth mode. They do not store raw bearer tokens, passwords, or API keys. Instead, set the secret here as a sensitive environment variable, then reference its key from the profile, for example FYVE_API_TOKEN. Login bearer profiles use the same pattern for login JSON fields such as API_EMAIL and API_PASSWORD.

Host runtime variables

Some Flowman platform settings are deployment/runtime variables, not project workflow variables. Trigger dispatch is one example: Convex must call the running Next.js app through a public URL, so set FLOWMAN_APP_URL or NEXT_PUBLIC_APP_URLin the host/Convex environment, not in a project's Environment variables page.

Coding-agent runtime hosts also need NEXT_PUBLIC_CONVEX_URL, CODING_AGENT_RUNTIME_TOKEN from the selected runtime environment and FLOWMAN_ENVIRONMENTset to that environment's slug. Repository paths are configured per environment in the Coding repository sheet because each host can mount the same repository at a different local path.

Connector-runtime hosts need NEXT_PUBLIC_CONVEX_URL and CONNECTOR_RUNTIME_TOKEN. Run only one connector-runtime unless you intentionally want multiple hosts polling the same enabled connector set.

Pull request completion uses a service token because the GitHub webhook and completion skill update PR state outside the browser. Set FLOWMAN_PR_COMPLETION_TOKEN on both the Next.js host and Convex deployment, or let it fall back to FLOWMAN_INTERNAL_DISPATCH_TOKEN.

For local trigger testing, expose http://localhost:4208 through a public zrok tunnel, then set FLOWMAN_APP_URL on the Convex cloud deployment with pnpm exec convex env set. See Zrok setup and Triggers and events for the full dispatch path.