Skip to main content
Current scope: Realtime AI Video (live-video-to-video) workloads only.
Remote signing is not supported for video transcoding.
A remote signer is a standalone go-livepeer mode that takes over all Ethereum-related responsibilities from the Gateway: signing payment tickets, managing PM session state, and providing the authentication signature for Orchestrator info requests. The Gateway communicates with the signer over the network and holds no Ethereum private key. Remote signers were introduced in PR #3791 and PR #3822, in January 2026.

Benefits

Key Isolation

By default, a go-livepeer Gateway holds its Ethereum private key in the same process that handles media from external clients. A vulnerability in media parsing or job handling could expose that key, allowing an attacker to drain the ETH deposit. A remote signer separates these concerns. The signer runs as a hardened service with a narrow, well-defined API surface. The Gateway never sees the private key - it only receives signed tickets and signatures.

Platform Flexibility

The PM system is complex enough that go-livepeer was historically the only Gateway implementation. Remote signers remove this barrier. A Python, browser, or mobile application can integrate with the Livepeer network by using a remote signer for all PM mechanics and interacting with a simple HTTP signing API instead of raw Arbitrum contracts. This is the foundation for the Livepeer SDK’s Gateway capabilities. Remote signers are also the technical primitive that build on.

Signer Mechanics

The remote signer implements two operations corresponding to the two places where Ethereum signing occurs in a Live AI Gateway session.

1. GetOrchestratorInfo signature

When a Gateway contacts an Orchestrator, it must provide an authentication signature. This signature is static for a given key and can be safely cached. At startup, the Gateway fetches this signature from the signer once, caches it, and reuses it for all Orchestrator info requests.
Gateway -> Signer: getOrchInfoSig()
Signer  -> Gateway: gatewaySig
Gateway -> Orchestrator: getOrchInfo(gatewaySig)

2. Payment Ticket Signing

For each payment in a Live AI session, the Gateway asks the signer to sign a ticket. The signer returns the signed ticket and updated session state. The Gateway is responsible for carrying that state forward into the next call.

Stateless Design

The signer stores no state between calls. State is carried by the Gateway and round-tripped on every signing request. The signer’s state is cryptographically signed to prevent the Gateway from fabricating or replaying it. This design enables running multiple signer instances behind a load balancer with no shared database, no synchronisation infrastructure, and seamless failover between instances.
HTTP 480 - expired ticket params
If the signer returns HTTP status 480, the ticket parameters from the Orchestrator have expired.
The Gateway should re-fetch OrchestratorInfo and restart the signing chain from the new parameters.

Prerequisites

  • A go-livepeer binary that includes remote signer support (confirm with livepeer --version; see PR #3822 for the implementation)
  • A funded Ethereum account on Arbitrum One for the signer (the Gateway itself needs no ETH)
  • An Arbitrum RPC endpoint accessible from the signer host
  • Network connectivity from the Gateway host to the signer service

Running the Signer

Operational Rules

Running a remote signer in production requires attention to a few non-obvious rules. Violating these leads to rejected tickets and failed jobs.
For production reliability, run two or more signer instances behind a load balancer. Because the signer is stateless, failover is seamless: the Gateway starts a new state chain from whichever instance responds next. No coordination infrastructure required.A simple round-robin or health-check-based load balancer is sufficient.
Every call to signTicket returns a new signerState. This state must be passed back to the next signTicket call for the same session. Passing stale state or an empty state on subsequent calls causes nonce collisions, which produce invalid tickets that Orchestrators reject.First call: signTicket(state=null, ticketParams) - null is correct here. Subsequent calls: signTicket(signerStateFromPreviousCall, ticketParams) - always use the most recent state.
Do not make concurrent signTicket calls for the same session. State advances sequentially; concurrent calls produce conflicting states and invalid tickets. One session maps to one sequential signing chain.Multiple sessions can run concurrently, each with their own state chain.
The remote signer handles signing only. It does not discover or select Orchestrators. For off-chain Live AI Gateways, supply Orchestrator addresses via -orchAddr or a discovery endpoint. Clearinghouse services may bundle discovery.

Security

With a remote signer correctly deployed:
  • The Gateway process holds no Ethereum private key
  • A fully compromised Gateway cannot sign payment tickets or drain ETH funds independently
  • The signer’s state is cryptographically signed and cannot be forged by the Gateway
  • Multiple Gateway instances can be keyless, reducing the blast radius of any single compromise
What a remote signer does not protect against:
  • A compromise of the signer service itself (the signer holds the actual key)
  • Unlimited ticket requests from a compromised Gateway (rate limiting is the signer’s responsibility)
  • Video transcoding workloads (not in scope)

Community Signer

A community-operated remote signer is available for testing and early development: Elite Encoder Remote Signer: https://signer.eliteencoder.net/ This instance provides free ETH for testing. It uses SIWE (ERC-4361 Sign-In with Ethereum) for authentication and issues per-user JWT tokens.
Do not use for production workloads.
The signer holds the Gateway’s signing key and can observe all tickets signed through it.
For production, run a dedicated signer instance.
Last modified on March 16, 2026