Skip to main content

Configure your environment

After successfully setting up your server and installing the Powerhouse services using the ph service setup command as described in the Setup Environment guide, the next crucial step is to configure your environment.

Powerhouse Connect reads its runtime configuration from powerhouse.config.json. Editing that file (or using the ph connect config CLI) is the recommended way to tune Connect's behavior — drives, renown integration, packages, log level, base path, and so on. Environment variables remain available as a legacy / CI mechanism for seeding the same fields at build time, but the JSON file is the source of truth at runtime.

This guide walks you through the configuration model and shows you how to set values via JSON, the CLI, or env vars.

Where the configuration lives​

A scaffolded Powerhouse project ships with powerhouse.config.json at the project root. Connect-specific settings live under the connect key:

{
"$schema": "https://raw.githubusercontent.com/powerhouse-inc/powerhouse/main/packages/shared/clis/source-config.schema.json",
"documentModelsDir": "./document-models",
"editorsDir": "./editors",
"studio": { "port": 3000 },
"reactor": { "port": 4001 },
"packages": [],
"connect": {
"app": {
"basePath": "/",
"logLevel": "info"
},
"packages": {
"externalEnabled": true
},
"drives": {
"allowAddDrive": true,
"defaultDrives": [],
"sections": {
"remote": { "enabled": true, "allowAdd": true, "allowDelete": true },
"local": { "enabled": true, "allowAdd": true, "allowDelete": true }
}
},
"renown": {
"url": "https://www.renown.id",
"networkId": "eip155",
"chainId": 1
}
}
}

The dist served by ph connect build deep-merges the project file with the schema defaults, so missing fields fall back automatically.

Precedence​

When the dist powerhouse.config.json is built, values resolve in this order (lowest to highest):

  1. Schema defaults (DEFAULT_CONNECT_CONFIG) — always present.
  2. Env-var seeds — set-if-absent; only fill fields the source file does not specify (see Build-time env-var seeds below for the list).
  3. powerhouse.config.json (project root) — the operator's source of truth.
  4. ph connect build --json — bulk override; applied last and beats source + seeds.
  5. ph connect build --<flag> — individual flag overrides; applied above --json for the fields they cover.

At runtime Connect always reads the resulting dist file as-is — it does not consult process.env for any field in the runtime schema.

Editing the JSON​

Manually​

Open powerhouse.config.json in any editor and edit the connect.* block. Save, then rebuild and restart:

ph connect build
ph service restart

Via ph connect config​

The CLI provides positional, flag, and bulk-JSON read/write access to every connect.* field. The same surface works on ph connect build and ph connect config — pick whichever fits your workflow (build-time vs. live edit on a deployed dist).

# Show the effective connect.* block (list mode)
ph connect config

# Read a single value — positional <key>, or equivalently --get
ph connect config connect.renown.url
ph connect config --get connect.renown.url

# Set a single value — positional <key> <value>, or equivalently a per-field flag
ph connect config connect.renown.url "https://renown.staging.example"
ph connect config connect.renown.chainId 137
ph connect config connect.drives.allowAddDrive false
ph connect config --renown-url "https://renown.staging.example"
ph connect config --renown-chain-id 137
ph connect config --allow-add-drive false

# Bulk update via JSON patch (required for arrays/objects; useful for multi-field changes)
ph connect config --json '{"renown":{"url":"https://x"},"drives":{"sections":{"remote":{"enabled":false}}}}'

Positional <value> is JSON-parsed first (so 137 → number, false → boolean) then schema-validated against the path. Strings without quotes pass through as bare strings. Arrays and objects should go through --json instead.

Writes are dual-target: the source powerhouse.config.json is updated (next build picks it up) and, if the dist file exists, it is patched as well (the currently-served SPA picks up the change on its next refresh). Invalid types fail loudly before any write; both positional and --json payloads are Ajv-validated against the runtime schema.

Mutually exclusive: positional <key> / <key> <value>, --get, --json, and any field flag can't be combined in one call — pick exactly one mode per invocation.

At build time via positional / flags / JSON​

ph connect build accepts the same positional <key> <value> pair, per-field flags, and --json to bake values into the dist:

# Positional override (single field)
ph connect build connect.renown.url https://renown.staging.example

# Per-field flags (combinable)
ph connect build \
--renown-url https://renown.staging.example \
--renown-chain-id 137 \
--allow-add-drive false \
--remote-drives-enabled true \
--app-name "My Connect"
ph connect build --json '{"renown":{"url":"https://x"},"drives":{"allowAddDrive":false}}'

