Skip to content

Commit

Permalink
Add helper for aliasmetadata and add to AWS auth (#8783) (#8866)
Browse files Browse the repository at this point in the history
* add aliasmetadata sdk helper and add to aws auth

* split into ec2_metadata and iam_metadata fields

* fix tests

* strip pointer

* add test of default metadata

* more test <3

* switch from interface to custom marshallers

* add tests for marshalling

* store nil when selected fields are default

* separate loop into pieces

* separate acc test into multiple

* Update builtin/credential/aws/path_login.go

Co-Authored-By: Jim Kalafut <jkalafut@hashicorp.com>

* changes from feedback

* update aws test

* refactor to also populate auth metadata

* update how jsonification is tested

* only add populated metadata values

* add auth_type to ec2 logins

Co-authored-by: Jim Kalafut <jkalafut@hashicorp.com>

Co-authored-by: Jim Kalafut <jkalafut@hashicorp.com>
  • Loading branch information
tyrannosaurus-becks and Jim Kalafut committed Apr 27, 2020
1 parent a934957 commit f03b22d
Show file tree
Hide file tree
Showing 11 changed files with 1,336 additions and 95 deletions.
71 changes: 64 additions & 7 deletions builtin/credential/aws/path_config_identity.go
Expand Up @@ -5,10 +5,52 @@ import (
"fmt"

"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/authmetadata"
"github.com/hashicorp/vault/sdk/helper/strutil"
"github.com/hashicorp/vault/sdk/logical"
)

var (
// iamAuthMetadataFields is a list of the default auth metadata
// added to tokens during login. The default alias type used
// by this back-end is the role ID. Subsequently, the default
// fields included are expected to have a low rate of change
// when the role ID is in use.
iamAuthMetadataFields = &authmetadata.Fields{
FieldName: "iam_metadata",
Default: []string{
"account_id",
"auth_type",
},
AvailableToAdd: []string{
"canonical_arn",
"client_arn",
"client_user_id",
"inferred_aws_region",
"inferred_entity_id",
"inferred_entity_type",
},
}

// ec2AuthMetadataFields is a list of the default auth metadata
// added to tokens during login. The default alias type used
// by this back-end is the role ID. Subsequently, the default
// fields included are expected to have a low rate of change
// when the role ID is in use.
ec2AuthMetadataFields = &authmetadata.Fields{
FieldName: "ec2_metadata",
Default: []string{
"account_id",
"auth_type",
},
AvailableToAdd: []string{
"ami_id",
"instance_id",
"region",
},
}
)

func (b *backend) pathConfigIdentity() *framework.Path {
return &framework.Path{
Pattern: "config/identity$",
Expand All @@ -18,11 +60,13 @@ func (b *backend) pathConfigIdentity() *framework.Path {
Default: identityAliasIAMUniqueID,
Description: fmt.Sprintf("Configure how the AWS auth method generates entity aliases when using IAM auth. Valid values are %q, %q, and %q. Defaults to %q.", identityAliasRoleID, identityAliasIAMUniqueID, identityAliasIAMFullArn, identityAliasRoleID),
},
iamAuthMetadataFields.FieldName: authmetadata.FieldSchema(iamAuthMetadataFields),
"ec2_alias": {
Type: framework.TypeString,
Default: identityAliasEC2InstanceID,
Description: fmt.Sprintf("Configure how the AWS auth method generates entity alias when using EC2 auth. Valid values are %q, %q, and %q. Defaults to %q.", identityAliasRoleID, identityAliasEC2InstanceID, identityAliasEC2ImageID, identityAliasRoleID),
},
ec2AuthMetadataFields.FieldName: authmetadata.FieldSchema(ec2AuthMetadataFields),
},

Operations: map[logical.Operation]framework.OperationHandler{
Expand All @@ -45,9 +89,12 @@ func identityConfigEntry(ctx context.Context, s logical.Storage) (*identityConfi
return nil, err
}

var entry identityConfig
entry := &identityConfig{
IAMAuthMetadataHandler: authmetadata.NewHandler(iamAuthMetadataFields),
EC2AuthMetadataHandler: authmetadata.NewHandler(ec2AuthMetadataFields),
}
if entryRaw != nil {
if err := entryRaw.DecodeJSON(&entry); err != nil {
if err := entryRaw.DecodeJSON(entry); err != nil {
return nil, err
}
}
Expand All @@ -60,7 +107,7 @@ func identityConfigEntry(ctx context.Context, s logical.Storage) (*identityConfi
entry.EC2Alias = identityAliasRoleID
}

return &entry, nil
return entry, nil
}

func pathConfigIdentityRead(ctx context.Context, req *logical.Request, _ *framework.FieldData) (*logical.Response, error) {
Expand All @@ -71,8 +118,10 @@ func pathConfigIdentityRead(ctx context.Context, req *logical.Request, _ *framew

return &logical.Response{
Data: map[string]interface{}{
"iam_alias": config.IAMAlias,
"ec2_alias": config.EC2Alias,
"iam_alias": config.IAMAlias,
iamAuthMetadataFields.FieldName: config.IAMAuthMetadataHandler.AuthMetadata(),
"ec2_alias": config.EC2Alias,
ec2AuthMetadataFields.FieldName: config.EC2AuthMetadataHandler.AuthMetadata(),
},
}, nil
}
Expand Down Expand Up @@ -102,6 +151,12 @@ func pathConfigIdentityUpdate(ctx context.Context, req *logical.Request, data *f
}
config.EC2Alias = ec2Alias
}
if err := config.IAMAuthMetadataHandler.ParseAuthMetadata(data); err != nil {
return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
}
if err := config.EC2AuthMetadataHandler.ParseAuthMetadata(data); err != nil {
return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
}

entry, err := logical.StorageEntryJSON("config/identity", config)
if err != nil {
Expand All @@ -117,8 +172,10 @@ func pathConfigIdentityUpdate(ctx context.Context, req *logical.Request, data *f
}

type identityConfig struct {
IAMAlias string `json:"iam_alias"`
EC2Alias string `json:"ec2_alias"`
IAMAlias string `json:"iam_alias"`
IAMAuthMetadataHandler *authmetadata.Handler `json:"iam_auth_metadata_handler"`
EC2Alias string `json:"ec2_alias"`
EC2AuthMetadataHandler *authmetadata.Handler `json:"ec2_auth_metadata_handler"`
}

const identityAliasIAMUniqueID = "unique_id"
Expand Down
51 changes: 22 additions & 29 deletions builtin/credential/aws/path_login.go
Expand Up @@ -830,24 +830,23 @@ func (b *backend) pathLoginUpdateEc2(ctx context.Context, req *logical.Request,

auth := &logical.Auth{
Metadata: map[string]string{
"instance_id": identityDocParsed.InstanceID,
"region": identityDocParsed.Region,
"account_id": identityDocParsed.AccountID,
"role_tag_max_ttl": rTagMaxTTL.String(),
"role": roleName,
"ami_id": identityDocParsed.AmiID,
},
Alias: &logical.Alias{
Name: identityAlias,
Metadata: map[string]string{
"instance_id": identityDocParsed.InstanceID,
"region": identityDocParsed.Region,
"account_id": identityDocParsed.AccountID,
"ami_id": identityDocParsed.AmiID,
},
},
}
roleEntry.PopulateTokenAuth(auth)
if err := identityConfigEntry.EC2AuthMetadataHandler.PopulateDesiredMetadata(auth, map[string]string{
"instance_id": identityDocParsed.InstanceID,
"region": identityDocParsed.Region,
"account_id": identityDocParsed.AccountID,
"ami_id": identityDocParsed.AmiID,
"auth_type": ec2AuthType,
}); err != nil {
b.Logger().Warn("unable to set alias metadata", "err", err)
}

resp := &logical.Response{
Auth: auth,
Expand Down Expand Up @@ -1348,15 +1347,7 @@ func (b *backend) pathLoginUpdateIam(ctx context.Context, req *logical.Request,

auth := &logical.Auth{
Metadata: map[string]string{
"client_arn": callerID.Arn,
"canonical_arn": entity.canonicalArn(),
"client_user_id": callerUniqueId,
"auth_type": iamAuthType,
"inferred_entity_type": inferredEntityType,
"inferred_entity_id": inferredEntityID,
"inferred_aws_region": roleEntry.InferredAWSRegion,
"account_id": entity.AccountNumber,
"role_id": roleEntry.RoleID,
"role_id": roleEntry.RoleID,
},
InternalData: map[string]interface{}{
"role_name": roleName,
Expand All @@ -1365,19 +1356,21 @@ func (b *backend) pathLoginUpdateIam(ctx context.Context, req *logical.Request,
DisplayName: entity.FriendlyName,
Alias: &logical.Alias{
Name: identityAlias,
Metadata: map[string]string{
"client_arn": callerID.Arn,
"canonical_arn": entity.canonicalArn(),
"client_user_id": callerUniqueId,
"auth_type": iamAuthType,
"inferred_entity_type": inferredEntityType,
"inferred_entity_id": inferredEntityID,
"inferred_aws_region": roleEntry.InferredAWSRegion,
"account_id": entity.AccountNumber,
},
},
}
roleEntry.PopulateTokenAuth(auth)
if err := identityConfigEntry.IAMAuthMetadataHandler.PopulateDesiredMetadata(auth, map[string]string{
"client_arn": callerID.Arn,
"canonical_arn": entity.canonicalArn(),
"client_user_id": callerUniqueId,
"auth_type": iamAuthType,
"inferred_entity_type": inferredEntityType,
"inferred_entity_id": inferredEntityID,
"inferred_aws_region": roleEntry.InferredAWSRegion,
"account_id": entity.AccountNumber,
}); err != nil {
b.Logger().Warn(fmt.Sprintf("unable to set alias metadata due to %s", err))
}

return &logical.Response{
Auth: auth,
Expand Down

0 comments on commit f03b22d

Please sign in to comment.