# Deploying Workflows
Source: https://docs.chain.link/cre/guides/operations/deploying-workflows
Last Updated: 2026-04-30

> For the complete documentation index, see [llms.txt](/llms.txt).

> **NOTE: Early Access required**
>
> Workflow deployment is currently in Early Access. Run `cre account access` or visit <a href="https://app.chain.link/cre/request-access" target="_blank" rel="noopener noreferrer">app.chain.link/cre/request-access</a> to submit a request. See [Requesting Deploy Access](/cre/account/deploy-access) for details.

**While you wait:** Continue building and simulating workflows using [`cre workflow simulate`](/cre/guides/operations/simulating-workflows).

When you deploy a workflow, you take your locally tested code and register it with a **workflow registry** so it can activate and respond to triggers across a [Decentralized Oracle Network (DON)](/cre/key-terms#decentralized-oracle-network-don). CRE supports two registry models today:

- **Public workflow**: Workflow management goes through the onchain Workflow Registry contract on Ethereum Mainnet. Use `deployment-registry: "onchain:ethereum-mainnet"`.
- **Private workflow**: Workflow management goes through the Chainlink-hosted private registry. Use `deployment-registry: "private"`.

This is a control-plane choice for workflow management: deploy, update, activate, pause, delete, and related ownership. It is not an execution-privacy setting.

> **NOTE: Private is not confidential**
>
> A private workflow uses a private, centralized, offchain registry for workflow management. It does not make workflow execution confidential. Confidential execution is a separate execution-plane feature. A workflow can use confidential execution or a confidential capability while still using the public onchain registry, and a workflow can use the private registry without being confidential.

## Prerequisites

Before you can deploy a workflow, you must have:

- **Early Access approval**: Workflow deployment is currently in Early Access. Run `cre account access` to check your status or submit a request. See [Requesting Deploy Access](/cre/account/deploy-access).
- **[Authenticated](/cre/reference/cli/authentication)**: Logged in via `cre login` or using an [API key](/cre/reference/cli/authentication#api-key-authentication) (`CRE_API_KEY`). To verify, run `cre whoami`.
- **(Optional) `deployment-registry` in `workflow.yaml`**: New in CRE CLI v1.14.0. When omitted, the CLI defaults to the public onchain Workflow Registry (existing behavior). Set this field to `"private"` to use the Chainlink-hosted private registry, or to `"onchain:ethereum-mainnet"` to explicitly target the onchain registry. Run `cre registry list` to see which registries are available to your organization.
- **(Onchain registry only) [Linked your key](/cre/reference/cli/account#cre-account-link-key)**: Required only when the target's `deployment-registry` is set to `onchain:ethereum-mainnet`. Link your EOA or multi-sig wallet to your account by running `cre account link-key`. Workflows deployed to the `private` registry do not need a linked key.
- **(Onchain registry only) A funded wallet**: The deploying account must hold ETH on Ethereum Mainnet to pay gas for the registration transaction. Not required for the `private` registry.

## Choosing your registry

Each target deploys to exactly one registry, selected by the `user-workflow.deployment-registry` field in `workflow.yaml`. Run `cre registry list` to see which registries are available to your organization:

```bash
cre registry list
```

**Example output:**

```
Registries available to your organization

ethereum-mainnet (0x4Ac5...E7e5)
  ID:   onchain:ethereum-mainnet
  Type: on-chain
  Addr: 0x4Ac54353FA4Fa961AfcC5ec4B118596d3305E7e5

Private (Chainlink-hosted)
  ID:   private
  Type: off-chain
```

Use the `ID` value as the value of `deployment-registry` in your `workflow.yaml`.

### Private vs. public workflow management

CRE exposes two ways to manage the lifecycle of a workflow (deploy, activate, pause, update, delete) and its secrets — together, this is the **control plane**. Pick per target by setting `deployment-registry`:

| Workflow management model           | `deployment-registry` value  | How management is authorized                                                                   | Key and gas requirements                                                                        |
| ----------------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| Public workflow / onchain registry  | `"onchain:ethereum-mainnet"` | A transaction signed by your linked web3 key updates the public Workflow Registry contract.    | Requires `cre account link-key`, an Ethereum Mainnet RPC, and ETH for registry transaction gas. |
| Private workflow / private registry | `"private"`                  | Your CRE login session authorizes the operation against the Chainlink-hosted private registry. | No linked key, no Ethereum Mainnet RPC, and no gas for registry management.                     |

Use the private registry when you want centralized, offchain workflow management, especially for lower-friction testing and team-managed workflows. Use the public onchain registry when workflow lifecycle operations must be recorded on the public Workflow Registry contract.

Secrets follow the same authorization split. See [Managing with a web3 key](#managing-with-a-web3-key) and [Managing with auth only](#managing-with-auth-only) below for the per-flow specifics, and [Using Secrets with Deployed Workflows](/cre/guides/workflow/secrets/using-secrets-deployed) for the secrets equivalent.

### Managing with a web3 key

Use this flow when `deployment-registry: "onchain:ethereum-mainnet"`:

1. Link your EOA or multi-sig wallet to your organization with `cre account link-key`. See [Linking Wallet Keys](/cre/organization/linking-keys).
2. Set `CRE_ETH_PRIVATE_KEY` in your `.env` and add an RPC URL for `ethereum-mainnet` to your `project.yaml`.
3. Run `cre workflow deploy` (or `activate`, `pause`, `delete`, `update`). Each command builds a transaction, prompts you to confirm, and submits it onchain. The Workflow Registry emits an event tying the workflow ID to your wallet address — that address is the workflow's owner and is what you'll see on the CRE platform UI.
4. For multi-sig wallets, pass `--unsigned` to print the raw transaction data instead of broadcasting. See [Using Multi-sig Wallets](/cre/guides/operations/using-multisig-wallets).

### Managing with auth only

Use this flow when `deployment-registry: "private"`:

1. Log in once with `cre login`.
2. Run `cre workflow deploy` (or `activate`, `pause`, `delete`, `update`). The CLI authorizes the operation against the Chainlink-hosted registry using your CRE login session. No `.env` private key, no wallet linking, and no Ethereum Mainnet RPC are required for these commands.
3. Workflows show as `private` in the CRE platform UI. The `Owner` is your CRE organization rather than a wallet address.

For a complete step-by-step walkthrough, see [Deploying to the Private Registry](/cre/guides/operations/deploying-to-private-registry).

If a target needs to deploy to the onchain registry but you have no `CRE_ETH_PRIVATE_KEY` configured, the CLI errors out before submitting anything (e.g., `failed to load settings: failed to parse private key. Please check CRE_ETH_PRIVATE_KEY in your .env file or system environment`).

## The deployment process

The `cre workflow deploy` command handles the entire end-to-end process for you:

1. **Compiles** your workflow to a WASM binary.
2. **Uploads** the compiled binary and any associated configuration files (like your config file or `secrets.yaml`) to the CRE Storage Service.
3. **Registers** the workflow with the registry selected by `user-workflow.deployment-registry`:
   - **`onchain:ethereum-mainnet`** — submits a transaction to the Workflow Registry contract on **Ethereum Mainnet**. Your wallet must have ETH for gas fees, and your `project.yaml` must include an RPC configuration for `ethereum-mainnet` (e.g., `https://ethereum-rpc.publicnode.com`). The transaction contains the workflow's name, owner, and artifact URLs.
   - **`private`** — registers the workflow with the Chainlink-hosted private registry, authorized by your CRE login session. No transaction, gas, or Ethereum Mainnet RPC is required for registry management.

> **CAUTION: Early Access: Disclaimer**
>
> Chainlink Runtime Environment (CRE) deployment is in the "Early Access" stage of development, which means that CRE currently has functionality which is under development and may be changed in later versions. By using CRE, you expressly acknowledge and agree to accept the Chainlink <a href="https://chain.link/terms" target="_blank" rel="noopener noreferrer">Terms of Service</a>, which provides important information and disclosures.

### Step 1: Ensure your configuration is correct

Before deploying, ensure your `workflow.yaml` file is correctly configured. The `workflow-name` field is required under the `user-workflow` section for your target environment. The `deployment-registry` field is optional — when omitted, the CLI defaults to the public onchain Workflow Registry.

If you are deploying to the onchain registry from a multi-sig wallet, specify your multi-sig address in the `workflow-owner-address` field. If you are deploying to the onchain registry from a standard EOA, you can leave this field unchanged—the owner will be automatically derived from the `CRE_ETH_PRIVATE_KEY` in your `.env` file. Private registry deployments use your CRE login session for workflow management and do not require `workflow-owner-address`.

For more details on configuration, see the [Project Configuration](/cre/reference/project-configuration) reference.

### Step 2: Run the deploy command

**From your project root directory**, run the `deploy` command with the path to your workflow folder.

```bash
cre workflow deploy <workflow-folder-path> [flags]
```

Example command to target the `production-settings` environment:

```bash
cre workflow deploy my-workflow --target production-settings
```

**Available flags:**

| Flag             | Description                                                                             |
| ---------------- | --------------------------------------------------------------------------------------- |
| `--target`       | Sets the target environment from your configuration files (e.g., `production-settings`) |
| `--output`       | The output file for the compiled WASM binary (default: `"./binary.wasm.br.b64"`)        |
| `--wasm`         | Path to a pre-built WASM binary (skips compilation). Useful in CI/CD pipelines          |
| `--config`       | Override the config file path from `workflow.yaml`                                      |
| `--no-config`    | Deploy without a config file                                                            |
| `--unsigned`     | Return the raw transaction instead of broadcasting it to the network                    |
| `--yes`          | Skip confirmation prompts and proceed with the operation                                |
| `--project-root` | Path to the project root directory                                                      |
| `--env`          | Path to your `.env` file (default: `".env"`)                                            |
| `--verbose`      | Enable verbose logging to print `DEBUG` level logs                                      |

### Step 3: Monitor the output

The CLI will provide detailed logs of the deployment process, including compilation, upload to the CRE Storage Service, and the registry operation. Public onchain deployments include transaction details; private registry deployments do not submit an Ethereum Mainnet transaction.

**Example onchain registry output:**

```bash
> cre workflow deploy my-workflow --target production-settings

Deploying Workflow :     my-workflow
Target :                 production-settings
Owner Address :          <your-owner-address>

Compiling workflow...
Workflow compiled successfully

Verifying ownership...
Workflow owner link status: owner=<your-owner-address>, linked=true
Key ownership verified

Uploading files...
✔ Loaded binary from: ./binary.wasm.br.b64
✔ Uploaded binary to: https://storage.cre.example.com/artifacts/<workflow-id>/binary.wasm
✔ Loaded config from: ./config.json
✔ Uploaded config to: https://storage.cre.example.com/artifacts/<workflow-id>/config

Preparing deployment transaction...
Preparing transaction for workflowID: <your-workflow-id>
Transaction details:
  Chain Name:   ethereum-mainnet
  To:           0x4Ac54353FA4Fa961AfcC5ec4B118596d3305E7e5
  Function:     UpsertWorkflow
  Inputs:
    [0]:        my-workflow
    [1]:        my-workflow
    [2]:        <your-workflow-id>
    [3]:        0
    [4]:        zone-a
    [5]:        https://storage.cre.example.com/artifacts/<workflow-id>/binary.wasm
    [6]:        https://storage.cre.example.com/artifacts/<workflow-id>/config
    [7]:        0x
    [8]:        false
  Data:         b377bfc50000000000000000000000000000000000...
Estimated Cost:
  Gas Price:      0.00100001 gwei
  Total Cost:     0.00000079 ETH
? Do you want to execute this transaction?:
  ▸ Yes
    No

Transaction confirmed
View on explorer: https://etherscan.io/tx/0x58599f6...d916b

✓ Workflow deployed successfully

Details:
   Registry:         onchain:ethereum-mainnet
   Contract address: 0x4Ac54353FA4Fa961AfcC5ec4B118596d3305E7e5
   Transaction hash: 0x58599f6...d916b
   Workflow Name:    my-workflow
   Workflow ID:      <your-workflow-id>
   Binary URL:       https://storage.cre.example.com/artifacts/<workflow-id>/binary.wasm
   Config URL:       https://storage.cre.example.com/artifacts/<workflow-id>/config
```

**Example private/offchain registry output:**

```bash
> cre workflow deploy my-workflow --target staging-settings

Deploying Workflow :     my-workflow
Target :                 staging-settings
Owner Address :          <your-organization-owner>

Compiling workflow...
Workflow compiled successfully

Uploading files...
✔ Loaded binary from: ./binary.wasm.br.b64
✔ Uploaded binary to: https://storage.cre.example.com/artifacts/<workflow-id>/binary.wasm
✔ Loaded config from: ./config.json
✔ Uploaded config to: https://storage.cre.example.com/artifacts/<workflow-id>/config

Registering workflow in private registry (workflowID: <your-workflow-id>)...
✓ Workflow registered in private registry

Details:
   Registry:         private
   Workflow Name:    my-workflow
   Workflow ID:      <your-workflow-id>
   Status:           Active
   Binary URL:       https://storage.cre.example.com/artifacts/<workflow-id>/binary.wasm
   Config URL:       https://storage.cre.example.com/artifacts/<workflow-id>/config
   Owner:            <your-organization-owner>
```

## Verifying your deployment

After a successful deployment, you can verify that your workflow was registered correctly:

1. **CLI**: Run [`cre workflow list`](/cre/reference/cli/workflow#cre-workflow-list) to see every workflow registered to your organization, the registry each was deployed to, and its current status. Workflows on the private registry are tagged `private` in the output.

2. **CRE UI**: View your deployed workflow in the [CRE platform](https://app.chain.link/cre/discover). Navigate to the **Workflows** section to see your workflow's status, ID, and execution history. Workflows deployed to the private registry are also tagged `private` in the UI.

3. **Block Explorer (onchain registry only)**: For workflows deployed with `deployment-registry: "onchain:ethereum-mainnet"`, the CLI output includes the transaction hash for the registration. The `WorkflowRegistry` contract is deployed on **Ethereum Mainnet** at <a href="https://etherscan.io/address/0x4ac54353fa4fa961afcc5ec4b118596d3305e7e5#code" target="_blank" rel="noopener noreferrer">`0x4Ac54353FA4Fa961AfcC5ec4B118596d3305E7e5`</a>.

## CI/CD pipeline integration

The `cre workflow build` and `cre workflow deploy` commands can be run as independent steps, making it straightforward to integrate CRE deployments into CI/CD pipelines.

The separation gives you two key benefits:

- **Build once, deploy many times** — Compile your workflow to a WASM binary in a build step, then promote that exact binary to staging and production without recompiling. This ensures the artifact you tested is the artifact you deploy.
- **Verify before deploying** — Use `cre workflow hash` after building to record and verify content hashes before submitting a deployment transaction.

### Example: GitHub Actions

The following example shows a two-job pipeline: a `build` job that compiles and uploads the WASM artifact, and a `deploy` job that downloads and deploys that exact binary.

```yaml
# .github/workflows/deploy.yml
name: Deploy Workflow

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install CRE CLI
        run: curl -sSL https://github.com/smartcontractkit/cre-cli/releases/latest/download/install.sh | sh

      - name: Build workflow
        run: cre workflow build ./my-workflow --output ./my-workflow/binary.wasm --non-interactive
        env:
          CRE_API_KEY: ${{ secrets.CRE_API_KEY }}

      - name: Display content hashes
        run: cre workflow hash ./my-workflow --wasm ./my-workflow/binary.wasm --target production-settings --non-interactive
        env:
          CRE_API_KEY: ${{ secrets.CRE_API_KEY }}
          CRE_ETH_PRIVATE_KEY: ${{ secrets.CRE_ETH_PRIVATE_KEY }}

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: workflow-binary
          path: ./my-workflow/binary.wasm

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install CRE CLI
        run: curl -sSL https://github.com/smartcontractkit/cre-cli/releases/latest/download/install.sh | sh

      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: workflow-binary
          path: ./my-workflow

      - name: Deploy workflow
        run: cre workflow deploy ./my-workflow --wasm ./my-workflow/binary.wasm --target production-settings --yes --non-interactive
        env:
          CRE_API_KEY: ${{ secrets.CRE_API_KEY }}
          CRE_ETH_PRIVATE_KEY: ${{ secrets.CRE_ETH_PRIVATE_KEY }}
          INFURA_API_KEY: ${{ secrets.INFURA_API_KEY }}
```

> **NOTE: API key authentication**
>
> Use `CRE_API_KEY` for non-interactive authentication in CI/CD pipelines instead of `cre login`, and pass `--non-interactive` so commands fail instead of prompting. Create an API key from the CRE platform under **Organization → APIs**. See [Authentication](/cre/reference/cli/authentication#api-key-authentication) for setup instructions.

> **NOTE: RPC URLs in CI/CD**
>
> Use `${VAR_NAME}` syntax in your `project.yaml` RPC URLs to inject secrets from your CI/CD environment. See [Environment variable interpolation in RPC URLs](/cre/reference/project-configuration#environment-variable-interpolation-in-rpc-urls) for details.

## Using multi-sig wallets

The `deploy` command supports multi-sig wallets through the `--unsigned` flag. When using this flag, the CLI generates raw transaction data that you can submit through your multi-sig wallet interface instead of sending the transaction directly.

For complete setup instructions, configuration requirements, and step-by-step guidance, see [Using Multi-sig Wallets](/cre/guides/operations/using-multisig-wallets).

## Next steps

- [Deploying to the Private Registry](/cre/guides/operations/deploying-to-private-registry): Step-by-step guide for using the Chainlink-hosted private registry
- [Activating & Pausing Workflows](/cre/guides/operations/activating-pausing-workflows): Learn how to control workflow execution
- [Monitoring Workflows](/cre/guides/operations/monitoring-workflows): Track your workflow's execution and performance
- [Updating Deployed Workflows](/cre/guides/operations/updating-deployed-workflows): Deploy new versions of your workflow