Authz and Ledger signing — an executive summary

Simon Warta
Confio
Published in
4 min readMar 16, 2022

During Confio’s work on CosmJS, I was made aware that it is currently not possible to sign authz message types with the Cosmos App on Ledger devices. In this write-up, I’ll summarize the status quo for executives and users. We’ll close with a look into the future.

Photo by Hendrik Morkel on Unsplash

Authz

The authorization module introduced with Cosmos SDK 0.43 allows a user to permit a different address to act on its behalf. By restricting what this second address can do, you can delegate everyday low-risk tasks to a keypair that is protected differently than a main account. The way this is used is by sending a single transaction with a message of type MsgGrant once. After that, the other address can do whatever it was allowed to do. This can then be e.g. an employee or a bot. The workshop Building for UX with Msg Authorization and Fee Grants by Amaury (Regen) and Likhita (Vitwit) shows this in detail.

One use case of authz is delegating the permission to vote to an employee’s address which does not necessarily get access to funds. This can be seen here.

It did not take long until a first validator started to use the feature to promote auto-compounding, which was quickly followed by a multi-validator solution. Auto-compounding is a simple idea: you claim staking rewards on a regular basis and stake them in addition to your previous stake. The exponential nature of the interest on interest formula makes this financially attractive for stakers.

The simplicity of auto-compounding along with the financial incentive quickly created a lot of interest in the new module.

Sign modes

Right now, there are two sign modes in Cosmos: SIGN_MODE_DIRECT and SIGN_MODE_LEGACY_AMINO_JSON which are often called just “direct” or “Amino”. Direct mode signs the serialized protobuf bytes directly. It was created with the release of Stargate, which started to use protobuf as a binary serialization format for transactions. Amino JSON is the format that was used for signing before Stargate. As the name suggests, a JSON representation of the transaction is signed. It remained supported after the Stargate release because this is the sign mode that can be used with Ledger hardware wallets.

Since the direct mode does not include field names and insufficient type information if the signer does not have the schema file of all possible message types, it is not suitable for Ledger signing. To overcome this limitation, a 3rd sign mode called “textual” is developed right now.

Amino JSON support for authz messages

The original plan during the Stargate release in 2021 was to not implement Amino JSON sign mode for new message types and new modules such as IBC but only preserve the status quo. But since this would exclude Ledger users from accessing this functionality, the MsgTransfer for IBC was the first exception. Over time people got used to having multiple sign modes and accepted that textual mode would take longer than originally anticipated, so the plan was discarded.

The bug

The authz modules also implement a JSON representation. However, the generated JSON is not in the general Amino JSON format which contains a type/value container. We’d expect a representation like this:

Expected Amino JSON representation of MsgGrant

Instead, the value is lifted one level:

Actual Amino JSON representation of MsgGrant

This bug is tracked in the Cosmos SDK.

Usage from command line

The authz messages can be successfully signed from command line with a Ledger device. The reason for this is that the blockchain node and the CLI both use the same code for the message serialization for signing. Also, the Cosmos app on the Ledger cares very little about the structure of JSON it displays and signs. Because client and node code agree on the buggy representation, this can easily be missed by manual testing.

Usage from the web

CosmJS is used by the majority of web applications connecting to Cosmos chains. It contains an independent implementation of the Amino JSON representation for each message type. CosmJS expects the type/value wrapper for all message types and cannot easily support the buggy JSON representation.

It would be possible to hack around this limitation by re-implementing the buggy JSON representation. However, I don’t think this is how resources should be allocated, and messing around with signing code is usually dangerous.

The future

The CosmJS maintainers will wait for Cosmos SDK 0.46+ to be shipped, which contains the real fix. Then it will become easy to add the correct Amino JSON representation for the authz messages, such that sign mode direct and sign mode Amino JSON can be supported equally well. This will unlock the authz+web+Ledger use cases through Keplr or directly via WebUSB.

Big thanks to all contributors from various teams, especially Riccardo for digging into this, Amaury & Regen crew for shipping the fix as part of the next release, Noam from Interchain for connecting people across teams and time zones.

--

--