livepeer / livepeer/go-livepeer
Support external key custody / remote signing (Turnkey, KMS) for payment signers
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 586
- Forks
- 226
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 19
Description
[!NOTE]
Idea originally raised by @eliteprox.
Summary
Allow the remote payment signer (-remoteSigner) to use an external key-custody / remote-signing backend (e.g. Turnkey, AWS KMS, GCP KMS, clef) instead of only a local keystore, behind a pluggable signing interface.
Motivation
The remote signer holds an Ethereum hot key to sign PM tickets and to fund on-chain deposit/reserve. Today that key is a local keystore on the signer host. For a shared, pooled-wallet payment signer that is the single biggest risk: compromise the host and the deposit/reserve can be drained, and there are no wallet-level spend controls.
Proposal
Make the signing path pluggable and add one external-signer client that speaks a standard remote-signing protocol, rather than integrating each provider. Backends then sit behind that protocol, outside go-livepeer:
- Port (in go-livepeer): a standard external-signer client, e.g. go-ethereum's
accounts/external(clef JSON-RPC) or a Web3Signer-compatible API. - Adapters (outside go-livepeer): Turnkey, AWS KMS, GCP KMS, HashiCorp Vault, HSM. Web3Signer already ships plugins for KMS/Vault/HSM; others reach the port via a thin shim. Adding a backend means running a sidecar/config change, no go-livepeer change.
The key never leaves the enclave/KMS; the signer asks the backend to sign:
- PM ticket payloads (raw secp256k1 message signing)
- State-blob and orchestrator-info signatures
- On-chain transactions (
fundDeposit/fundReserve/withdraw) — go-livepeer still builds the tx (nonce, gas) and broadcasts via its own RPC; the backend only returns a signature.
Note: providers like Turnkey are wallet / key-management infrastructure (enclave-secured keys), not a "signer" product. The overloaded term here is go-livepeer's
-remoteSigner; the external signer is the key backend.
Integration point (current code)
Signing already goes through a clean interface, so this is additive, not surgery:
pm.Signer(pm/signer.go):Sign(msg []byte) ([]byte, error)+Account() accounts.Account.eth.AccountManager(eth/accountmanager.go) is the only implementation today and wraps a local go-ethereumkeystore.KeyStore(Sign,SignTypedData,Unlock).server/remote_signer.goonly ever signs via these interfaces (Eth.Sign(...)), never a raw key.
So the work is an alternative AccountManager/Signer implementation backed by the external client, plus a flag to select it. remote_signer.go itself does not change.
Benefits for payment signers
- No hot key on the signer host. The pooled wallet key lives in the enclave/KMS, removing the worst failure mode of running a shared payment signer.
- Policy-based loss prevention. Providers like Turnkey enforce signing policies (max value per period, allowlisted recipients/contracts, quorum on withdrawals) — i.e. anti-drain on deposit/reserve at the key layer, even if the signer is compromised.
- Safer HA / redundancy. Run redundant signers without copying a raw private key to each host.
- No protocol change. Tickets, deposit/reserve, redemption, and the gateway→orchestrator flow stay byte-identical. Only how a signature is produced changes.
Scope / considerations
- Implement behind the existing
pm.Signer/AccountManagerinterface so the backend (local keystore vs Turnkey/KMS/HSM) is a swappable adapter. - Raw-hash signing: PM tickets are signed as a raw keccak hash. Some remote signers refuse raw-hash signing for safety, so the chosen interface must allow it (clef
account_signDataand Web3Signer eth1 modes can) — verify against the ticket format. - Hot-path latency + cost: PM mints tickets frequently, so per-signature API round-trips add latency and cost vs a local key. Worth measuring against minting rate; batch/cached signing may be needed.
- This is cleanly enabled by factoring the signer into a standalone package, but can land as a contained adapter on the current
-remoteSignermode.
Out of scope
- Per-user / embedded wallets (a larger non-custodial direction) — separate discussion.
- Clearinghouse / accounting changes — none required; this sits below the signer seam.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with pm/signer.go and eth/accountmanager.go to understand the existing signing interfaces, then trace their use from server/remote_signer.go. Compare the proposed external-signing protocols and verify how PM ticket, state-blob, orchestrator-info, and transaction signatures must be represented. Done means an external-signer implementation and selection mechanism work through the existing interfaces without requiring changes to remote_signer.go.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- backend, blockchain, payments, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100