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

# Configure a signing backend

> Point Cosmos-KMS at the custodian holding the consensus key: AWS KMS, a PKCS#11 HSM, or a file.

A signing backend is the custodian that holds the validator's consensus key and signs with it. Cosmos-KMS supports three: AWS KMS, a PKCS#11 hardware module, and a file on disk. The `keys` block in `kms.yaml` selects one, and this guide configures each in turn.

## Prerequisites

* A running signer and node, which [Remote signing tutorial](/sdk/next/kms/tutorial-file-backend) sets up. Only the `keys` block changes between backends, so everything else from the tutorial runs as is.
* Per backend: the [AWS CLI](https://aws.amazon.com/cli/) and an AWS account for AWS KMS; your HSM's tooling plus [OpenSC](https://github.com/OpenSC/OpenSC)'s `pkcs11-tool` for PKCS#11, with [SoftHSM2](https://www.opendnssec.org/softhsm/) as a local test rig.

The `algorithm` field is required for all backends.

## AWS KMS

AWS Key Management Service (KMS) is a managed service that stores cryptographic keys and signs with them on request. With this backend, the consensus key lives in KMS and never leaves it. The signer calls the KMS Sign API to produce each signature. Credentials come from the standard AWS default chain: environment, shared config, SSO, or an IAM role. No secrets enter `kms.yaml`.

Provision an Ed25519 signing key, or reuse one:

```shell theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
aws kms create-key --key-spec ECC_NIST_EDWARDS25519 --key-usage SIGN_VERIFY
```

```shell theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
aws kms create-alias --alias-name alias/validator --target-key-id <key-id>
```

Then bind it in the `keys` block:

```yaml theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
keys:
  - chain_ids: [my-chain-1]
    backend: awskms
    algorithm: ed25519
    key_id: alias/validator
    region: us-east-1
```

The `key_id` accepts a key ID, a full ARN, or an alias. The `region` and `profile` fields are optional and fall back to the AWS default chain. The `endpoint` field exists for LocalStack-style testing only.

## `PKCS#11`

The `PKCS#11` backend keeps the consensus key on a hardware security module (HSM) or token and signs on the device through `PKCS#11`, the standard interface for cryptographic hardware. The key never leaves the module. The signer uses an existing key only, so provision one with your HSM tooling first. For a local test rig, SoftHSM2 works:

```shell theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
softhsm2-util --init-token --free --label validator-token --pin 1234 --so-pin 4321
```

```shell theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --login --pin 1234 --keypairgen --key-type EC:edwards25519 --label validator --id 01
```

Then bind it:

```yaml theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
keys:
  - chain_ids: [my-chain-1]
    backend: pkcs11
    algorithm: ed25519
    module: /usr/lib/softhsm/libsofthsm2.so
    token_label: validator-token
    key_label: validator
    pin_env: KMS_PIN
```

The signer enforces three field rules at startup:

* Select the token with exactly one of `token_label` or `slot`.
* Select the key with `key_label`, `key_id` (the hex `CKA_ID`), or both.
* Supply the PIN through exactly one of `pin`, `pin_env`, or `pin_file`.

Prefer `pin_env` or `pin_file`. An inline `pin` puts the PIN in the config file.

## File

The file backend reads the consensus key from a file on the signer's disk into memory. It is the development and testing backend. The key sits in plaintext, so it is not production custody. The tutorial covers it end to end:

```yaml theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
keys:
  - chain_ids: [my-chain-1]
    backend: file
    algorithm: ed25519
    key_file: priv_validator_key.json
```

The `key_file` accepts a CometBFT `priv_validator_key.json` or a raw base64-encoded private key. The file backend also signs post-quantum consensus keys. Generate the key with `simd init <moniker> --consensus-key-algo ml_dsa_65` and bind it:

```yaml theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
keys:
  - chain_ids: [my-chain-1]
    backend: file
    algorithm: mldsa65
    key_file: priv_validator_key.json
```

{/* TODO(ERIC): confirm the per-backend mldsa65 support matrix for the release; awskms/ and pkcs11/ ship mldsa65 at kms 0007b0d but are untested against real hardware. Verify that post-quantum keys work with aws and pkcs11 backends and update this page to reflect that. */}

## Verify any backend

Verification is the same regardless of custodian. Start the signer, start the node, and confirm blocks flow, exactly as in [the tutorial](/sdk/next/kms/tutorial-file-backend):

```shell theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
curl -s localhost:26657/status | jq '.result.sync_info.latest_block_height'
```

Backend problems surface when the signer starts, not when it signs. A wrong PIN, a missing PKCS#11 module, or missing AWS permissions all fail at `kms start` before any connection is made. Fix the `keys` block and start the signer again.

## What can go wrong

* The signer rejects the config at startup: a missing `algorithm`, both `token_label` and `slot` set, or more than one PIN source. The error names the offending field.
* The signer starts but cannot reach the key: wrong `module` path, wrong `key_id` or alias, or AWS credentials that resolve to no permission. These also fail at startup.
* The node exits with a pubkey timeout: the signer is not running or not reachable. Start the signer first. It dials and retries.

## Next steps

* Look up any config field, its type, and its constraints. See the [configuration reference](/sdk/next/kms/configuration-reference).
* Run the whole flow once with the file backend. See [Remote signing tutorial](/sdk/next/kms/tutorial-file-backend).
* Move an existing validator onto a key in a new backend by rotation. See [Rotate a consensus key held in Cosmos-KMS](/sdk/next/kms/rotate-key-remote-signer).