The --json payload is the connect.* block without the connect wrapper, as nested objects. Dotted keys ({"app.workflowsEnabled":true}), a {"connect":{...}} wrapper, unknown keys, and wrong types fail the command with a validation error. For example, to enable workflows and add a default drive:

ph connect build --json '{"app":{"workflowsEnabled":true},"drives":{"defaultDrives":[{"url":"https://switchboard.example/d/my-workflows","name":"My workflows"}]}}'

Overrides apply at dist-emit time and are baked into the dist file — operators see the resulting values when the container boots.

Full flag matrix​

Every connect.* field has a dedicated flag. Both ph connect config and ph connect build accept the same set.

connect.* JSON pathFlagType
connect.app.basePath--basestring
connect.app.logLevel--log-leveldebug | info | warn | error
connect.packages.externalEnabled--external-packagesboolean
connect.packages.registryUrl--packages-registrystring
connect.branding.appName--app-namestring
connect.branding.homeBackground--home-backgroundstring (pass "" to reset to bundled image)
connect.drives.allowAddDrive--allow-add-driveboolean
connect.drives.defaultDrives--default-drives-urlcomma-list → array of {url, name, icon}
connect.drives.preserveStrategy--drive-preserve-strategypreserve-all | preserve-by-url-and-detach
connect.drives.sections.remote.enabled--remote-drives-enabledboolean
connect.drives.sections.remote.allowAdd--remote-drives-allow-addboolean
connect.drives.sections.remote.allowDelete--remote-drives-allow-deleteboolean
connect.drives.sections.local.enabled--local-drives-enabledboolean
connect.drives.sections.local.allowAdd--local-drives-allow-addboolean
connect.drives.sections.local.allowDelete--local-drives-allow-deleteboolean
connect.renown.url--renown-urlstring
connect.renown.networkId--renown-network-idstring
connect.renown.chainId--renown-chain-idnumber
(bulk, any subset of fields)--json '{...}'partial connect.* blob, no connect wrapper

Plus ph connect config --get <connect.path> to read a single value, ph connect config --dist-dir <path> to point at a non-default dist location (overrides PH_CONNECT_OUTDIR).

Configuring Connect's runtime values​

Connect's runtime configuration (everything under connect.* in powerhouse.config.json — branding, drives, renown, app, packages) is set from one of three sources, in increasing precedence:

  1. The source file powerhouse.config.json (project root) — hand-edited or generated by ph init.
  2. ph connect config --<field> — dual-writes the value into the source file and the running dist file, so the SPA picks it up on the next refresh without a rebuild.
  3. ph connect build --<field> / --json — applies as a CLI override for the build, written into the emitted dist file.

Environment variables are not a source for Connect's runtime config. The table above lists each connect.* field together with its CLI flag.

Docker deployments​

When deploying Connect's Docker image, the entrypoint applies the operator-supplied PH_CONNECT_CONFIG_JSON env var to the dist powerhouse.config.json at container start (operator-wins: concrete values override the baked file; null/omitted keep it; connect.app.basePath is ignored). This is purely an operator-time convenience — the SPA itself never reads env vars at runtime — and is documented in the Docker Deployment guide.

Variables that stay as env vars​

The following are not runtime-config fields. They remain ordinary env vars because they are secrets, build-stamped metadata, or container-shape concerns:

# Sentry (secrets / per-deploy)
PH_SENTRY_AUTH_TOKEN=""
PH_SENTRY_ORG=""
PH_SENTRY_PROJECT=""
PH_CONNECT_SENTRY_DSN=""
PH_CONNECT_SENTRY_ENV="prod"
PH_CONNECT_SENTRY_TRACING_ENABLED="false"
PH_CONNECT_SENTRY_RELEASE=""

# Build-stamped metadata
PH_CONNECT_VERSION="..." # baked into the bundle at build time
PH_CONNECT_CLI_VERSION="..." # baked into the bundle at build time

# Container shape
PORT=3001

Configuring authorization (Switchboard)​

A critical aspect of your environment configuration is setting up authorization to control who can access your services and what they can do. As detailed in our dedicated Switchboard Authorization guide, you can manage access using authentication, supreme admin access, and document protection.

Authorization is a Switchboard concern, not Connect. The same powerhouse.config.json carries both:

