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

# Cosmos-KMS configuration reference

> Every field of kms.yaml: chains, validators, keys with per-backend parameters, and the gRPC block.

The signer reads one file, `<home>/kms.yaml`, at startup. Relative paths anywhere in the file resolve against the `--home` directory. Validation runs at `kms start`; a rejected field is named in the error.

For task-shaped setup, see [Configure a signing backend](/sdk/latest/kms/configure-backend); this page is the complete field list.

## chains

Declares one chain to sign for. One entry per chain.

| Field        | Type   | Required | Description                                                                          |
| ------------ | ------ | -------- | ------------------------------------------------------------------------------------ |
| `id`         | string | yes      | The chain ID, matching the chain's genesis.                                          |
| `state_file` | string | no       | Path to the double-sign protection state file. Defaults to `<home>/state/<id>.json`. |

## validators

Declares one outbound connection to a validator node's privval listener. A chain can have multiple entries, for example a primary and a backup node.

| Field          | Type   | Required | Description                                                                                                                                                                   |
| -------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chain_id`     | string | yes      | Must match a declared `chains[].id`.                                                                                                                                          |
| `addr`         | string | yes      | The listener address. `tcp://host:port` selects the SecretConnection transport; `noise://<validator-peer-id>@host:port` selects the Noise transport with mutual peer pinning. |
| `identity_key` | string | yes      | Path to the signer's identity key file, generated by `kms init`. Authenticates the SecretConnection, and doubles as the signer's Noise identity.                              |
| `reconnect`    | bool   | no       | Reconnect automatically after a dropped connection. Defaults to `true`.                                                                                                       |

## keys

Binds one signing key to one or more chains. Each chain must be backed by exactly one key. The `backend` field selects the custodian, and the remaining fields depend on it; fields belonging to other backends are ignored.

Fields shared by every backend:

| Field       | Type            | Required    | Description                                                                                     |
| ----------- | --------------- | ----------- | ----------------------------------------------------------------------------------------------- |
| `chain_ids` | list of strings | yes         | Chains this key signs for. Each must match a declared `chains[].id`.                            |
| `backend`   | string          | no          | `file` (default), `pkcs11`, or `awskms`.                                                        |
| `algorithm` | string          | yes         | Key algorithm: `ed25519`, `secp256k1`, `secp256k1eth`, or `mldsa65`. Set it explicitly.         |
| `key_id`    | string          | per backend | For `pkcs11`: hex `CKA_ID` of the key object. For `awskms`: KMS key ID, ARN, or `alias/<name>`. |

Consensus signing supports `ed25519`, `secp256k1eth`, and `mldsa65` on every backend, and `secp256k1` on the AWS KMS backend only. The algorithm name `mldsa65` has no underscores; the chain-side key type `ml_dsa_65` does.

### backend: file

A key read from disk into memory. Development and testing only; the key is held in plaintext.

| Field      | Type   | Required | Description                                                                                                                                                            |
| ---------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `key_file` | string | yes      | Path to the key. Accepts a CometBFT `priv_validator_key.json`, or a raw private key file (base64-encoded for `ed25519` and `mldsa65`, hex-encoded for `secp256k1eth`). |

### backend: pkcs11

A key on a PKCS#11 token or HSM. Signing happens on-device; the signer uses an existing key and never generates or imports one.

| Field         | Type    | Required                             | Description                                      |
| ------------- | ------- | ------------------------------------ | ------------------------------------------------ |
| `module`      | string  | yes                                  | Path to the PKCS#11 module shared library.       |
| `token_label` | string  | exactly one of the two               | `CKA_LABEL` of the token.                        |
| `slot`        | integer | exactly one of the two               | Slot number of the token.                        |
| `key_label`   | string  | at least one of `key_label`/`key_id` | `CKA_LABEL` of the key object.                   |
| `pin`         | string  | exactly one PIN source               | User PIN, inline. Prefer the alternatives below. |
| `pin_env`     | string  | exactly one PIN source               | Environment variable holding the PIN.            |
| `pin_file`    | string  | exactly one PIN source               | Path to a file holding the PIN.                  |

### backend: awskms

A key held in AWS KMS. Signing happens through the KMS Sign API; credentials resolve through the AWS default credential chain, and no secret material appears in the config.

