From e77652d15d9676c20a2cbe79b97375328ea3620d Mon Sep 17 00:00:00 2001 From: root Date: Tue, 14 Jun 2016 14:49:36 +0000 Subject: [PATCH] adding IAM Role as constrain --- builtin/credential/aws-ec2/path_login.go | 12 ++++++++++-- builtin/credential/aws-ec2/path_role.go | 18 ++++++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/builtin/credential/aws-ec2/path_login.go b/builtin/credential/aws-ec2/path_login.go index ef14bf7062..f4d7f06144 100644 --- a/builtin/credential/aws-ec2/path_login.go +++ b/builtin/credential/aws-ec2/path_login.go @@ -244,13 +244,21 @@ func (b *backend) pathLoginUpdate( return logical.ErrorResponse("role entry not found"), nil } - // Only 'bound_ami_id' constraint is supported on the role currently. + // Only 'bound_ami_id' and 'bound_iam_role_arn' constraints are supported on the role currently. // Check if the AMI ID of the instance trying to login matches the // AMI ID specified as a constraint on the role. - if identityDoc.AmiID != roleEntry.BoundAmiID { + if roleEntry.BoundAmiID != "" && identityDoc.AmiID != roleEntry.BoundAmiID { return logical.ErrorResponse(fmt.Sprintf("AMI ID %s does not belong to role %s", identityDoc.AmiID, roleName)), nil } + // Check if the IAM Role ARN of the instance trying to login matches the + // IAM Role ARN specified as a constraint on the role. + iamRoleArn := "" + iamRoleArn = *instanceDesc.Reservations[0].Instances[0].IamInstanceProfile.Arn + if roleEntry.BoundIamARN != "" && iamRoleArn != roleEntry.BoundIamARN { + return logical.ErrorResponse(fmt.Sprintf("IAM Role ARN %s does not belong to role %s", iamRoleArn, roleName)), nil + } + // Get the entry from the identity whitelist, if there is one. storedIdentity, err := whitelistIdentityEntry(req.Storage, identityDoc.InstanceID) if err != nil { diff --git a/builtin/credential/aws-ec2/path_role.go b/builtin/credential/aws-ec2/path_role.go index d958e5f1bd..c21a55d629 100644 --- a/builtin/credential/aws-ec2/path_role.go +++ b/builtin/credential/aws-ec2/path_role.go @@ -27,6 +27,11 @@ func pathRole(b *backend) *framework.Path { using the AMI ID specified by this parameter.`, }, + "bound_iam_role_arn": &framework.FieldSchema{ + Type: framework.TypeString, + Description: `If set, defines a constraint on the EC2 instances that they should be using the IAM Role ARN specified by this parameter.`, + }, + "role_tag": &framework.FieldSchema{ Type: framework.TypeString, Default: "", @@ -211,10 +216,18 @@ func (b *backend) pathRoleCreateUpdate( roleEntry.BoundAmiID = boundAmiIDStr.(string) } + boundIamARNStr, ok := data.GetOk("bound_iam_role_arn") + if ok { + roleEntry.BoundIamARN = boundIamARNStr.(string) + } + // At least one bound parameter should be set. Currently, only - // 'bound_ami_id' is supported. Check if that is set. + // 'bound_ami_id' and 'bound_iam_role_arn' are supported. Check if one of them is set. if roleEntry.BoundAmiID == "" { - return logical.ErrorResponse("role is not bounded to any resource; set bound_ami_id"), nil + // check if an IAM Role ARN was provided instead of an AMI ID + if roleEntry.BoundIamARN == "" { + return logical.ErrorResponse("role is not bounded to any resource; set bound_ami_id or bount_iam_role_arn"), nil + } } policiesStr, ok := data.GetOk("policies") @@ -295,6 +308,7 @@ func (b *backend) pathRoleCreateUpdate( // Struct to hold the information associated with an AMI ID in Vault. type awsRoleEntry struct { BoundAmiID string `json:"bound_ami_id" structs:"bound_ami_id" mapstructure:"bound_ami_id"` + BoundIamARN string `json:"bound_iam_role_arn" structs:"bound_iam_role_arn" mapstructure:"bound_iam_role_arn"` RoleTag string `json:"role_tag" structs:"role_tag" mapstructure:"role_tag"` AllowInstanceMigration bool `json:"allow_instance_migration" structs:"allow_instance_migration" mapstructure:"allow_instance_migration"` MaxTTL time.Duration `json:"max_ttl" structs:"max_ttl" mapstructure:"max_ttl"`