> ## Documentation Index
> Fetch the complete documentation index at: https://certplane.kippel.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Store Certplane secrets in HashiCorp Vault

> Configure Certplane's broker to read sensitive credentials like DNS API tokens directly from a HashiCorp Vault or OpenBao KV secrets engine.

If you use HashiCorp Vault or OpenBao to manage secrets, Certplane's broker can read sensitive values (like DNS API tokens) directly from Vault rather than from environment variables or files. This keeps credentials out of your shell environment and lets you manage rotation centrally through Vault's API.

## Prerequisites

Before you begin, confirm the following:

* Vault is running and its API is reachable from the broker host.
* You have a Vault token with `read` capability on the secret path you plan to use.
* The KV secrets engine is mounted and enabled in your Vault instance.

<Steps>
  <Step title="Write the secret to Vault">
    Store your Cloudflare DNS API token (or any other credential) as a KV secret. The example below uses the KV v2 engine mounted at `secret`:

    ```bash theme={null}
    vault kv put secret/certplane/cloudflare value="your-cloudflare-token"
    ```

    Certplane reads the field named by `secrets.vault.key` from this secret. The default key name is `value`, matching the command above.

    <Tip>
      Create a dedicated Vault policy that restricts the broker token to only the paths it needs. A minimal policy for the path above looks like this:

      ```hcl theme={null}
      path "secret/data/certplane/*" {
        capabilities = ["read"]
      }
      ```

      Apply it with `vault policy write certplane-broker certplane-broker.hcl`, then generate a token with `vault token create -policy=certplane-broker`.
    </Tip>
  </Step>

  <Step title="Write the Vault token to a file">
    Certplane reads the Vault token from a file rather than an environment variable, so the token is never exposed through the process environment:

    ```bash theme={null}
    echo "hvs.YOUR_VAULT_TOKEN" > /etc/certplane/vault-token
    chmod 600 /etc/certplane/vault-token
    ```

    Ensure the file is readable only by the user that runs the broker process.
  </Step>

  <Step title="Configure the broker to use the Vault provider">
    Update `broker.yml` to set `secrets.provider` to `vault` and fill in the connection details:

    ```yaml theme={null}
    secrets:
      provider: vault
      vault:
        address: https://vault.example.com:8200
        token_file: /etc/certplane/vault-token
        mount_path: secret
        kv_version: 2
        key: value
        timeout: 10s
    ```

    <Note>
      `kv_version` controls which KV Secrets Engine API Certplane uses to fetch the secret:

      * **`2`** (default) — KV Secrets Engine v2. Secrets have full version history and are stored under the `secret/data/<path>` prefix internally. Use this for new Vault deployments.
      * **`1`** — KV Secrets Engine v1. No versioning; secrets are stored directly at `secret/<path>`. Use this only if your Vault instance has not upgraded to KV v2.

      Both versions are supported; set `kv_version` to match what your Vault mount actually uses.
    </Note>
  </Step>

  <Step title="Reference the secret in your profile config">
    In `policy.yml`, set `acme.credentials` to the Vault path of the secret (relative to the mount). Certplane appends this to `mount_path` when constructing the Vault API call:

    ```yaml theme={null}
    profiles:
      public_wildcard:
        type: wildcard
        dns_names:
          - "*.example.com"
        acme:
          challenge: dns-01
          credentials: certplane/cloudflare
        renew_before: 720h
    ```

    <Note>
      `acme.credentials` is a secret reference, resolved by the broker's configured secrets provider. With the Vault provider, the value is the secret path relative to `secrets.vault.mount_path`. The broker reads the field named by `secrets.vault.key` (default `value`) from that secret to obtain the actual DNS provider token.
    </Note>

    The value `certplane/cloudflare` in the example above matches the secret you wrote in step 1 (`secret/certplane/cloudflare` minus the mount prefix `secret`).
  </Step>
</Steps>

## Using OpenBao

[OpenBao](https://openbao.org/) is an open-source fork of Vault with a compatible API. Certplane supports it natively — use the same configuration as above but set `provider` to `openbao`:

```yaml theme={null}
secrets:
  provider: openbao
  vault:
    address: https://openbao.example.com:8200
    token_file: /etc/certplane/vault-token
    mount_path: secret
    kv_version: 2
    key: value
    timeout: 10s
```

All other fields (`mount_path`, `kv_version`, `key`, `timeout`) behave identically. The `vault` sub-key is reused for OpenBao configuration — there is no separate `openbao` block.