| Field      | Type   | Required | Description                                                                 |
| ---------- | ------ | -------- | --------------------------------------------------------------------------- |
| `region`   | string | no       | AWS region of the key. Falls back to the AWS default chain.                 |
| `profile`  | string | no       | Shared-config profile name. Falls back to the AWS default chain.            |
| `endpoint` | string | no       | Custom KMS endpoint URL, for LocalStack-style testing. Leave unset for AWS. |

## grpc

Optional. When present, the signer also serves the SignerService gRPC API alongside privval. Its usage documentation ships with the interoperability release; the fields are listed here for completeness.

| Field      | Type   | Required | Description                                                                                     |
| ---------- | ------ | -------- | ----------------------------------------------------------------------------------------------- |
| `listen`   | string | yes      | `host:port` the gRPC server binds to.                                                           |
| `tls_cert` | string | no       | TLS server certificate file. Omitting both TLS fields serves plaintext, for local testing only. |
| `tls_key`  | string | no       | TLS server private key file.                                                                    |
| `keys`     | list   | yes      | The keys the service exposes; see below.                                                        |

Each `grpc.keys` entry:

| Field       | Type   | Required | Description                                                                                                                                                                |
| ----------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`        | string | yes      | Logical key identifier returned to clients.                                                                                                                                |
| `backend`   | string | yes      | `file`, `awskms`, or `pkcs11`.                                                                                                                                             |
| `algorithm` | string | yes      | For `file` and `pkcs11`: `ed25519` or `secp256k1eth`. For `awskms`: `ed25519`, `secp256k1`, or `secp256k1eth`. `mldsa65` has no gRPC signature scheme and is privval-only. |
| `key_id`    | string | awskms   | KMS key ID, ARN, or `alias/<name>`.                                                                                                                                        |
| `key_file`  | string | file     | Path to the key. Accepts a CometBFT `priv_validator_key.json`, or a raw private key file (base64-encoded for `ed25519`, hex-encoded for `secp256k1eth`).                   |

A `grpc.keys` entry with `backend: pkcs11` also takes the PKCS#11 fields, with the same rules and the same validation as a privval key. See [backend: pkcs11](#backend-pkcs11) for `module`, `token_label`, `slot`, `key_label`, `key_id`, and the PIN sources.

<Warning>The gRPC server performs no caller authentication or authorization. Any client that can reach the listener can use every configured key. Restrict access with TLS and network controls.</Warning>

## Constraints checked at startup

* Every `validators[].chain_id` and every entry in `keys[].chain_ids` must match a declared `chains[].id`.
* Each chain must be backed by exactly one key.
* PKCS#11 keys must select the token with exactly one of `token_label` or `slot`, select the key with `key_label` or `key_id`, and supply exactly one PIN source.
* A declared chain with no `validators` entry is not rejected. The signer starts, binds nothing, and signs nothing, with no warning, so check that every chain has a validator entry.
* Every chain's sign-state file must exist and be non-empty. A missing or empty file fails closed with `sign-state file <path> is missing or empty; refusing to start at height 0`, so the signer cannot re-sign a height it has no record of. See [First start on a new chain](#first-start-on-a-new-chain).

This list is not exhaustive. Config-level rejections are prefixed `config:` and name the field at fault; errors raised later, when a backend or chain signer is opened, use their own prefixes such as `app:` or `file:`.

## First start on a new chain

A key that has never signed on a chain has no sign-state file, so the checks above block its first start. Write the height-0 floor with:

```shell theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
kms start --home <home> --allow-fresh-state <chain-id>
```

`kms state init` writes a floor too, but it loads and validates `kms.yaml` first, so it only works once the chain is declared and the config is complete. It also defaults `--step` to 3, which refuses everything at that height and round, where `--allow-fresh-state` writes step 0. Pass `--step 0` to match. See [Migrate from TMKMS](/sdk/latest/kms/migrate-from-tmkms) for more details.

<Warning>Pass `--allow-fresh-state` only for a chain the key has genuinely never signed on. It will not overwrite an existing floor, but a service definition that carries it permanently removes the protection: a deleted or truncated state file resets the double-sign floor to zero instead of stopping the signer.</Warning>

## Next steps

* Task-shaped backend setup. See [Configure a signing backend](/sdk/latest/kms/configure-backend).
* First-time setup end to end. See [Remote signing tutorial](/sdk/latest/kms/tutorial-file-backend).
