变更记录
- 2019-11-06:初始草案
- 2020-10-12:更新草案
- 2020-11-13:已接受
- 2020-05-06:proto API 更新,使用
sdk.Msg替代sdk.ServiceMsg(后者概念已从 Cosmos SDK 中移除) - 2022-04-20:更新
SendAuthorization的 proto 文档,以明确SpendLimit是必填字段。(可使用通用授权配合 bank msg type url 创建无额度限制的 bank 授权)
状态
已接受摘要
本 ADR 定义了x/authz 模块,该模块允许账户向其他账户授予授权,使其能够代表该账户执行操作。
背景
推动该模块设计的具体用例包括:- 希望将提案投票能力委托给除已委托质押所对应账户之外的其他账户
- 最初在 #4480 中提出的“sub-keys”功能,这是一个术语,用来描述本模块与 ADR 029 中的
fee_grant模块以及 group module 共同提供的功能。
决策
我们将创建一个名为authz 的模块,用于提供将任意权限从一个账户(granter,授权方)授予另一个账户(grantee,被授权方)的能力。授权必须针对特定的 Msg 服务方法逐一授予,并通过 Authorization 接口的实现来完成。
类型
授权决定了具体授予哪些权限。它们具有可扩展性,可以为任意Msg 服务方法定义,甚至可以定义在声明该 Msg 方法的模块之外。Authorization 通过 TypeURL 引用 Msg。
Authorization
MsgSend 定义如下的 SendAuthorization,它接收一个 SpendLimit,并在使用后将其递减直到归零:
Authorization 接口为 MsgSend 实现另一种能力类型,而无需修改底层 bank 模块。
关于 AcceptResponse 的几点说明
-
如果授权被接受,
AcceptResponse.Accept字段将被设为true。 但如果被拒绝,Accept函数会直接返回错误(不会将AcceptResponse.Accept设为false)。 -
只有当授权确实发生变化时,
AcceptResponse.Updated字段才会被设为非 nil 值。 如果授权保持不变(例如在GenericAuthorization中通常总是如此),该字段将为nil。
Msg 服务
路由中间件
authz 的 Keeper 将暴露一个 DispatchActions 方法,使其他模块能够基于 Authorization 授权将 Msg 发送到路由器:
CLI
tx exec 方法
当 CLI 用户希望使用 MsgExec 代表其他账户运行交易时,可以使用 exec 方法。例如,gaiacli tx gov vote 1 yes --from <grantee> --generate-only | gaiacli tx authz exec --send-as <granter> --from <grantee> 会发送如下交易:
tx grant <grantee> <authorization> --from <granter>
该 CLI 命令会发送一笔 MsgGrant 交易。authorization 应在 CLI 中编码为 JSON。
tx revoke <grantee> <method-name> --from <granter>
该 CLI 命令会发送一笔 MsgRevoke 交易。
内置授权
SendAuthorization
GenericAuthorization
影响
正面
- 用户将能够授权其他用户代表其账户执行任意操作,从而改善许多场景下的密钥管理
- 该方案比先前考虑的方法更通用,并且基于
Authorization接口的方法可以由 SDK 用户扩展,以覆盖其他用例
负面
中性
参考
Changelog
- 2019-11-06: Initial Draft
- 2020-10-12: Updated Draft
- 2020-11-13: Accepted
- 2020-05-06: proto API updates, use
sdk.Msginstead ofsdk.ServiceMsg(the latter concept was removed from Cosmos SDK) - 2022-04-20: Updated the
SendAuthorizationproto docs to clarify theSpendLimitis a required field. (Generic authorization can be used with bank msg type url to create limit less bank authorization)
Status
AcceptedAbstract
This ADR defines thex/authz module which allows accounts to grant authorizations to perform actions
on behalf of that account to other accounts.
Context
The concrete use cases which motivated this module include:- the desire to delegate the ability to vote on proposals to other accounts besides the account which one has delegated stake
- “sub-keys” functionality, as originally proposed in #4480 which
is a term used to describe the functionality provided by this module together with
the
fee_grantmodule from ADR 029 and the group module.
Decision
We will create a module namedauthz which provides functionality for
granting arbitrary privileges from one account (the granter) to another account (the grantee). Authorizations
must be granted for a particular Msg service methods one by one using an implementation
of Authorization interface.
Types
Authorizations determine exactly what privileges are granted. They are extensible and can be defined for anyMsg service method even outside of the module where
the Msg method is defined. Authorizations reference Msgs using their TypeURL.
Authorization
SendAuthorization like this is defined for MsgSend that takes
a SpendLimit and updates it down to zero:
MsgSend could be implemented
using the Authorization interface with no need to change the underlying
bank module.
Small notes on AcceptResponse
-
The
AcceptResponse.Acceptfield will be set totrueif the authorization is accepted. However, if it is rejected, the functionAcceptwill raise an error (without settingAcceptResponse.Accepttofalse). -
The
AcceptResponse.Updatedfield will be set to a non-nil value only if there is a real change to the authorization. If authorization remains the same (as is, for instance, always the case for aGenericAuthorization), the field will benil.
Msg Service
Router Middleware
Theauthz Keeper will expose a DispatchActions method which allows other modules to send Msgs
to the router based on Authorization grants:
CLI
tx exec Method
When a CLI user wants to run a transaction on behalf of another account using MsgExec, they
can use the exec method. For instance gaiacli tx gov vote 1 yes --from <grantee> --generate-only | gaiacli tx authz exec --send-as <granter> --from <grantee>
would send a transaction like this:
tx grant <grantee> <authorization> --from <granter>
This CLI command will send a MsgGrant transaction. authorization should be encoded as
JSON on the CLI.
tx revoke <grantee> <method-name> --from <granter>
This CLI command will send a MsgRevoke transaction.
Built-in Authorizations
SendAuthorization
GenericAuthorization
Consequences
Positive
- Users will be able to authorize arbitrary actions on behalf of their accounts to other users, improving key management for many use cases
- The solution is more generic than previously considered approaches and the
Authorizationinterface approach can be extended to cover other use cases by SDK users