-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ADR 030: Authorization Module #7105
Merged
Merged
Changes from 4 commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
18b5c8b
Add ADR 030
aaronc fdeaa27
Cleanup
aaronc 2098c59
Updates
aaronc c7fe2c5
Merge branch 'master' of https://github.com/cosmos/cosmos-sdk into aa…
aaronc a8e69fd
Merge branch 'master' of https://github.com/cosmos/cosmos-sdk into aa…
aaronc e021c9d
Updates based on ADR 031
aaronc 9f14576
Add abstract and context
aaronc 2a823dd
Updates
aaronc 4e593f3
Update module name as per #7615
aaronc 1051cdb
Updates from reviews
aaronc 68372a1
Merge branch 'master' of github.com:cosmos/cosmos-sdk into aaronc/adr…
aaronc 789f45c
Rename
aaronc 14ca1f2
CLI update
aaronc 8cb3c5d
Merge branch 'master' into aaronc/adr-msg-auth
02580d9
Merge branch 'master' into aaronc/adr-msg-auth
aaronc 9e7123d
Update docs/architecture/adr-030-authz-module.md
aaronc e041142
Update docs/architecture/adr-030-authz-module.md
aaronc 4310eb7
Update docs/architecture/adr-030-authz-module.md
aaronc 8f41109
Update docs/architecture/adr-030-authz-module.md
aaronc 39e38f5
Code review updates
aaronc 2017248
Merge remote-tracking branch 'origin/aaronc/adr-msg-auth' into aaronc…
aaronc cc7997f
Update docs
aaronc c2f078b
Merge branch 'master' into aaronc/adr-msg-auth
aaronc File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
# ADR 030: Msg Authorization Module | ||
|
||
## Changelog | ||
|
||
- 2019-11-06: Initial Draft | ||
- 2020-08-18: Updated Draft | ||
|
||
## Status | ||
|
||
Accepted | ||
|
||
## Context | ||
|
||
|
||
## Decision | ||
|
||
We will create a module named `msg_authorization`. The `msg_authorization` module provides support for | ||
granting arbitrary capabilities from one account (the granter) to another account (the grantee). Capabilities | ||
must be granted for a particular type of `sdk.Msg` one by one using an implementation | ||
of `Capability`. | ||
|
||
### Types | ||
|
||
Capabilities determine exactly what action is delegated. They are extensible | ||
and can be defined for any sdk.Msg type even outside of the module where the Msg is defined. | ||
|
||
#### Capability | ||
|
||
```go | ||
type Capability interface { | ||
// MsgType returns the type of Msg's that this capability can accept | ||
MsgType() sdk.Msg | ||
aaronc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Accept determines whether this grant allows the provided action, and if | ||
// so provides an upgraded capability grant | ||
Accept(msg sdk.Msg, block abci.Header) (allow bool, updated Capability, delete bool) | ||
} | ||
``` | ||
|
||
For example a `SendCapability` like this is defined for `MsgSend` that takes | ||
a `SpendLimit` and updates it down to zero: | ||
|
||
```go | ||
type SendCapability struct { | ||
// SpendLimit specifies the maximum amount of tokens that can be spent | ||
// by this capability and will be updated as tokens are spent. If it is | ||
// empty, there is no spend limit and any amount of coins can be spent. | ||
SpendLimit sdk.Coins | ||
} | ||
|
||
func (cap SendCapability) MsgType() sdk.Msg { | ||
return &bank.MsgSend{} | ||
} | ||
|
||
func (cap SendCapability) Accept(msg sdk.Msg, block abci.Header) (allow bool, updated Capability, delete bool) { | ||
switch msg := msg.(type) { | ||
case bank.MsgSend: | ||
left, invalid := cap.SpendLimit.SafeSub(msg.Amount) | ||
if invalid { | ||
return false, nil, false | ||
} | ||
if left.IsZero() { | ||
return true, nil, true | ||
} | ||
return true, SendCapability{SpendLimit: left}, false | ||
} | ||
return false, nil, false | ||
} | ||
``` | ||
|
||
A different type of capability for `MsgSend` could be implemented | ||
using the `Capability` interface with no need to change the underlying | ||
`bank` module. | ||
|
||
### Messages | ||
|
||
#### `MsgGrant` | ||
|
||
```go | ||
// MsgGrant grants the provided capability to the grantee on the granter's | ||
// account with the provided expiration time. | ||
type MsgGrant struct { | ||
Granter sdk.AccAddress `json:"granter"` | ||
Grantee sdk.AccAddress `json:"grantee"` | ||
Capability Capability `json:"capability"` | ||
// Expiration specifies the expiration time of the grant | ||
Expiration time.Time `json:"expiration"` | ||
} | ||
``` | ||
|
||
#### MsgRevoke | ||
|
||
```go | ||
// MsgRevoke revokes any capability with the provided sdk.Msg type on the | ||
// granter's account with that has been granted to the grantee. | ||
type MsgRevoke struct { | ||
Granter sdk.AccAddress `json:"granter"` | ||
Grantee sdk.AccAddress `json:"grantee"` | ||
// CapabilityMsgType is the full protobuf message name for the Msg type | ||
// whose capability is being revoked. | ||
CapabilityMsgType string `json:"capability_msg_type"` | ||
} | ||
aaronc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
|
||
#### MsgExecDelegated | ||
|
||
```go | ||
// MsgExecDelegated attempts to execute the provided messages using | ||
// capabilities granted to the grantee. Each message should have only | ||
// one signer corresponding to the granter of the capability. | ||
type MsgExecDelegated struct { | ||
Grantee sdk.AccAddress `json:"grantee"` | ||
Msgs []sdk.Msg `json:"msg"` | ||
} | ||
``` | ||
|
||
### Keeper | ||
|
||
#### Constructor: `NewKeeper(storeKey sdk.StoreKey, cdc *codec.Codec, router sdk.Router) Keeper` | ||
|
||
The message delegation keeper receives a reference to the baseapp's `Router` in order | ||
to dispatch delegated messages. | ||
|
||
#### `DispatchActions(ctx sdk.Context, grantee sdk.AccAddress, msgs []sdk.Msg) sdk.Result` | ||
|
||
`DispatchActions` attempts to execute the provided messages via capability | ||
grants from the message signer to the grantee. | ||
|
||
#### `Grant(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, capability Capability, expiration time.Time)` | ||
|
||
Grants the provided capability to the grantee on the granter's account with the provided expiration | ||
time. If there is an existing capability grant for the same `sdk.Msg` type, this grant | ||
overwrites that. | ||
|
||
#### `Revoke(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType sdk.Msg)` | ||
|
||
Revokes any capability for the provided message type granted to the grantee by the granter. | ||
|
||
#### `GetCapability(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType sdk.Msg) (cap Capability, expiration time.Time)` | ||
|
||
Returns any `Capability` (or `nil`), with the expiration time, granted to the grantee by the granter for the provided msg type. | ||
|
||
### CLI | ||
|
||
#### `--send-as` Flag | ||
|
||
When a CLI user wants to run a transaction as another user using `MsgExecDelegated`, they | ||
can use the `--send-as` flag. For instance `gaiacli tx gov vote 1 yes --from mykey --send-as cosmos3thsdgh983egh823` | ||
would send a transaction like this: | ||
|
||
```go | ||
MsgExecDelegated { | ||
Grantee: mykey, | ||
Msgs: []sdk.Msg{ | ||
MsgVote { | ||
ProposalID: 1, | ||
Voter: cosmos3thsdgh983egh823 | ||
Option: Yes | ||
} | ||
} | ||
} | ||
``` | ||
#### `tx grant <grantee> <capability> --from <granter>` | ||
|
||
This CLI command will send a `MsgGrant` tx. `capability` should be encoded as | ||
JSON on the CLI. | ||
|
||
#### `tx revoke <grantee> <capability-msg-type> --from <granter>` | ||
|
||
This CLI command will send a `MsgRevoke` tx. `capability-msg-type` should be encoded as | ||
JSON on the CLI. | ||
|
||
### Built-in Capabilities | ||
|
||
#### `SendCapability` | ||
|
||
```go | ||
type SendCapability struct { | ||
// SpendLimit specifies the maximum amount of tokens that can be spent | ||
// by this capability and will be updated as tokens are spent. If it is | ||
// empty, there is no spend limit and any amount of coins can be spent. | ||
SpendLimit sdk.Coins | ||
} | ||
``` | ||
|
||
#### `GenericCapability` | ||
|
||
```go | ||
// GenericCapability grants the permission to execute any transaction of the provided | ||
// sdk.Msg type without restrictions | ||
type GenericCapability struct { | ||
// MsgType is the type of Msg this capability grant allows | ||
MsgType sdk.Msg | ||
} | ||
``` | ||
|
||
## Status | ||
|
||
Accepted | ||
|
||
## Consequences | ||
|
||
### Positive | ||
|
||
- Users will be able to authorize arbitrary permissions on their accounts to other | ||
users, simplifying key management for some use cases | ||
- The solution is more generic than previously considered approaches and the | ||
`Capability` interface approach can be extended to cover other use cases by | ||
SDK users | ||
|
||
### Negative | ||
|
||
### Neutral | ||
|
||
## References | ||
|
||
- Initial Hackatom implementation: https://github.com/cosmos-gaians/cosmos-sdk/tree/hackatom/x/delegation | ||
- Post-Hackatom spec: https://gist.github.com/aaronc/b60628017352df5983791cad30babe56#delegation-module | ||
- B-Harvest subkeys spec: https://github.com/cosmos/cosmos-sdk/issues/4480 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ADR is about authorization and delegation.
How about renaming to Delegation Module, Auth Delegation Module? ... and respectively other types below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original name was msg delegation but people complained that it was confusing because of validator delegation. So we chose authorization as an alternative
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so how about the other proposals, Auth Delegation Module?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
People basically didn't want us to use the word "delegation" at all as I recall.