diff --git a/Gopkg.lock b/Gopkg.lock
index ac4f2f285d14ed8b28b9331e02b41f7106c6ba3d..fb5c586a4249ae7666a6417bb8d71f131b348b1f 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -31,7 +31,7 @@
   name = "github.com/btcsuite/btcd"
   packages = ["btcec"]
   pruneopts = "NUT"
-  revision = "f673a4b563b57b9a95832545c878669a7fa801d9"
+  revision = "9a2f9524024889e129a5422aca2cff73cb3eabf6"
 
 [[projects]]
   branch = "master"
@@ -436,7 +436,7 @@
     "ssh/terminal",
   ]
   pruneopts = "NUT"
-  revision = "a2144134853fc9a27a7b1e3eb4f19f1a76df13c9"
+  revision = "c126467f60eb25f8f27e5a981f32a87e3965053f"
 
 [[projects]]
   digest = "1:15dbe437d38eb2103f6b55348758958a6f85a400ecc16fcb53b3f271d38cd8ea"
@@ -495,7 +495,7 @@
   name = "google.golang.org/genproto"
   packages = ["googleapis/rpc/status"]
   pruneopts = "NUT"
-  revision = "fedd2861243fd1a8152376292b921b394c7bef7e"
+  revision = "02b4e95473316948020af0b7a4f0f22c73929b0e"
 
 [[projects]]
   digest = "1:f778941d5c2e46da5e0f5d553d3e80bf70eb40d2e80bb4c649b625b9133f3d5f"
@@ -552,7 +552,9 @@
     "github.com/go-kit/kit/log/term",
     "github.com/gogo/protobuf/gogoproto",
     "github.com/gogo/protobuf/proto",
+    "github.com/gogo/protobuf/types",
     "github.com/golang/protobuf/proto",
+    "github.com/golang/protobuf/ptypes/timestamp",
     "github.com/gorilla/websocket",
     "github.com/howeyc/gopass",
     "github.com/imdario/mergo",
diff --git a/Makefile b/Makefile
index fcc9956dd5a37a02ae95ffb288d57712202355ef..3db456789da99d0d0a401b9074d08210c8db3833 100644
--- a/Makefile
+++ b/Makefile
@@ -78,7 +78,7 @@ protobuf_deps:
 # Implicit compile rule for GRPC/proto files (note since pb.go files no longer generated
 # in same directory as proto file this just regenerates everything
 %.pb.go: %.proto
-	protoc -I vendor -I protobuf $< --gogo_out=plugins=grpc:${GOPATH}/src
+	protoc -I protobuf -I vendor $< --gogo_out=plugins=grpc:${GOPATH}/src
 
 .PHONY: protobuf
 protobuf: $(PROTO_GO_FILES)
diff --git a/execution/contexts/permissions_context.go b/execution/contexts/permissions_context.go
index 00cbd1a5589823ba72a7d59f55e361a59238c197..ac4c450b3adf904ba0d85f776aac597e62804a2e 100644
--- a/execution/contexts/permissions_context.go
+++ b/execution/contexts/permissions_context.go
@@ -44,7 +44,7 @@ func (ctx *PermissionsContext) Execute(txe *exec.TxExecution) error {
 		return fmt.Errorf("PermsTx received containing invalid PermArgs: %v", err)
 	}
 