{
"switchboard": {
"auth": {
"enabled": true,
"admins": ["0x123...", "0x456..."]
}
}
}

Or via env vars:

AUTH_ENABLED=true
ADMINS="0x123...,0x456..."
DEFAULT_PROTECTION=true
DOCUMENT_PERMISSIONS_ENABLED=true

For a complete understanding of how authorization (authentication, admin access, and document protection) works, please refer to the full Authorization guide.

Configuring workflows​

One setting in powerhouse.config.json turns workflows on for both Switchboard and Connect:

{
"workflows": { "enabled": true }
}

In Switchboard it starts the workflow runtime: trigger watching, runs, step execution. In Connect it loads Workflow Studio and the workflow and connection editors. It defaults to off.

ph vetra also seeds a drive named Workflows (slug workflows) that opens in Workflow Studio, and adds it to Connect's default drives.

To set Connect apart, give it connect.app.workflowsEnabled, which wins over workflows.enabled when present. For example, a Connect that browses workflows running on another reactor:

{
"connect": { "app": { "workflowsEnabled": true } }
}

Or via env vars:

PH_WORKFLOWS_ENABLED=true

PH_WORKFLOWS_ENABLED also accepts 1 and 0, and it overrides workflows.enabled in the config file.

Connect has no env var: it follows the config file, or ph connect build --workflows true.

Beyond the switch, the runtime reads a handful of PH_WORKFLOWS_* variables for things an operator tunes: run concurrency, poll and webhook intervals, the file-size ceiling, and the two below. Each is declared with its type, default and purpose in the config block of the @powerhousedao/workflow package manifest, which is the list to read rather than a copy of it here.

Two are worth naming, because leaving them out fails in ways that are hard to diagnose:

# 32 bytes of hex encrypting stored connection secrets. Required when the
# database is Postgres. Unset on PGlite, the runtime generates a key next to its
# working directory. A key other than the one the secrets were stored with is
# refused, so keep it: a lost key means re-entering every secret.
PH_WORKFLOWS_SECRETS_MASTER_KEY=<64 hex chars>

# Addresses a piece may reach, widening a policy that refuses private and
# loopback space by default. Without it a step pointed at a service on your own
# machine or network fails to connect.
PH_WORKFLOWS_EGRESS_ALLOW_ADDRESSES=127.0.0.1/32,::1/128

ph vetra and ph switchboard --dev add 127.0.0.1/32,::1/128 to PH_WORKFLOWS_EGRESS_ALLOW_ADDRESSES themselves, keeping any addresses already in it, so pieces can reach services on your machine during development.

Webhook origin. A webhook URL the runtime hands out uses PUBLIC_URL, then RENDER_EXTERNAL_URL, then HEROKU_APP_DEFAULT_DOMAIN_NAME, and falls back to http://localhost:<port>. Set one of them wherever a provider has to reach the reactor. This is not PH_SWITCHBOARD_PUBLIC_URL, which sets the attachment service URL.

PUBLIC_URL=https://switchboard.example.com

Pieces from a registry. The runtime also reads pieces from the registry Switchboard installs packages from (packageRegistryUrl in powerhouse.config.json, or PH_REGISTRY_URL), ahead of the Activepieces catalogue. There is no separate setting for it.

:::note Variable names changed These names carry the PH_WORKFLOWS_ prefix as of the release that introduced it. Earlier releases read them unprefixed — PH_SECRETS_MASTER_KEY, WORKFLOW_EGRESS_ALLOW_ADDRESSES, WORKFLOW_RUN_CONCURRENCY and so on — with no fallback, so check which your installed version expects if a setting appears to be ignored. The config block of the installed package's manifest is authoritative for the version you actually have. :::

Applying your changes​

Regardless of which method you use to update your configuration, the changes will not be applied until the service that consumes them restarts (or, in the case of the running SPA, the page is refreshed and re-fetches /powerhouse.config.json).

ph service restart

This stops and restarts Connect and Switchboard so they pick up the new configuration. You can check the status with ph service status.

Summary​

Configure Connect via powerhouse.config.json — edit the file directly, use ph connect config <key> <value>, or pass --flag / --json overrides to ph connect build. Env vars stay supported as build-time seeds for CI / docker workflows but are no longer the recommended interface. Secrets, build metadata, and container shape (sentry tokens, version stamps, PORT) remain as ordinary env vars.