Skip to main content
The IBC CLI reads its configuration from ibc.yml. The file tells the CLI:
  • which chains to connect to
  • which clients form each connection
  • which attestors to run or query
  • which keys to use for deployment, relaying, and attestation
  • where the relayer stores packet state
Run the following commands to create and validate the file:
Populate the chains, signers, connections, and attestors you need before running the process-specific checks:
ibc config validate rejects unknown fields and unresolved cross-references, including a local attestor’s chainId and signer, without starting a process. Key-management commands and commands that write a draft configuration do not necessarily run these checks. Pass relayer or attestor to add the sufficiency checks needed to run that process. Values can contain ${VAR}. The CLI replaces each variable from the environment before it parses the file.

Example config.yml

Below is an example of a config file:
Some fields name something declared elsewhere in the file. The loader checks each of these when it reads the config: For example, signer: attestor-dan-base-key selects the signer whose alias is attestor-dan-base-key. A local attestor’s chainId must name a chain declared under chains; running the attestor also requires that chain’s evm.rpc endpoint. ibc config validate, ibc relayer run, and ibc attestor run reject unresolved references.

server

server sets the address for the relayer and attestor APIs. A process that runs both services uses one server. Server reflection is always enabled.

logging

logging sets how the process writes its own logs. Each key has a matching flag, and the flag wins only when it is passed explicitly, so a value here survives an ordinary invocation. --log-level and --log-json override their keys for one run.

db

db configures the relayer’s packet store. The store lets the relayer resume unfinished work after a restart. ibc relayer run applies pending migrations at startup. Pass --no-migrate to disable automatic migration, or run ibc migrate up separately.

observability

observability turns metrics on and says how they are served. With metrics false nothing else in the block is read, and the process logs that observability is disabled. simple serves Prometheus metrics over HTTP on simpleMetricsListenAddr. otel collects through OpenTelemetry instead and needs a configuration file, from otelFile or from OTEL_CONFIG_FILE. See Observability and metrics for metric names, labels, and semantics.

chains

chains lists every chain used elsewhere in the file. ibc deploy core deploys the router and multicall. Omit their addresses before deployment, then fill them in from the manifest, or let ibc deploy render-config write the finished blocks. The deployer must be a local signer, because deployment requires direct access to the key.

relayer

Connections

relayer.connections selects the connections this process relays. Each entry identifies one client on each chain, and the relayer handles traffic in both directions. Client identifiers are scoped to a chain, so both ends can use the same clientId. The ibc deploy client subcommands do this by default. The two client ends must belong to different chains. A client can appear in only one configured connection on a given chain. With autoRelay.enabled on an end, the relayer carries that end’s outgoing packets without being asked. That end’s chain needs evm.ws, and validation fails without it. Unset and false are the same input. remoteProver is optional. Without it, the relayer proves an end with the built-in prover for its type; with it, the ProverService at remoteProver.url proves that end instead, and type may name a light client the IBC CLI does not implement. ibc deploy render-config never writes a remoteProver block, and keeps one you added.

Relay settings

The relayer uses these defaults unless you override them. Each EVM submission estimates its fee cap as twice the latest block’s base fee plus the node’s suggested tip. Replacement attempts increase the fee cap and tip by 20%, rounded up with a minimum increase of one wei, within a ceiling of four times that fresh estimate. The ceiling stays fixed during a submission’s retries and is recalculated from fresh node data on the next submission. Add an override only when a chain needs different behavior:
Receive batches use the destination chain’s settings. Acknowledgement and timeout batches use the source chain’s settings.

attestors

attestors lists the attestors that the process runs or queries. A local attestor watches a configured chain and signs with a configured signer. A remote attestor runs elsewhere and is queried over gRPC.

Local attestor

Set finalityOffset according to the chain’s finality model.

Remote attestor

A remote entry does not set chainId or signer. The process obtains the attestor’s chain and signing address from its Info RPC. Fields from the other attestor type are rejected. A remote attestor cannot set chainId, and a local attestor cannot set grpc. Local attestor names must be unique. Two local attestors for the same chain must also use different signers. Use separate signing keys for independent clients and chains. See Attestor keys for the signature replay risk.

signers

signers defines the keys referenced elsewhere in the file. Each signer has a unique alias.

Local signer

For file: relayer, the CLI checks relayer, relayer.json, and the keys directory under the IBC home directory. The final path is typically ~/.ibc/keys/relayer.json.

Remote signer

The remote signer holds the key material and performs signing.

TLS for remote services

Remote signers, remote attestors, and remote provers all follow one rule: an https:// address turns TLS on, and anything else connects in plaintext. That address is the signer’s grpc, the attestor’s grpc, or a client end’s remoteProver.url.
Without a tls block, TLS trusts the system’s CAs and presents no client certificate. Add a tls block, with the keys listed in the remote attestor and remote signer tables, to change that; a client end’s remoteProver block takes it as tls. A tls block on an address that isn’t https:// is rejected, since its settings would be ignored. An https:// address without a port uses 443, so https://attestor.example.com connects to port 443; write https://host:port for any other port. A bare host:port connects in plaintext: attestors and provers dial it as http://host:port, and signers pass it to gRPC as written. An attestor or prover URL may carry a path but not a query or fragment, since the RPC path is appended to it. For a signer, an http:// or https:// URL becomes the gRPC target host:port, with 80 or 443 when the port is omitted, and must not carry userinfo, a path, a query or a fragment, which a gRPC target can’t express; other targets, such as dns:///host:port, are passed to gRPC as written. Set certFile and keyFile together for mTLS. The CA bundle and client certificate are read once at startup, so restart the process after rotating either. A client certificate that has expired or is not yet valid fails validation. TLS here covers outbound connections only. The CLI’s own API server on server.listenAddr listens without TLS.

Split the configuration by process

The complete example runs the relayer and both attestors together. In production, you can give each process only the blocks it uses:
  • A standalone relayer needs server, db, chains, relayer, the attestors it queries, and its transaction signers.
  • A standalone local attestor needs server, its chain, its attestors entry, and its attestation signer. It does not need db or relayer.

Next steps