-	permFlag := ctx.tx.PermArgs.PermFlag
+	permFlag := ctx.tx.PermArgs.Action
 	// check permission
 	if !HasPermission(ctx.StateWriter, inAcc, permFlag, ctx.Logger) {
 		return fmt.Errorf("account %s does not have moderator permission %s (%b)", ctx.tx.Input.Address,
@@ -65,17 +65,17 @@ func (ctx *PermissionsContext) Execute(txe *exec.TxExecution) error {
 		"perm_args", ctx.tx.PermArgs.String())
 
 	var permAcc acm.Account
-	switch ctx.tx.PermArgs.PermFlag {
+	switch ctx.tx.PermArgs.Action {
 	case permission.HasBase:
 		// this one doesn't make sense from txs
 		return fmt.Errorf("HasBase is for contracts, not humans. Just look at the blockchain")
 	case permission.SetBase:
-		permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Address,
+		permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Target,
 			func(perms *permission.AccountPermissions) error {
 				return perms.Base.Set(*ctx.tx.PermArgs.Permission, *ctx.tx.PermArgs.Value)
 			})
 	case permission.UnsetBase:
-		permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Address,
+		permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Target,
 			func(perms *permission.AccountPermissions) error {
 				return perms.Base.Unset(*ctx.tx.PermArgs.Permission)
 			})
@@ -87,20 +87,20 @@ func (ctx *PermissionsContext) Execute(txe *exec.TxExecution) error {
 	case permission.HasRole:
 		return fmt.Errorf("HasRole is for contracts, not humans. Just look at the blockchain")
 	case permission.AddRole:
-		permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Address,
+		permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Target,
 			func(perms *permission.AccountPermissions) error {
 				if !perms.AddRole(*ctx.tx.PermArgs.Role) {
 					return fmt.Errorf("role (%s) already exists for account %s",
-						*ctx.tx.PermArgs.Role, *ctx.tx.PermArgs.Address)
+						*ctx.tx.PermArgs.Role, *ctx.tx.PermArgs.Target)
 				}
 				return nil
 			})
 	case permission.RemoveRole:
-		permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Address,
+		permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Target,
 			func(perms *permission.AccountPermissions) error {
 				if !perms.RmRole(*ctx.tx.PermArgs.Role) {
 					return fmt.Errorf("role (%s) does not exist for account %s",
-						*ctx.tx.PermArgs.Role, *ctx.tx.PermArgs.Address)
+						*ctx.tx.PermArgs.Role, *ctx.tx.PermArgs.Target)
 				}
 				return nil
 			})
diff --git a/permission/permission.pb.go b/permission/permission.pb.go
index b72986011d0be70e3ed447ac9745961bd7388b3e..da42a596ccca8986f5ed7f27f39077291efab47e 100644
--- a/permission/permission.pb.go
+++ b/permission/permission.pb.go
@@ -94,20 +94,23 @@ func (*BasePermissions) XXX_MessageName() string {
 }
 
 type PermArgs struct {
-	PermFlag   PermFlag                                      `protobuf:"varint,1,opt,name=PermFlag,casttype=PermFlag" json:"PermFlag"`
-	Address    *github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,2,opt,name=Address,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address,omitempty"`
-	Permission *PermFlag                                     `protobuf:"varint,3,opt,name=Permission,casttype=PermFlag" json:"Permission,omitempty"`
-	Role       *string                                       `protobuf:"bytes,4,opt,name=Role" json:"Role,omitempty"`
-	Value      *bool                                         `protobuf:"varint,5,opt,name=Value" json:"Value,omitempty"`
+	// The permission function
+	Action PermFlag `protobuf:"varint,1,opt,name=Action,casttype=PermFlag" json:"Action"`
+	// The target of the action
+	Target *github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,2,opt,name=Target,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Target,omitempty"`
+	// Possible arguments
+	Permission *PermFlag `protobuf:"varint,3,opt,name=Permission,casttype=PermFlag" json:"Permission,omitempty"`
+	Role       *string   `protobuf:"bytes,4,opt,name=Role" json:"Role,omitempty"`
+	Value      *bool     `protobuf:"varint,5,opt,name=Value" json:"Value,omitempty"`
 }
 
 func (m *PermArgs) Reset()                    { *m = PermArgs{} }
 func (*PermArgs) ProtoMessage()               {}
 func (*PermArgs) Descriptor() ([]byte, []int) { return fileDescriptorPermission, []int{2} }
 
