> Feedback: If these docs are stale, missing, or confusing, post sanitized feedback to `https://docs.tempo.xyz/api/feedback` with `source: "mcp"`, a short `message`, and any relevant `toolName`, `relatedResource`, or `client`.
# Validator onboarding

:::info
The active validator set is currently permissioned. If you are interested in becoming a validator, please [get in touch](https://tempo.xyz/contact) with the Tempo team.
:::

This guide walks through registering, generating your signing key, and starting your validator node for the first time. Before proceeding, make sure you have completed [system requirements](/docs/guide/node/system-requirements) and [installation](/docs/guide/node/installation).

## Initial registration

Registering a validator takes three steps:

1. **[Generate a signing keypair](#step-1-generate-a-signing-keypair)** — Create an encrypted ed25519 private key and derive the public key.
2. **[Create the add-validator signature](#step-2-create-the-add-validator-signature)** — Prove ownership of the signing key by producing a signature over your registration details.
3. **[Submit registration details](#step-3-submit-registration-details)** — Provide the Tempo team with all required values to add your validator on-chain.

### Step 1: Generate a signing keypair

:::warning
Never share your private signing key. Anyone with access to it can impersonate your validator. The Tempo team will never ask for your private key.
:::

Generate an encrypted ed25519 keypair. The `--secret` argument points to a file-like input that contains the encryption key. Prefer a named pipe (FIFO) or shell process substitution for this path: a FIFO lets one process stream bytes directly to another process without storing those bytes as a regular file, and it keeps the secret out of environment variables and command-line arguments. See [Why FIFOs and not env vars](/docs/guide/node/validator-keys#why-fifos-and-not-env-vars).

```bash
mkfifo /run/tempo/consensus-secret
<ENCRYPTION_KEY_CMD> > /run/tempo/consensus-secret &
tempo consensus generate-signing-key \
  --output <SIGNING_KEY_PATH> \
  --secret /run/tempo/consensus-secret
```

Verify the public key:

```bash
<ENCRYPTION_KEY_CMD> > /run/tempo/consensus-secret &
tempo consensus show-verification-key \
  --private-key <SIGNING_KEY_PATH> \
  --secret /run/tempo/consensus-secret
```

The public key should match the output of the `generate-signing-key` command.

`<ENCRYPTION_KEY_CMD>` should be a command that retrieves the encryption key from your KMS or secret manager and writes the raw secret to stdout.

### Step 2: Create the add-validator signature

The signature proves ownership of the ed25519 key being registered. Generate it with:

::::code-group

```bash [Mainnet]
tempo consensus create-add-validator-signature \
  --signing-key <PRIVATE_KEY_PATH> \
  --validator-address <YOUR_VALIDATOR_ADDRESS> \
  --public-key <YOUR_PUBLIC_KEY> \
  --ingress <IP:PORT> \
  --egress <IP> \
  --fee-recipient <FEE_RECIPIENT_ADDRESS> \
  --chain-id-from-rpc-url https://rpc.tempo.xyz
```

```bash [Testnet]
tempo consensus create-add-validator-signature \
  --signing-key <PRIVATE_KEY_PATH> \
  --validator-address <YOUR_VALIDATOR_ADDRESS> \
  --public-key <YOUR_PUBLIC_KEY> \
  --ingress <IP:PORT> \
  --egress <IP> \
  --fee-recipient <FEE_RECIPIENT_ADDRESS> \
  --chain-id-from-rpc-url https://rpc.testnet.tempo.xyz
```

::::

### Step 3: Submit registration details

Provide the following values along with the signature to the Tempo team:

| Value | Format | Description |
|-------|--------|-------------|
| **Validator operator address** | Ethereum address (`0x…`) | The control address for your validator. Used to authorize on-chain operations (IP updates, rotation, ownership transfer). |
| **Public key** | `0x`-prefixed 32-byte hex | Your ed25519 identity key (from [Step 1](#step-1-generate-a-signing-keypair)). |
| **Ingress** | `IP:port` | The inbound address other validators use to reach your node. Must be unique across all active validators. |
| **Egress** | `IP` | The outbound IP address your node uses to connect to other validators. |
| **Fee recipient** | Ethereum address (`0x…`) | The address that receives transaction fees from blocks your validator proposes. If you are not prepared to accept fees, use `0x0000000000000000000000000000000000000000`. |
| **Signature** | `0x`-prefixed hex | The ed25519 signature proving you control the signing key (from [Step 2](#step-2-create-the-add-validator-signature)). |

Once the Tempo team adds your validator on-chain, it will enter the active set in the [next epoch](/docs/guide/node/validator-status#state-transitions).

## Running the validator

The process for running a validator node is very similar to [running a full node](/docs/guide/node/rpc).

You should start by downloading the latest snapshot. Validators should use `--minimal` when migrating to minimal snapshots, and should keep using `--minimal` for future validator replacements.

::::code-group

```bash [Mainnet]
tempo download --chain mainnet --minimal
```

```bash [Testnet]
tempo download --chain moderato --minimal
```

::::

If you are replacing snapshot data in an existing data directory, add `--force` after the profile flag. This clears old snapshot files while preserving `discovery-secret` and `known-peers.json`.

If you are unsure which pruning configuration your validator is running, reach out to the Tempo team before replacing snapshot data. To check whether an existing validator is already migrated, inspect the node startup logs for the `Loaded storage settings` line and its `pruning_mode` field. If `pruning_mode` is `minimal`, no action is needed unless you are replacing the node.

Once you've downloaded the snapshot and have been whitelisted on-chain, you can proceed to run the validator node:

::::code-group

```bash [Mainnet]
tempo node --datadir <datadir> \
    --chain mainnet \
    --consensus.signing-key <path> \
    --consensus.secret <ENCRYPTION_KEY_FIFO> \
    --telemetry-url <TELEMETRY_URL>
```

```bash [Testnet]
tempo node --datadir <datadir> \
    --chain moderato \
    --consensus.signing-key <path> \
    --consensus.secret <ENCRYPTION_KEY_FIFO> \
    --telemetry-url <TELEMETRY_URL>
```

::::
The notable difference between RPC nodes and validator nodes is the omission of the `--follow` argument and the addition of the `--consensus.signing-key` argument. If the signing key is encrypted, provide the encryption key with `--consensus.secret`.

Once your node is up, it may not start syncing immediately. This is because your node might not be part of the active set. In most cases, your validator will enter the active set in under 6 hours after the on-chain addition of the validator identity.

### Optional flags

| Flag | Description |
|------|-------------|
| `--telemetry-url <URL>` | Unified metrics and logs export. See [Telemetry endpoint](#telemetry-endpoint) below for details. **We ask all validators to configure this so we can support troubleshooting.** |
| `--telemetry-metrics-interval <DURATION>` | Interval for pushing metrics (default: `10s`). |
| `--consensus.datadir <PATH>` | Store consensus data on a separate volume (e.g., AWS EBS) while keeping execution state on high-performance local disks. Migrate by copying `<datadir>/consensus` to the new location. |
| `--consensus.secret <PATH>` | Read the encrypted signing-key secret from a FIFO, process-substitution path, or regular file. Prefer FIFO or process substitution so the secret is streamed just in time and kept out of the process environment. |

### Telemetry endpoint

The `--telemetry-url` flag enables unified telemetry export. It pushes two types of data to a Tempo-operated metrics backend:

* **Prometheus metrics** — execution-layer (reth) and consensus-layer metrics in Prometheus text format, pushed at a configurable interval (default every 10 seconds).
* **Structured logs** — operational logs exported via OTLP at `debug` level, covering consensus events, block processing, and sync progress.

The URL must include credentials: `--telemetry-url https://user:pass@metrics.example.com`

#### What is collected

| Category | Examples |
|----------|---------|
| Execution metrics | Block processing times, transaction pool size, peer count, sync status, database stats |
| Consensus metrics | Epoch and view progress, DKG ceremony status, proposal and finalization counts |
| Operational logs | Consensus state transitions, block proposals, sync progress, error events |

All consensus metrics are namespaced under a `consensus` prefix.

#### What is **not** collected

The telemetry endpoint does **not** collect any ambient information about the host machine. Specifically:

* No hostname, IP address, or machine identifiers
* No operating system, CPU, memory, or disk information
* No information about other processes or services running on the machine
* No file paths or directory structures beyond the node's own data directory references in logs
* No network topology or firewall configuration

The data is strictly limited to the node's own operational metrics and logs.
