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 (#11345)

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

Co-authored-by: Brad Vernon <[email protected]>
Co-authored-by: Jim Kalafut <[email protected]>
Co-authored-by: Tom Proctor <[email protected]>
  • Loading branch information
4 people authored and tvoran committed May 17, 2021
1 parent 8e96383 commit 1726f57
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 @@ -33,6 +33,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 @@ -81,6 +85,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 @@ -126,7 +131,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 @@ -142,7 +142,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 @@ -166,10 +166,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 @@ -189,8 +198,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 @@ -201,8 +211,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 @@ -524,6 +524,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 @@ -551,7 +555,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 1726f57

Please sign in to comment.