# LIP-118 secured one side of the network. The other side still has one key holding everything

**URL:** https://forum.livepeer.org/t/lip-118-secured-one-side-of-the-network-the-other-side-still-has-one-key-holding-everything/3349
**Category:** Research & Protocol Improvements
**Created:** [August 31, 2026, 10:49am UTC](https://forum.livepeer.org/t/lip-118-secured-one-side-of-the-network-the-other-side-still-has-one-key-holding-everything/3349 "2026-08-31T10:49:18Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![chrishobcroft](https://yyz2.discourse-cdn.com/flex030/user_avatar/forum.livepeer.org/chrishobcroft/32/1340_2.png) [@chrishobcroft](https://forum.livepeer.org/u/chrishobcroft)
#### Post date: [August 31, 2026, 10:49am UTC](https://forum.livepeer.org/t/lip-118-secured-one-side-of-the-network-the-other-side-still-has-one-key-holding-everything/3349/1 "2026-08-31T10:49:19Z")

</div>

**Summary.** Livepeer’s payment protocol already contains the machinery to let a  
sender authorise other addresses to sign its tickets. It is present in the codebase  
and switched off. Turning it on would let a gateway’s funds be held by a Safe or  
any contract account, while a hot key does the per-second signing.

**The symmetry, which is the whole argument.**

**LIP-118 established that an address can act on behalf of another** — reward  
calling delegated, bounded, revocable on chain. **The orchestrator side of the  
network got materially safer**, because the key that performs the frequent action  
stopped having to be the key that holds the stake.

**The gateway side never got the same treatment.** A gateway must keep a key online  
to sign tickets many times a minute, and **today that key _is_ the sender** — so the  
key that has to be online is also the key holding the deposit and the reserve.

**Remote signing helps and is worth doing.** A signing machine that handles no media  
has a far smaller attack surface. But it changes **where the key runs, not what the  
key controls.** The online key still commands the balance. That is a property of the  
protocol, not of anyone’s deployment, and it is the part that can be fixed here.

**So: the same principle LIP-118 established, applied to the other half of the  
protocol.**

**What already exists in the code.** In `pm/sigverifier.go` there is an  
`ApprovedSigVerifier` — it recovers the address from a ticket signature and, if it  
does not match the sender, asks the broker whether that address is an _approved  
signer_ for the sender. **The entire type is commented out.** The live  
`DefaultSigVerifier` does a plain ECDSA recover and requires the recovered address  
to equal the sender. The `Broker` interface declares no `ApproveSigners`, and the  
deployed TicketBroker ABI has no such function.

The design anticipated this. It was never finished.

**What it unlocks.**

_Custody._ A gateway’s deposit and reserve held by a **Safe**. Compromise of a  
signing key then costs the tickets it can sign before removal — not the balance.

_Rotation._ A signer replaced by a transaction, rather than by moving funds to a new  
sender and rebuilding the channel.

_More than one operator._ Several approved signers for one sender, so a gateway  
survives an operator being unavailable **without anybody sharing a key.**

_Collectives._ A Safe with two or more owners funding a gateway that neither owner  
individually controls — two people sharing a broadcast’s cost, a venue and a  
producer splitting a bill, a group funding a public service. **Today every Livepeer  
payment channel is owned by exactly one private key on one machine. That is a limit  
on who can participate, not only on how safely.**

**There is a working precedent next door.** Swarm’s Volume Registry separates  
**owner** , **payer** and **chunk signer** as distinct on-chain roles: one party pays  
for storage, a different party writes to it, neither can do the other’s job. I have  
that running — a Safe owns and funds storage that a separate operator key writes to.  
**The shape is proven; Livepeer is missing only the approved-signer half.**

**Scope, as far as I can tell.** Restoring `ApprovedSigVerifier` is roughly forty  
lines that already exist. The contract side needs an approved-signer registry and  
the `Broker` interface extended to read it. I am not close enough to the contracts  
to estimate that half honestly, and would rather be corrected than guess.

**A design question I cannot answer.** Should approval be per-sender-per-signer, or  
should a sender nominate a contract that decides? The second is more flexible and  
much more to review.

**What I can contribute.** I run a gateway that pays orchestrators directly from one  
key, and I have the Safe-and-delegated-writer half working on the storage side. I am  
happy to test, to write the client half, or to be told this is the wrong shape and  
why.

---

<div class="post-metadata">

### Author: ![chrishobcroft](https://yyz2.discourse-cdn.com/flex030/user_avatar/forum.livepeer.org/chrishobcroft/32/1340_2.png) [@chrishobcroft](https://forum.livepeer.org/u/chrishobcroft)
#### Post date: [September 1, 2026, 8:12pm UTC](https://forum.livepeer.org/t/lip-118-secured-one-side-of-the-network-the-other-side-still-has-one-key-holding-everything/3349/2 "2026-09-01T20:12:55Z")

</div>

# Forum reply — amending the proposal after Doug’s critique

_For the existing thread. Unwrapped for pasting._

* * *

## Correcting the custody claim, and a better version of the proposal

Doug has pointed out that the central claim in my post does not hold as written, and I want to correct it in the thread rather than leave it standing.

**What I claimed:** that separating the signer from the sender means a compromised signing key costs “the tickets it can sign before it is removed — not the balance.”

**Why that is wrong:** a ticket’s `faceValue` is chosen by whoever signs it. So a compromised signing key signs **one enormous ticket** and takes the deposit. Splitting custody, on its own, does not protect the deposit at all.

**What does survive, and it is narrower than I said:** the **reserve** is protected. Withdrawal stays with the account keyholder, so a compromised signing key cannot pull the reserve even though it can sign. That is a real benefit and it is half of what I claimed.

## The stronger proposal, which is Doug’s

His suggestion, in a parenthesis: _put a limit on ticket size from the signing key._

That changes what an approved-signer registry is for. Instead of recording **whether** an address may sign for a sender, it records **how much a signature from that address may be worth**. Bounded delegation rather than binary delegation.

**And that is a better mechanism than the one I proposed** , for a reason worth stating plainly: it makes the loss ceiling explicit rather than making it a function of how quickly somebody notices a compromise and gets a revocation transaction mined. With a cap, the worst case is a number you chose in advance. Without one, the worst case is your reaction time.

It also composes with the reserve behaviour rather than replacing it. **Cap bounds the deposit; withdrawal delay protects the reserve.** Together they cover both halves of a sender’s balance, and neither covers both alone.

## An open design question

**Where does the cap live?** My instinct is that it belongs with the approval — the sender sets a maximum when authorising a signer, and the verifier only checks it — rather than being a parameter of the verifier itself. That keeps the authority with the party whose money it is, and means changing a cap is the same kind of action as granting or revoking.

But I am not close enough to the contracts to argue that. It may be cleaner in the broker, or as a per-sender rather than per-signer bound. Interested in views from anyone who is.

## A caveat on the ground this stands on

Doug also flagged that the deposit/reserve model may be **rethought under an uncapped node operator set in 2.0** : the reserve exists to secure against double spends across a _limited_ orchestrator set, and that reasoning does not hold if the set is unlimited.

**Worth surfacing before anyone builds on it.** If the reserve goes, then the reserve half of the argument above goes with it — and what remains is the deposit and the cap, which is also the half that does the real work. I would rather this thread be about the durable part.

## Where this leaves the ask

Still small, and now more precise. `ApprovedSigVerifier` exists in `pm/sigverifier.go` and is commented out; the `Broker` interface declares no `ApproveSigners` and the deployed ABI has no such function. **The change is no longer “restore the commented-out type” but “restore it with an amount attached”** — which is more contract work than I first suggested and a better thing to build.

I would rather have a correct proposal than my proposal. Thanks to Doug for the correction; the version above is his.
