> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/infrastructure-as-code-management/registry/provider-registry.md).

# Provider Registry

The Harness IaCM **Provider Registry** allows you to securely publish and distribute custom providers. Providers are signed with GPG keys, compiled as binary files for multiple platforms, and made available for use in [OpenTofu](https://opentofu.org/) or Terraform configurations.

You find the Provider Registry under **IaCM** > **Registry**, alongside the [Module Registry](/infrastructure-as-code-management/registry/module-registry/module-registry.md) and **GPG Keys** tabs. Because providers are distributed as compiled binaries rather than source, you build and sign them yourself, then upload the binaries and their signature to Harness.

{% hint style="info" %}
**EXAMPLE USE CASE**

A DevOps team creates a **custom provider** to integrate OpenTofu with their internal APIs. By publishing it in the Provider Registry, developers across macOS, Linux, and Windows consume the provider during `tofu init` without manually managing binaries.
{% endhint %}

***

### What you will learn from this topic <a href="#what-you-will-learn-from-this-topic" id="what-you-will-learn-from-this-topic"></a>

This page walks through the full lifecycle of a custom provider, from signing key to consumption:

* **Generate and register a GPG key:** Create a signing key and add it to Harness so the registry can verify your binaries.
* **Build the required artifacts:** Produce platform-specific binaries, a checksum file, and a detached signature.
* **Publish a provider version:** Register the provider in Harness, select a protocol version, upload the artifacts, and publish.
* **Consume the published provider:** Reference the provider from an OpenTofu or Terraform configuration, and authenticate the CLI for local runs.

***

### Before you begin <a href="#before-you-begin" id="before-you-begin"></a>

Confirm the following before you publish a provider version:

* **Harness account with IaCM enabled:** You need **Infrastructure as Code Management** under **Infrastructure** in Harness when it is entitled on your account. Go to [Getting started with Harness Platform](/harness-ai/new-to-harness-platform/get-started.md) to access or create a Harness account.

  <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p><strong>CONTACT HARNESS SUPPORT:</strong></p><p>If IaCM does not appear, go to <a href="/pages/13Oqw5qhSvsXSpzVztiw">Get started with IaCM</a> or contact your account administrator or <a href="mailto:support@harness.io">Harness Support</a>.</p></div>
* **Provider Registry permissions:** You need **View** (`iac_providerregistry_view`) and **Create / Edit** (`iac_providerregistry_edit`) on **IACM Provider Registry**, plus **Create / Edit** (`iac_registry_edit`) on **Registry** to add GPG keys. Go to the [permissions reference](/harness-ai/use-harness-platform/platform-access-control/permissions-reference.md#infrastructure-as-code) to review the IaCM resources, and to [RBAC in Harness](/harness-ai/use-harness-platform/platform-access-control.md) and [Manage roles](/harness-ai/use-harness-platform/platform-access-control/add-manage-roles.md) to have an administrator assign a role that includes them.
* **Local build environment:** A toolchain that compiles your provider into platform-specific binaries, such as Go.
* **GPG tooling:** Go to [GnuPG downloads](https://www.gnupg.org/download/) to install `gpg` on your machine.

***

### Prepare your provider <a href="#prepare-your-provider" id="prepare-your-provider"></a>

The Provider Registry assumes your binaries are already signed with a GPG key. This section covers generating that key, registering it with Harness, and producing the checksum and signature files that publishing requires.

#### Generate a GPG key <a href="#generate-a-gpg-key" id="generate-a-gpg-key"></a>

GPG keys sign your provider binaries so the registry, and the OpenTofu or Terraform client, can verify them. Harness needs three values from the key: the **Name**, the **Key ID**, and the **ASCII armored public key**.

Run the following commands in order to generate a key and collect those values:

1. Generate a key pair and follow the interactive prompts:

   ```bash
   gpg --full-generate-key
   ```
2. List your keys in long format to find the key ID:

   ```bash
   gpg --list-keys --keyid-format LONG
   ```
3. Export the public key in ASCII armor format, substituting the key ID from the previous step:

   ```bash
   gpg --armor --export <KEY_ID>
   ```

Go to [Generating a new GPG key](https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key) to review the full GnuPG walkthrough, including passphrase and expiry choices.

#### Add your GPG key to IaCM <a href="#add-your-gpg-key-to-iacm" id="add-your-gpg-key-to-iacm"></a>

Register the public key with Harness so it can verify the signature you upload with each provider version:

1. Go to **IaCM** > **Registry** > **GPG Keys**.
2. Click **New GPG Key**.
3. Enter the **Name**, **Key ID**, and **ASCII armored public key** you collected in the previous step.
4. Click **Save**.

#### Create checksum and signature files <a href="#create-checksum-and-signature-files" id="create-checksum-and-signature-files"></a>

Each provider version requires three kinds of artifact:

* **Compiled binaries:** One binary for each operating system and architecture you support.
* **Checksum file:** A `SHA256SUMS` checksum file listing the hash of every binary.
* **Signature file:** A `SHA256SUMS.sig` signature file, which is a detached signature. A detached signature is a separate file that proves the checksum file was signed by your key, rather than wrapping the signed content inside it.

Run both commands from the directory that holds your compiled binaries.

1. Create the checksum file. The command differs by operating system:

   <div data-gb-custom-block data-tag="hint" data-style="warning" class="hint hint-warning"><p><strong>MATCH THE CHECKSUM ENTRIES TO THE FILES YOU UPLOAD</strong></p><p>Both commands expand <code>*</code> against the current directory only. If your binaries sit in per-platform subdirectories, the command fails with a directory error and hashes nothing. Flatten the binaries into one directory first, or name them explicitly. Re-run the command if you rebuild a binary, and delete any stale <code>SHA256SUMS</code> beforehand so the file does not list itself.</p></div>
2. Sign the checksum file with the same key you registered in Harness:

   ```bash
   gpg --default-key <KEY_ID> --output SHA256SUMS.sig --detach-sign SHA256SUMS
   ```

***

### Register and publish a provider <a href="#register-and-publish-a-provider" id="register-and-publish-a-provider"></a>

Registering a provider creates the entry in the registry. Publishing a version validates your uploaded artifacts and makes that version available to OpenTofu and Terraform.

#### Select a provider protocol version <a href="#select-a-provider-protocol-version" id="select-a-provider-protocol-version"></a>

Registration asks you to select a protocol version, so decide which one your provider implements before you start.

{% hint style="info" %}
**PROVIDER PROTOCOL VERSIONS**

The provider protocol defines the interface and communication standard between OpenTofu or Terraform and external providers. Each protocol version, such as v4, v5, or v6, specifies how providers implement functions, handle requests, and structure their schemas. Newer protocol versions add features, improve security, and may deprecate older behaviours.

Select the protocol version that matches your provider implementation and the Terraform or OpenTofu version you intend to support. Selecting multiple protocol versions widens compatibility and supports users who have not yet upgraded. If the selected protocol does not match what your binary implements, `init` fails when the client negotiates with the provider.

Go to the [Terraform plugin protocol reference](https://developer.hashicorp.com/terraform/plugin/terraform-plugin-protocol) to review what each protocol version supports.
{% endhint %}

#### Publish a provider version <a href="#publish-a-provider-version" id="publish-a-provider-version"></a>

Follow either the interactive guide or the written steps below.

{% tabs %}
{% tab title="Interactive Guide" %}
{% embed url="<https://app.tango.us/app/embed/c6beb8f1-75df-4c1d-bbab-3d87209ef6fd?skipCover=true&defaultListView=false&skipBranding=false&makeViewOnly=true&hideAuthorAndDetails=true>" %}
Register a Provider in Harness IaCM
{% endembed %}
{% endtab %}

{% tab title="Step-by-Step" %}
Complete the following steps to register a provider and publish its first version:

1. From the IaCM module, go to **Registry**, then select the **Provider Registry** tab.
2. Click **New Provider** and enter a provider name.
3. Add a version. The version must follow semantic versioning, for example `1.0.0`.
4. Select one of your stored GPG keys.
5. Select a provider protocol version, for example v4, v5, or v6.
6. Upload the required files: the compiled binaries for all supported operating systems and architectures, the `SHA256SUMS` checksum file, and the `SHA256SUMS.sig` signature file.
7. Verify that all registry files are uploaded.
8. Click **Publish**. Harness validates the upload and publishes the provider version.

{% hint style="info" %}
**DRAFT STATE**

If you do not publish the version immediately, it remains in a draft state and appears alongside published versions on the provider detail page. Drafts allow you to upload additional binaries, checksums, or signature files later before finalizing the version. Draft versions are not available for consumption in OpenTofu or Terraform, so `init` cannot resolve them until you reopen the draft and click **Publish**.
{% endhint %}

{% hint style="warning" %}
**PUBLISHING FAILS IF:**

* Any required file is missing.
* Filename versions do not match the version you entered.
* The signature or checksum file does not match the uploaded binaries.

The version stays in draft state when validation fails. Correct the artifacts, re-upload the affected files, then publish again.
{% endhint %}
{% endtab %}
{% endtabs %}

***

### Consume a published provider <a href="#consume-a-published-provider" id="consume-a-published-provider"></a>

Once published, a provider version resolves like any other registry provider. Workspace executions authenticate automatically; local runs need a token.

#### Reference the provider in your configuration <a href="#reference-the-provider-in-your-configuration" id="reference-the-provider-in-your-configuration"></a>

Declare the provider in the `required_providers` block, using your Harness account ID and provider name:

```hcl
terraform {
  required_providers {
    <provider-name> = {
      source = "<provider-name>.app.harness.io/account/<harness-account-id>/<provider-name>"
      version = "1.0.0"
    }
  }
}
provider "<provider-name>" {
 # Configuration options
}
```

Your Harness account ID appears in the URL of any Harness page, after `/account/`, and under **Account Settings** > **Account Details**.

When you run the init command, OpenTofu or Terraform automatically pulls the binary that matches the client operating system and architecture. If no uploaded binary matches that platform, `init` fails.

#### Authenticate the OpenTofu or Terraform CLI <a href="#authenticate-the-opentofu-or-terraform-cli" id="authenticate-the-opentofu-or-terraform-cli"></a>

Inside an IaCM workspace execution, Harness authenticates to the registry for you and no extra configuration is needed. When you run `tofu init` or `terraform init` locally against a configuration that sources providers from the Harness registry, the CLI must authenticate with `app.harness.io` itself. Without authentication, `init` fails with a `401` error when it tries to download the provider.

OpenTofu and Terraform read tokens from environment variables named `TF_TOKEN_<hostname>`, where dots in the hostname are replaced with underscores. Set the variable to a [Harness personal access token (PAT)](/harness-ai/use-harness-platform/automation/api/add-and-manage-api-keys.md) before running any local commands:

```bash
export TF_TOKEN_app_harness_io=<your_harness_pat>
tofu init
# or: terraform init <a href="#or-terraform-init" id="or-terraform-init"></a>
```

{% hint style="info" %}
**SELF-MANAGED PLATFORM**

If your organization runs Harness on a custom domain, for example `registry.example.com`, replace dots with underscores in that hostname:

```bash
export TF_TOKEN_registry_example_com=<your_harness_pat>
tofu init   # or: terraform init
```

{% endhint %}

To persist the token across shell sessions, add the `export` line to your shell profile, such as `~/.zshrc` or `~/.bashrc`. Alternatively, store credentials in the OpenTofu or Terraform credentials file (`~/.tofurc` or `~/.terraform.d/credentials.tfrc.json`).

{% hint style="info" %}
**TWO AUTHENTICATION CONTEXTS, KEPT SEPARATE**

`TF_TOKEN_app_harness_io` authenticates your local CLI with the registry. It is unrelated to the GPG key, which only signs and verifies the binaries. Go to [Use a Module](/infrastructure-as-code-management/registry/module-registry/registered-module-settings.md#use-a-module) to review the equivalent setup for modules.
{% endhint %}

***

### Troubleshooting <a href="#troubleshooting" id="troubleshooting"></a>

<details>

<summary>tofu init or terraform init returns a 401 error when pulling a provider from the Harness IaCM Provider Registry</summary>

Set the TF\_TOKEN\_app\_harness\_io environment variable to a valid Harness personal access token before running init. If your organization uses a custom domain, replace dots in the hostname with underscores for the variable name, for example TF\_TOKEN\_registry\_example\_com.

</details>

<details>

<summary>Publishing a provider version fails in Harness IaCM because a required file is missing or the version does not match</summary>

Publishing requires every supported binary plus the SHA256SUMS and SHA256SUMS.sig files. Confirm that the version string in each binary filename matches the version you entered exactly, for example 1.0.0 and not 1.0.1. The version stays in draft state until validation passes.

</details>

<details>

<summary>Signature verification fails when publishing a provider version to the Harness IaCM Provider Registry</summary>

SHA256SUMS.sig must be a detached signature of the exact SHA256SUMS file you upload, created with the same GPG key registered under Registry > GPG Keys. If you rebuilt any binary, regenerate SHA256SUMS and re-sign it before uploading.

</details>

<details>

<summary>A published Harness IaCM provider does not download for a specific operating system or architecture during tofu init</summary>

Upload a compiled binary for every operating system and architecture you intend to support. OpenTofu and Terraform resolve the binary matching the client platform, and init fails when no uploaded binary matches it.

</details>

<details>

<summary>A Harness IaCM provider version stays in draft state and cannot be consumed in OpenTofu or Terraform</summary>

Draft versions are not available for consumption. Open the version on the provider detail page, confirm all binaries, the checksum file, and the signature file are uploaded, then click Publish.

</details>

***

### Next steps <a href="#next-steps" id="next-steps"></a>

You have published a signed provider version and made it available to every OpenTofu and Terraform configuration in your account. Explore the other reusable building blocks in IaCM:

* [Module Registry](/infrastructure-as-code-management/registry/module-registry/module-registry.md): Publish and share OpenTofu or Terraform modules.
* [Workspace Templates](/infrastructure-as-code-management/platform/workspaces/workspace-templates.md): Standardize workspace configurations across teams.
* [Permissions reference](/harness-ai/use-harness-platform/platform-access-control/permissions-reference.md#infrastructure-as-code): Review every IaCM resource and permission before delegating registry access.
