Skip to content

Commit

Permalink
feat(aws): add ability to provide a role session name when generating…
Browse files Browse the repository at this point in the history
… STS credentials (hashicorp#11345)

* feat(aws): add ability to provide a sessionName to sts credentials

Co-authored-by: Brad Vernon <bvernon@nvidia.com>
Co-authored-by: Jim Kalafut <jim@kalafut.net>
Co-authored-by: Tom Proctor <tomhjp@users.noreply.github.com>
  • Loading branch information
4 people authored and jartek committed Sep 11, 2021
1 parent b098650 commit f730274
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 8 deletions.
7 changes: 6 additions & 1 deletion builtin/logical/aws/path_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ func pathUser(b *backend) *framework.Path {
Description: "Lifetime of the returned credentials in seconds",
Default: 3600,
},
"role_session_name": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Session name to use when assuming role. Max chars: 64",
},
},

Callbacks: map[logical.Operation]framework.OperationFunc{
Expand Down Expand Up @@ -80,6 +84,7 @@ func (b *backend) pathCredsRead(ctx context.Context, req *logical.Request, d *fr
}

roleArn := d.Get("role_arn").(string)
roleSessionName := d.Get("role_session_name").(string)

var credentialType string
switch {
Expand Down Expand Up @@ -125,7 +130,7 @@ func (b *backend) pathCredsRead(ctx context.Context, req *logical.Request, d *fr
case !strutil.StrListContains(role.RoleArns, roleArn):
return logical.ErrorResponse(fmt.Sprintf("role_arn %q not in allowed role arns for Vault role %q", roleArn, roleName)), nil
}
return b.assumeRole(ctx, req.Storage, req.DisplayName, roleName, roleArn, role.PolicyDocument, role.PolicyArns, role.IAMGroups, ttl)
return b.assumeRole(ctx, req.Storage, req.DisplayName, roleName, roleArn, role.PolicyDocument, role.PolicyArns, role.IAMGroups, ttl, roleSessionName)
case federationTokenCred:
return b.getFederationToken(ctx, req.Storage, req.DisplayName, roleName, role.PolicyDocument, role.PolicyArns, role.IAMGroups, ttl)
default:
Expand Down
22 changes: 16 additions & 6 deletions builtin/logical/aws/secret_access_keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func (b *backend) getFederationToken(ctx context.Context, s logical.Storage,

func (b *backend) assumeRole(ctx context.Context, s logical.Storage,
displayName, roleName, roleArn, policy string, policyARNs []string,
iamGroups []string, lifeTimeInSeconds int64) (*logical.Response, error) {
iamGroups []string, lifeTimeInSeconds int64, roleSessionName string) (*logical.Response, error) {

// grab any IAM group policies associated with the vault role, both inline
// and managed
Expand All @@ -165,10 +165,19 @@ func (b *backend) assumeRole(ctx context.Context, s logical.Storage,
return logical.ErrorResponse(err.Error()), nil
}

username, usernameWarning := genUsername(displayName, roleName, "iam_user")
roleSessionNameWarning := ""
if roleSessionName == "" {
roleSessionName, roleSessionNameWarning = genUsername(displayName, roleName, "iam_user")
} else {
roleSessionName = normalizeDisplayName(roleSessionName)
if len(roleSessionName) > 64 {
roleSessionName = roleSessionName[0:64]
roleSessionNameWarning = "the role session name was truncated to 64 characters to fit within IAM session name length limits"
}
}

assumeRoleInput := &sts.AssumeRoleInput{
RoleSessionName: aws.String(username),
RoleSessionName: aws.String(roleSessionName),
RoleArn: aws.String(roleArn),
DurationSeconds: &lifeTimeInSeconds,
}
Expand All @@ -187,8 +196,9 @@ func (b *backend) assumeRole(ctx context.Context, s logical.Storage,
"access_key": *tokenResp.Credentials.AccessKeyId,
"secret_key": *tokenResp.Credentials.SecretAccessKey,
"security_token": *tokenResp.Credentials.SessionToken,
"arn": *tokenResp.AssumedRoleUser.Arn,
}, map[string]interface{}{
"username": username,
"username": roleSessionName,
"policy": roleArn,
"is_sts": true,
})
Expand All @@ -199,8 +209,8 @@ func (b *backend) assumeRole(ctx context.Context, s logical.Storage,
// STS are purposefully short-lived and aren't renewable
resp.Secret.Renewable = false

if usernameWarning != "" {
resp.AddWarning(usernameWarning)
if roleSessionNameWarning != "" {
resp.AddWarning(roleSessionNameWarning)
}

return resp, nil
Expand Down
3 changes: 3 additions & 0 deletions changelog/11345.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
secrets/aws: add ability to provide a role session name when generating STS credentials
```
7 changes: 6 additions & 1 deletion website/content/api-docs/secret/aws.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,10 @@ credentials retrieved through `/aws/creds` must be of the `iam_user` type.
the Vault role is `assumed_role`. Must match one of the allowed role ARNs in
the Vault role. Optional if the Vault role only allows a single AWS role ARN;
required otherwise.
- `role_session_name` `(string)` - The role session name to attach to the assumed role ARN.
`role_session_name` is limited to 64 characters; if exceeded, the `role_session_name` in the
assumed role ARN will be truncated to 64 characters. If `role_session_name` is not provided,
then it will be generated dynamically by default.
- `ttl` `(string: "3600s")` – Specifies the TTL for the use of the STS token.
This is specified as a string with a duration suffix. Valid only when
`credential_type` is `assumed_role` or `federation_token`. When not specified,
Expand Down Expand Up @@ -550,7 +554,8 @@ $ curl \
"data": {
"access_key": "AKIA...",
"secret_key": "xlCs...",
"security_token": null
"security_token": null,
"arn": "arn:aws:sts::123456789012:assumed-role/DeveloperRole/some-user-supplied-role-session-name"
}
}
```

0 comments on commit f730274

Please sign in to comment.