Overview
The IBC Attestor is a stateless gRPC service that produces cryptographic attestations of blockchain state for use in IBC v2 cross-chain communication. It connects to a chain via an adapter (EVM, Cosmos, or Solana) and signs state at requested heights using either a local keystore or a remote signing service. Each deployed attestor instance handles a single chain type. To attest multiple chains, deploy one instance per chain.Components
1. IBC Attestor (this service)
The core attestation service. Exposes a gRPC API on port8090 (configurable) and a metrics endpoint on port 9000.
Image: ghcr.io/cosmos/ibc-attestor:latest
Binary: ibc_attestor
2. Signer Service (external dependency)
The attestor requires a secp256k1 signing key. Two deployment modes are supported:- Local signer — key is stored in an encrypted keystore file on disk, read directly by the attestor process
- Remote signer — the attestor delegates signing to an external gRPC signer service (e.g.
platform-signer) over the network
3. Chain RPC Endpoint (external dependency)
Each attestor instance requires a live RPC endpoint for the chain it is attesting:| Chain Type | Required Endpoint |
|---|---|
| EVM | JSON-RPC HTTP endpoint (e.g. Alchemy, Infura, or self-hosted geth) |
| Cosmos | Tendermint RPC HTTP endpoint |
| Solana | Solana JSON-RPC HTTP endpoint |
Configuration
The attestor is configured via a TOML file passed with--config. The chain type and signer mode are passed as CLI flags.
Full configuration reference
Note: Only the fields relevant to the chosen--signer-typeneed to be present. The[adapter]fields that apply depend on the--chain-type.
EVM example (attestor-evm.toml)
Cosmos example (attestor-cosmos.toml)
Local signer example (attestor-local.toml)
CLI Reference
Key Management
Before running the attestor with a local signer, generate a keypair:Docker Deployment
Building the image
- Builder — Rust 1.88 on Debian Bookworm; compiles the binary with
cargo build --release --locked - Runtime —
debian:bookworm-slimwith onlyca-certificatesandlibssl3; runs as non-root usernonroot(uid 65532)
Running with Docker
The config file must be mounted into the container. The chain type is passed as a CLI argument. With remote signer (recommended):Docker Compose example
Kubernetes Deployment
The attestor is stateless and well-suited for Kubernetes. Below is a reference manifest.Ports
| Port | Protocol | Purpose |
|---|---|---|
8090 | gRPC (HTTP/2) | Attestation API — used by relayers and the fleet backend |
9000 | HTTP | Metrics (Prometheus) and observability |
Thelisten_addrin your TOML config controls the gRPC port.8090matches theEXPOSEin the Dockerfile; adjust to match your config.
Networking
Signer connectivity
The attestor connects to the signer service at startup of each signing request (connections are created on-demand). The endpoint must be reachable from the attestor container:- Same Docker network: use the container name and port (e.g.
http://signer:9006) - Kubernetes: use the service DNS name (e.g.
http://signer-service.ibc.svc.cluster.local:9006) - Cross-network: ensure firewall/security group rules permit TCP on the signer port
Chain RPC connectivity
The attestor polls the chain RPC on each attestation request. Ensure theadapter.url is reachable from wherever the attestor runs. For EVM chains with finality_offset unset, the RPC must support the finalized block tag (standard on most clients; may not be available on test networks).
DNS
When deploying alongside Kurtosis-managed chains or other service-mesh-based infrastructure, ensure the attestor container’s DNS resolves the RPC hostnames correctly. Custom DNS servers can be set via Docker’s--dns flag or Kubernetes dnsConfig.
Observability
The attestor emits structured JSON logs viatracing. Log level is controlled by the RUST_LOG environment variable:
OTEL_EXPORTER_* environment variables if you want distributed traces.
Prometheus metrics are exposed on port 9000.
Health Checking
The attestor is considered ready when it can successfully serve aStateAttestation gRPC request. There is no separate health endpoint; use gRPC health probes or poll StateAttestation with a low height (e.g. height=1) to verify liveness.
A 30-second startup timeout is typical — the attestor needs the chain RPC and signer to be reachable before it can respond.
Multi-Chain Deployments
Deploy one attestor instance per chain. Each instance gets its own config file specifying the chain’s RPC URL and chain type. They can share a single signer service, differentiating keys bywallet_id.
On-Chain Registration
The Ethereum address derived from the attestor’s signing key must be registered with the IBC light client on-chain before attestations will be accepted. After deploying:-
Retrieve the public key/address:
- Register the address with the IBC router contract or light client configuration as required by your chain’s deployment.
GetWallet RPC before deployment.