-func (m *PermArgs) GetPermFlag() PermFlag {
+func (m *PermArgs) GetAction() PermFlag {
 	if m != nil {
-		return m.PermFlag
+		return m.Action
 	}
 	return 0
 }
@@ -232,12 +235,12 @@ func (m *PermArgs) MarshalTo(dAtA []byte) (int, error) {
 	_ = l
 	dAtA[i] = 0x8
 	i++
-	i = encodeVarintPermission(dAtA, i, uint64(m.PermFlag))
-	if m.Address != nil {
+	i = encodeVarintPermission(dAtA, i, uint64(m.Action))
+	if m.Target != nil {
 		dAtA[i] = 0x12
 		i++
-		i = encodeVarintPermission(dAtA, i, uint64(m.Address.Size()))
-		n2, err := m.Address.MarshalTo(dAtA[i:])
+		i = encodeVarintPermission(dAtA, i, uint64(m.Target.Size()))
+		n2, err := m.Target.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
@@ -307,9 +310,9 @@ func (m *BasePermissions) Size() (n int) {
 func (m *PermArgs) Size() (n int) {
 	var l int
 	_ = l
-	n += 1 + sovPermission(uint64(m.PermFlag))
-	if m.Address != nil {
-		l = m.Address.Size()
+	n += 1 + sovPermission(uint64(m.Action))
+	if m.Target != nil {
+		l = m.Target.Size()
 		n += 1 + l + sovPermission(uint64(l))
 	}
 	if m.Permission != nil {
@@ -568,9 +571,9 @@ func (m *PermArgs) Unmarshal(dAtA []byte) error {
 		switch fieldNum {
 		case 1:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PermFlag", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field Action", wireType)
 			}
-			m.PermFlag = 0
+			m.Action = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowPermission
@@ -580,14 +583,14 @@ func (m *PermArgs) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.PermFlag |= (PermFlag(b) & 0x7F) << shift
+				m.Action |= (PermFlag(b) & 0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
 		case 2:
 			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType)
 			}
 			var byteLen int
 			for shift := uint(0); ; shift += 7 {
@@ -612,8 +615,8 @@ func (m *PermArgs) Unmarshal(dAtA []byte) error {
 				return io.ErrUnexpectedEOF
 			}
 			var v github_com_hyperledger_burrow_crypto.Address
-			m.Address = &v
-			if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+			m.Target = &v
+			if err := m.Target.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
 			iNdEx = postIndex
@@ -818,27 +821,28 @@ func init() { proto.RegisterFile("permission.proto", fileDescriptorPermission) }
 func init() { golang_proto.RegisterFile("permission.proto", fileDescriptorPermission) }
 
 var fileDescriptorPermission = []byte{
-	// 351 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x51, 0x31, 0x4b, 0xc3, 0x40,
-	0x14, 0xee, 0xb5, 0xa9, 0xb6, 0xcf, 0x82, 0xe5, 0x70, 0x08, 0x0a, 0x49, 0xe8, 0x20, 0x19, 0x6a,
-	0x22, 0x82, 0x4b, 0x07, 0xa1, 0x19, 0x1c, 0x9c, 0xe4, 0x04, 0x07, 0xb7, 0x34, 0x3d, 0xd3, 0x40,
-	0xda, 0x0b, 0x77, 0x17, 0xa4, 0xff, 0xc4, 0x51, 0xff, 0x89, 0x63, 0xc7, 0xce, 0x0e, 0x45, 0x5a,
-	0xf0, 0x47, 0x38, 0xc9, 0x5d, 0x6a, 0x1b, 0x85, 0xba, 0xbd, 0xef, 0x7d, 0xdf, 0x7b, 0xdf, 0xbd,
-	0xef, 0xa0, 0x9d, 0x51, 0x3e, 0x4e, 0x84, 0x48, 0xd8, 0xc4, 0xcb, 0x38, 0x93, 0x0c, 0xc3, 0xb6,
-	0x73, 0x7c, 0x16, 0x27, 0x72, 0x94, 0x0f, 0xbc, 0x88, 0x8d, 0xfd, 0x98, 0xc5, 0xcc, 0xd7, 0x92,
-	0x41, 0xfe, 0xa8, 0x91, 0x06, 0xba, 0x2a, 0x46, 0x3b, 0x21, 0xe0, 0x7e, 0x14, 0xb1, 0x7c, 0x22,
-	0x6f, 0x37, 0x3b, 0x04, 0xbe, 0x04, 0x23, 0x08, 0x05, 0x35, 0x91, 0x83, 0xdc, 0x83, 0x8b, 0x13,
-	0xaf, 0xe4, 0xa8, 0xfa, 0x25, 0x69, 0x60, 0xcc, 0x16, 0x76, 0x85, 0x68, 0x39, 0x3e, 0x82, 0x3a,
-	0x61, 0x29, 0x15, 0x66, 0xd5, 0xa9, 0xb9, 0x4d, 0x52, 0x80, 0x4e, 0x02, 0x87, 0x7f, 0x86, 0xf0,
-	0x29, 0xd4, 0x15, 0x14, 0xda, 0xc0, 0x08, 0xda, 0x6a, 0xc7, 0xd7, 0xc2, 0x6e, 0xa8, 0xe6, 0x75,
-	0x1a, 0xc6, 0xa4, 0xa0, 0xb1, 0x0b, 0x7b, 0x77, 0x54, 0x06, 0x89, 0x34, 0xab, 0x3b, 0x84, 0x6b,
-	0xbe, 0x67, 0x3c, 0xbf, 0xd8, 0x95, 0xce, 0x27, 0x02, 0x4d, 0xf5, 0x79, 0x2c, 0x70, 0x17, 0x36,
-	0xb2, 0x9d, 0x3e, 0x9b, 0x0a, 0xdf, 0xc0, 0x7e, 0x7f, 0x38, 0xe4, 0x54, 0x08, 0xed, 0xd5, 0x0a,
-	0xce, 0xdf, 0x17, 0x76, 0xb7, 0x14, 0xe6, 0x68, 0x9a, 0x51, 0x9e, 0xd2, 0x61, 0x4c, 0xb9, 0x3f,
-	0xc8, 0x39, 0x67, 0x4f, 0x7e, 0xc4, 0xa7, 0x99, 0x64, 0xde, 0x7a, 0x8e, 0xfc, 0x2c, 0xc0, 0x5d,
-	0x80, 0xed, 0xb5, 0x66, 0x4d, 0x7b, 0xb7, 0x7e, 0xf9, 0x96, 0x78, 0x8c, 0xc1, 0x50, 0x41, 0x99,
-	0x86, 0x83, 0xdc, 0x26, 0xd1, 0xb5, 0x4a, 0xf2, 0x3e, 0x4c, 0x73, 0x6a, 0xd6, 0x1d, 0xe4, 0x36,
-	0x48, 0x01, 0x7a, 0x0d, 0x75, 0xe4, 0xfc, 0xd5, 0xae, 0x04, 0x57, 0xb3, 0xa5, 0x85, 0xe6, 0x4b,
-	0x0b, 0x7d, 0x2c, 0x2d, 0xf4, 0xb6, 0xb2, 0xd0, 0x6c, 0x65, 0xa1, 0x07, 0xf7, 0xff, 0xe7, 0x6e,
-	0x7f, 0xf1, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x75, 0xf4, 0x5f, 0xe9, 0x44, 0x02, 0x00, 0x00,
+	// 355 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x51, 0xb1, 0x4b, 0xfb, 0x40,
+	0x14, 0xee, 0xb5, 0x69, 0x69, 0xdf, 0xaf, 0xf0, 0x2b, 0x87, 0x43, 0x50, 0x48, 0x42, 0x07, 0xc9,
+	0x50, 0x13, 0x11, 0x5c, 0x3a, 0x08, 0xc9, 0x20, 0x8e, 0x12, 0xc5, 0xc1, 0x2d, 0x4d, 0xcf, 0x6b,
+	0x20, 0xed, 0x85, 0xbb, 0x0b, 0xd2, 0xff, 0xc4, 0x51, 0xff, 0x13, 0xc7, 0x8e, 0x9d, 0x1d, 0x4a,
+	0x69, 0xff, 0x0b, 0x27, 0xb9, 0x4b, 0xb1, 0x51, 0xa8, 0xdb, 0xfb, 0xde, 0xf7, 0x7d, 0xef, 0xbb,
+	0xf7, 0x0e, 0x7a, 0x39, 0xe1, 0xd3, 0x54, 0x88, 0x94, 0xcd, 0xbc, 0x9c, 0x33, 0xc9, 0x30, 0xec,
+	0x3b, 0xc7, 0x67, 0x34, 0x95, 0x93, 0x62, 0xe4, 0x25, 0x6c, 0xea, 0x53, 0x46, 0x99, 0xaf, 0x25,
+	0xa3, 0xe2, 0x49, 0x23, 0x0d, 0x74, 0x55, 0x5a, 0xfb, 0x31, 0xe0, 0x20, 0x49, 0x58, 0x31, 0x93,
+	0xb7, 0xdf, 0x33, 0x04, 0xbe, 0x04, 0x23, 0x8c, 0x05, 0x31, 0x91, 0x83, 0xdc, 0x7f, 0x17, 0x27,
+	0x5e, 0x25, 0x51, 0xf5, 0x2b, 0xd2, 0xd0, 0x58, 0xac, 0xec, 0x5a, 0xa4, 0xe5, 0xf8, 0x08, 0x9a,
+	0x11, 0xcb, 0x88, 0x30, 0xeb, 0x4e, 0xc3, 0xed, 0x44, 0x25, 0xe8, 0xa7, 0xf0, 0xff, 0x97, 0x09,
+	0x9f, 0x42, 0x53, 0x41, 0xa1, 0x03, 0x8c, 0xb0, 0xa7, 0x66, 0x7c, 0xae, 0xec, 0xb6, 0x6a, 0x5e,
+	0x67, 0x31, 0x8d, 0x4a, 0x1a, 0xbb, 0xd0, 0xba, 0x23, 0x32, 0x4c, 0xa5, 0x59, 0x3f, 0x20, 0xdc,
+	0xf1, 0x43, 0xe3, 0xe5, 0xd5, 0xae, 0xf5, 0xd7, 0x08, 0x34, 0x15, 0x70, 0xaa, 0xcd, 0x41, 0x22,
+	0x53, 0x36, 0x3b, 0x98, 0xb2, 0xe3, 0xf1, 0x0d, 0xb4, 0xee, 0x63, 0x4e, 0x49, 0x19, 0xd3, 0x0d,
+	0xcf, 0x3f, 0x56, 0xf6, 0xa0, 0x72, 0xc7, 0xc9, 0x3c, 0x27, 0x3c, 0x23, 0x63, 0x4a, 0xb8, 0x3f,
+	0x2a, 0x38, 0x67, 0xcf, 0x7e, 0xc2, 0xe7, 0xb9, 0x64, 0x5e, 0x30, 0x1e, 0x73, 0x22, 0x44, 0xb4,
+	0xf3, 0xe3, 0x01, 0xc0, 0x7e, 0x4f, 0xb3, 0xa1, 0x73, 0xbb, 0x3f, 0x32, 0x2b, 0x3c, 0xc6, 0x60,
+	0xa8, 0x13, 0x99, 0x86, 0x83, 0xdc, 0x4e, 0xa4, 0x6b, 0x75, 0xc3, 0x87, 0x38, 0x2b, 0x88, 0xd9,
+	0x74, 0x90, 0xdb, 0x8e, 0x4a, 0x30, 0x6c, 0xab, 0xf5, 0x96, 0x6f, 0x76, 0x2d, 0xbc, 0x5a, 0x6c,
+	0x2c, 0xb4, 0xdc, 0x58, 0x68, 0xbd, 0xb1, 0xd0, 0xfb, 0xd6, 0x42, 0x8b, 0xad, 0x85, 0x1e, 0xdd,
+	0xbf, 0x5f, 0xbb, 0xff, 0xbf, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xaa, 0x70, 0x53, 0xf2, 0x3e,
+	0x02, 0x00, 0x00,
 }
diff --git a/permission/snatives.go b/permission/snatives.go
index 6f3df0a1ec184c07c3f0975a1e3c7693cdb3287a..649fcc111f0084f25c0b0c51c689ad5d18347c3a 100644
--- a/permission/snatives.go
+++ b/permission/snatives.go
@@ -26,9 +26,9 @@ import (
 
 func (pa PermArgs) String() string {
 	body := make([]string, 0, 5)
-	body = append(body, fmt.Sprintf("PermFlag: %v", String(pa.PermFlag)))
-	if pa.Address != nil {
-		body = append(body, fmt.Sprintf("Address: %s", *pa.Address))
+	body = append(body, fmt.Sprintf("PermFlag: %v", String(pa.Action)))
+	if pa.Target != nil {
+		body = append(body, fmt.Sprintf("Address: %s", *pa.Target))
 	}
 	if pa.Permission != nil {
 		body = append(body, fmt.Sprintf("Permission: %v", String(*pa.Permission)))
@@ -43,9 +43,9 @@ func (pa PermArgs) String() string {
 }
 
 func (pa PermArgs) EnsureValid() error {
-	pf := pa.PermFlag
+	pf := pa.Action
 	// Address
-	if pa.Address == nil && pf != SetGlobal {
+	if pa.Target == nil && pf != SetGlobal {
 		return fmt.Errorf("PermArgs for PermFlag %v requires Address to be provided but was nil", pf)
 	}
 	if pf == HasRole || pf == AddRole || pf == RemoveRole {
@@ -65,16 +65,16 @@ func (pa PermArgs) EnsureValid() error {
 
 func HasBaseArgs(address crypto.Address, permFlag PermFlag) PermArgs {
 	return PermArgs{
-		PermFlag:   HasBase,
-		Address:    &address,
+		Action:     HasBase,
+		Target:     &address,
 		Permission: &permFlag,
 	}
 }
 
 func SetBaseArgs(address crypto.Address, permFlag PermFlag, value bool) PermArgs {
 	return PermArgs{
-		PermFlag:   SetBase,
-		Address:    &address,
+		Action:     SetBase,
+		Target:     &address,
 		Permission: &permFlag,
 		Value:      &value,
 	}
@@ -82,15 +82,15 @@ func SetBaseArgs(address crypto.Address, permFlag PermFlag, value bool) PermArgs
 
 func UnsetBaseArgs(address crypto.Address, permFlag PermFlag) PermArgs {
 	return PermArgs{
-		PermFlag:   UnsetBase,
-		Address:    &address,
+		Action:     UnsetBase,
+		Target:     &address,
 		Permission: &permFlag,
 	}
 }
 
 func SetGlobalArgs(permFlag PermFlag, value bool) PermArgs {
 	return PermArgs{
-		PermFlag:   SetGlobal,
+		Action:     SetGlobal,
 		Permission: &permFlag,
 		Value:      &value,
 	}
@@ -98,24 +98,24 @@ func SetGlobalArgs(permFlag PermFlag, value bool) PermArgs {
 
 func HasRoleArgs(address crypto.Address, role string) PermArgs {
 	return PermArgs{
-		PermFlag: HasRole,
-		Address:  &address,
-		Role:     &role,
+		Action: HasRole,
+		Target: &address,
+		Role:   &role,
 	}
 }
 
 func AddRoleArgs(address crypto.Address, role string) PermArgs {
 	return PermArgs{
-		PermFlag: AddRole,
-		Address:  &address,
-		Role:     &role,
+		Action: AddRole,
+		Target: &address,
+		Role:   &role,
 	}
 }
 
 func RemoveRoleArgs(address crypto.Address, role string) PermArgs {
 	return PermArgs{
-		PermFlag: RemoveRole,
-		Address:  &address,
-		Role:     &role,
+		Action: RemoveRole,
+		Target: &address,
+		Role:   &role,
 	}
 }
diff --git a/protobuf/permission.proto b/protobuf/permission.proto
index d7ba52af5dd3ace0ffcb79596c26a819a263ceb6..b1709bffea4c90d68336dfdc585942842cb3de64 100644
--- a/protobuf/permission.proto
+++ b/protobuf/permission.proto
@@ -31,8 +31,11 @@ message BasePermissions {
 message PermArgs {
     option (gogoproto.goproto_unrecognized) = false;
     option (gogoproto.goproto_stringer) = false;
-    optional uint64 PermFlag = 1 [(gogoproto.casttype) = "PermFlag", (gogoproto.nullable) = false];
-    optional bytes Address = 2 [(gogoproto.customtype) = "github.com/hyperledger/burrow/crypto.Address"];
+    // The permission function
+    optional uint64 Action = 1 [(gogoproto.casttype) = "PermFlag", (gogoproto.nullable) = false];
+    // The target of the action
+    optional bytes Target = 2 [(gogoproto.customtype) = "github.com/hyperledger/burrow/crypto.Address"];
+    // Possible arguments
     optional uint64 Permission = 3 [(gogoproto.casttype) = "PermFlag"];
     optional string Role = 4;
     optional bool Value = 5;