Pass identity metadata through to plugins (#4967)

It's not obvious why this should be secret, and if it were considered
secret, when and what anything would ever be allowed to access it.
Likely the right way to tie secret values to particular
entities/aliases/groups would be to use the upcoming templated ACL
feature.
This commit is contained in:
Jeff Mitchell
2018-07-23 12:45:06 -04:00
committed by GitHub
parent 20ea32fa9a
commit 24b032aad5
4 changed files with 105 additions and 44 deletions

View File

@@ -24,17 +24,19 @@ type Entity struct {
// Name is the human-friendly unique identifier for the entity
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
// Aliases contains thhe alias mappings for the given entity
Aliases []*Alias `protobuf:"bytes,3,rep,name=aliases,proto3" json:"aliases,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
Aliases []*Alias `protobuf:"bytes,3,rep,name=aliases,proto3" json:"aliases,omitempty"`
// Metadata represents the custom data tied to this entity
Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Entity) Reset() { *m = Entity{} }
func (m *Entity) String() string { return proto.CompactTextString(m) }
func (*Entity) ProtoMessage() {}
func (*Entity) Descriptor() ([]byte, []int) {
return fileDescriptor_identity_6481f5f23202c059, []int{0}
return fileDescriptor_identity_8ee6f9f1922f77d7, []int{0}
}
func (m *Entity) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Entity.Unmarshal(m, b)
@@ -75,6 +77,13 @@ func (m *Entity) GetAliases() []*Alias {
return nil
}
func (m *Entity) GetMetadata() map[string]string {
if m != nil {
return m.Metadata
}
return nil
}
type Alias struct {
// MountType is the backend mount's type to which this identity belongs
MountType string `protobuf:"bytes,1,opt,name=mount_type,json=mountType,proto3" json:"mount_type,omitempty"`
@@ -82,17 +91,19 @@ type Alias struct {
// identity belongs
MountAccessor string `protobuf:"bytes,2,opt,name=mount_accessor,json=mountAccessor,proto3" json:"mount_accessor,omitempty"`
// Name is the identifier of this identity in its authentication source
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
// Metadata represents the custom data tied to this alias
Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Alias) Reset() { *m = Alias{} }
func (m *Alias) String() string { return proto.CompactTextString(m) }
func (*Alias) ProtoMessage() {}
func (*Alias) Descriptor() ([]byte, []int) {
return fileDescriptor_identity_6481f5f23202c059, []int{1}
return fileDescriptor_identity_8ee6f9f1922f77d7, []int{1}
}
func (m *Alias) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Alias.Unmarshal(m, b)
@@ -133,27 +144,40 @@ func (m *Alias) GetName() string {
return ""
}
func (m *Alias) GetMetadata() map[string]string {
if m != nil {
return m.Metadata
}
return nil
}
func init() {
proto.RegisterType((*Entity)(nil), "logical.Entity")
proto.RegisterMapType((map[string]string)(nil), "logical.Entity.MetadataEntry")
proto.RegisterType((*Alias)(nil), "logical.Alias")
proto.RegisterMapType((map[string]string)(nil), "logical.Alias.MetadataEntry")
}
func init() { proto.RegisterFile("logical/identity.proto", fileDescriptor_identity_6481f5f23202c059) }
func init() { proto.RegisterFile("logical/identity.proto", fileDescriptor_identity_8ee6f9f1922f77d7) }
var fileDescriptor_identity_6481f5f23202c059 = []byte{
// 209 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x44, 0xcf, 0x31, 0x6b, 0x85, 0x30,
0x14, 0x05, 0x60, 0xd4, 0x56, 0xf1, 0x96, 0x3a, 0x64, 0x28, 0x2e, 0x05, 0x91, 0x16, 0x9c, 0x12,
0x68, 0x7f, 0x81, 0xc5, 0x0e, 0xae, 0x52, 0x3a, 0x74, 0x29, 0xd7, 0x34, 0x68, 0x20, 0x9a, 0x60,
0x62, 0xc1, 0x7f, 0x5f, 0x9a, 0x97, 0xf7, 0xde, 0x16, 0xbe, 0x03, 0x27, 0xe7, 0xc2, 0x83, 0xd2,
0x93, 0xe4, 0xa8, 0x98, 0xfc, 0x11, 0xab, 0x93, 0xee, 0xa0, 0x66, 0xd3, 0x4e, 0x93, 0x2c, 0x78,
0xfd, 0x09, 0xe9, 0xbb, 0x0f, 0x48, 0x01, 0x71, 0xdf, 0x95, 0x51, 0x15, 0x35, 0xf9, 0x10, 0xf7,
0x1d, 0x21, 0x70, 0xb3, 0xe2, 0x22, 0xca, 0xd8, 0x8b, 0x7f, 0x93, 0x06, 0x32, 0x54, 0x12, 0xad,
0xb0, 0x65, 0x52, 0x25, 0xcd, 0xdd, 0x4b, 0x41, 0x43, 0x11, 0x6d, 0xff, 0x7d, 0x38, 0xc7, 0x35,
0xc2, 0xad, 0x17, 0xf2, 0x08, 0xb0, 0xe8, 0x7d, 0x75, 0xdf, 0xee, 0x30, 0x22, 0xd4, 0xe7, 0x5e,
0x3e, 0x0e, 0x23, 0xc8, 0x33, 0x14, 0xa7, 0x18, 0x39, 0x17, 0xd6, 0xea, 0x2d, 0xfc, 0x77, 0xef,
0xb5, 0x0d, 0x78, 0x19, 0x93, 0x5c, 0xc7, 0xbc, 0x3d, 0x7d, 0xd5, 0x93, 0x74, 0xf3, 0x3e, 0x52,
0xae, 0x17, 0x36, 0xa3, 0x9d, 0x25, 0xd7, 0x9b, 0x61, 0xbf, 0xb8, 0x2b, 0xc7, 0xc2, 0xae, 0x31,
0xf5, 0x07, 0xbf, 0xfe, 0x05, 0x00, 0x00, 0xff, 0xff, 0x53, 0x90, 0x60, 0xf6, 0x0a, 0x01, 0x00,
0x00,
var fileDescriptor_identity_8ee6f9f1922f77d7 = []byte{
// 287 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x91, 0x4f, 0x4b, 0xc3, 0x40,
0x10, 0xc5, 0x49, 0xd2, 0x3f, 0x76, 0xa4, 0x45, 0x06, 0x91, 0x20, 0x16, 0x4a, 0x50, 0xc8, 0x29,
0x01, 0xbd, 0x54, 0x3d, 0x55, 0xda, 0x43, 0x0f, 0x5e, 0x82, 0x27, 0x2f, 0x32, 0x4d, 0x97, 0x66,
0x31, 0xc9, 0x86, 0x64, 0x52, 0xc8, 0x97, 0xf4, 0xec, 0xc7, 0x91, 0x6e, 0xb6, 0xc1, 0xe2, 0xd9,
0xdb, 0xec, 0xef, 0xcd, 0xce, 0xbe, 0x79, 0x0b, 0x57, 0xa9, 0xda, 0xc9, 0x98, 0xd2, 0x50, 0x6e,
0x45, 0xce, 0x92, 0x9b, 0xa0, 0x28, 0x15, 0x2b, 0x1c, 0x1a, 0xee, 0x7d, 0x59, 0x30, 0x58, 0x69,
0x05, 0x27, 0x60, 0xaf, 0x97, 0xae, 0x35, 0xb3, 0xfc, 0x51, 0x64, 0xaf, 0x97, 0x88, 0xd0, 0xcb,
0x29, 0x13, 0xae, 0xad, 0x89, 0xae, 0xd1, 0x87, 0x21, 0xa5, 0x92, 0x2a, 0x51, 0xb9, 0xce, 0xcc,
0xf1, 0xcf, 0xef, 0x27, 0x81, 0x99, 0x14, 0x2c, 0x0e, 0x3c, 0x3a, 0xca, 0xf8, 0x08, 0x67, 0x99,
0x60, 0xda, 0x12, 0x93, 0xdb, 0xd3, 0xad, 0xd3, 0xae, 0xb5, 0x7d, 0x30, 0x78, 0x35, 0xfa, 0x2a,
0xe7, 0xb2, 0x89, 0xba, 0xf6, 0xeb, 0x67, 0x18, 0x9f, 0x48, 0x78, 0x01, 0xce, 0xa7, 0x68, 0x8c,
0xb5, 0x43, 0x89, 0x97, 0xd0, 0xdf, 0x53, 0x5a, 0x1f, 0xcd, 0xb5, 0x87, 0x27, 0x7b, 0x6e, 0x79,
0xdf, 0x16, 0xf4, 0xb5, 0x15, 0x9c, 0x02, 0x64, 0xaa, 0xce, 0xf9, 0x83, 0x9b, 0x42, 0x98, 0xcb,
0x23, 0x4d, 0xde, 0x9a, 0x42, 0xe0, 0x1d, 0x4c, 0x5a, 0x99, 0xe2, 0x58, 0x54, 0x95, 0x2a, 0xcd,
0xac, 0xb1, 0xa6, 0x0b, 0x03, 0xbb, 0x14, 0x9c, 0x5f, 0x29, 0xcc, 0xff, 0xec, 0x76, 0x73, 0x1a,
0xc3, 0xbf, 0xac, 0xf6, 0x72, 0xfb, 0xee, 0xed, 0x24, 0x27, 0xf5, 0x26, 0x88, 0x55, 0x16, 0x26,
0x54, 0x25, 0x32, 0x56, 0x65, 0x11, 0xee, 0xa9, 0x4e, 0x39, 0x34, 0x06, 0x36, 0x03, 0xfd, 0xc3,
0x0f, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xbf, 0xfb, 0x6f, 0x8c, 0xfb, 0x01, 0x00, 0x00,
}

View File

@@ -13,6 +13,9 @@ message Entity {
// Aliases contains thhe alias mappings for the given entity
repeated Alias aliases = 3;
// Metadata represents the custom data tied to this entity
map<string, string> metadata = 4;
}
message Alias {
@@ -25,5 +28,7 @@ message Alias {
// Name is the identifier of this identity in its authentication source
string name = 3;
}
// Metadata represents the custom data tied to this alias
map<string, string> metadata = 4;
}

View File

@@ -8,6 +8,7 @@ import (
"reflect"
"github.com/gogo/protobuf/proto"
plugin "github.com/hashicorp/go-plugin"
"github.com/hashicorp/vault/helper/consts"
"github.com/hashicorp/vault/logical"
@@ -170,6 +171,19 @@ func TestSystem_GRPC_entityInfo(t *testing.T) {
sys.EntityVal = &logical.Entity{
ID: "id",
Name: "name",
Metadata: map[string]string{
"foo": "bar",
},
Aliases: []*logical.Alias{
&logical.Alias{
MountType: "logical",
MountAccessor: "accessor",
Name: "name",
Metadata: map[string]string{
"zip": "zap",
},
},
},
}
client, _ := plugin.TestGRPCConn(t, func(s *grpc.Server) {
pb.RegisterSystemViewServer(s, &gRPCSystemViewServer{
@@ -183,7 +197,7 @@ func TestSystem_GRPC_entityInfo(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if sys.EntityVal.ID != actual.ID || sys.EntityVal.Name != actual.Name {
if !proto.Equal(sys.EntityVal, actual) {
t.Fatalf("expected: %v, got: %v", sys.EntityVal, actual)
}
}

View File

@@ -169,22 +169,40 @@ func (d dynamicSystemView) EntityInfo(entityID string) (*logical.Entity, error)
return nil, nil
}
aliases := make([]*logical.Alias, len(entity.Aliases))
for i, alias := range entity.Aliases {
aliases[i] = &logical.Alias{
MountAccessor: alias.MountAccessor,
Name: alias.Name,
}
// MountType is not stored with the entity and must be looked up
if mount := d.core.router.validateMountByAccessor(alias.MountAccessor); mount != nil {
aliases[i].MountType = mount.MountType
// Return a subset of the data
ret := &logical.Entity{
ID: entity.ID,
Name: entity.Name,
}
if entity.Metadata != nil {
ret.Metadata = make(map[string]string, len(entity.Metadata))
for k, v := range entity.Metadata {
ret.Metadata[k] = v
}
}
// Only returning a subset of the data
return &logical.Entity{
ID: entity.ID,
Name: entity.Name,
Aliases: aliases,
}, nil
aliases := make([]*logical.Alias, len(entity.Aliases))
for i, a := range entity.Aliases {
alias := &logical.Alias{
MountAccessor: a.MountAccessor,
Name: a.Name,
}
// MountType is not stored with the entity and must be looked up
if mount := d.core.router.validateMountByAccessor(a.MountAccessor); mount != nil {
alias.MountType = mount.MountType
}
if a.Metadata != nil {
alias.Metadata = make(map[string]string, len(a.Metadata))
for k, v := range a.Metadata {
alias.Metadata[k] = v
}
}
aliases[i] = alias
}
ret.Aliases = aliases
return ret, nil
}