-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add AWS Secret Engine Root Credential Rotation #5140
Merged
vishalnayak
merged 12 commits into
hashicorp:master
from
joelthompson:aws_secret_root_rotation
Sep 26, 2018
Merged
Changes from 11 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
649c4e4
Add AWS Secret Engine Root Credential Rotation
joelthompson 21fd1cf
Add test for AWS root credential rotation
joelthompson 075c905
Add docs for AWS root rotation
joelthompson 7f79d83
Add locks around reading and writing config/root
joelthompson 63efb7e
Respond to PR feedback
joelthompson 91fa6fb
Merge remote-tracking branch 'origin/master' into aws_secret_root_rot…
joelthompson b86f6cc
Fix casing in error messages
joelthompson dd32f20
Merge remote-tracking branch 'origin/master' into aws_secret_root_rot…
joelthompson 8e23e0c
Fix merge errors
joelthompson 16c60d6
Merge remote-tracking branch 'origin/master' into aws_secret_root_rot…
joelthompson f8f020f
Fix locking bugs
joelthompson 27e4b1d
Merge branch 'master' into aws_secret_root_rotation
vishalnayak File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package aws | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/iam" | ||
"github.com/hashicorp/errwrap" | ||
"github.com/hashicorp/vault/logical" | ||
"github.com/hashicorp/vault/logical/framework" | ||
) | ||
|
||
func pathConfigRotateRoot(b *backend) *framework.Path { | ||
return &framework.Path{ | ||
Pattern: "config/rotate-root", | ||
Callbacks: map[logical.Operation]framework.OperationFunc{ | ||
logical.UpdateOperation: b.pathConfigRotateRootUpdate, | ||
}, | ||
|
||
HelpSynopsis: pathConfigRotateRootHelpSyn, | ||
HelpDescription: pathConfigRotateRootHelpDesc, | ||
} | ||
} | ||
|
||
func (b *backend) pathConfigRotateRootUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { | ||
// have to get the client config first because that takes out a read lock | ||
client, err := b.clientIAM(ctx, req.Storage) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if client == nil { | ||
return nil, fmt.Errorf("nil IAM client") | ||
} | ||
|
||
b.clientMutex.Lock() | ||
defer b.clientMutex.Unlock() | ||
|
||
rawRootConfig, err := req.Storage.Get(ctx, "config/root") | ||
if err != nil { | ||
return nil, err | ||
} | ||
if rawRootConfig == nil { | ||
return nil, fmt.Errorf("no configuration found for config/root") | ||
} | ||
var config rootConfig | ||
if err := rawRootConfig.DecodeJSON(&config); err != nil { | ||
return nil, errwrap.Wrapf("error reading root configuration: {{err}}", err) | ||
} | ||
|
||
if config.AccessKey == "" || config.SecretKey == "" { | ||
return logical.ErrorResponse("Cannot call config/rotate-root when either access_key or secret_key is empty"), nil | ||
} | ||
|
||
var getUserInput iam.GetUserInput // empty input means get current user | ||
getUserRes, err := client.GetUser(&getUserInput) | ||
if err != nil { | ||
return nil, errwrap.Wrapf("error calling GetUser: {{err}}", err) | ||
} | ||
if getUserRes == nil { | ||
return nil, fmt.Errorf("nil response from GetUser") | ||
} | ||
if getUserRes.User == nil { | ||
return nil, fmt.Errorf("nil user returned from GetUser") | ||
} | ||
if getUserRes.User.UserName == nil { | ||
return nil, fmt.Errorf("nil UserName returned from GetUser") | ||
} | ||
|
||
createAccessKeyInput := iam.CreateAccessKeyInput{ | ||
UserName: getUserRes.User.UserName, | ||
} | ||
createAccessKeyRes, err := client.CreateAccessKey(&createAccessKeyInput) | ||
if err != nil { | ||
return nil, errwrap.Wrapf("error calling CreateAccessKey: {{err}}", err) | ||
} | ||
if createAccessKeyRes.AccessKey == nil { | ||
return nil, fmt.Errorf("nil response from CreateAccessKey") | ||
} | ||
if createAccessKeyRes.AccessKey.AccessKeyId == nil || createAccessKeyRes.AccessKey.SecretAccessKey == nil { | ||
return nil, fmt.Errorf("nil AccessKeyId or SecretAccessKey returned from CreateAccessKey") | ||
} | ||
|
||
oldAccessKey := config.AccessKey | ||
|
||
config.AccessKey = *createAccessKeyRes.AccessKey.AccessKeyId | ||
config.SecretKey = *createAccessKeyRes.AccessKey.SecretAccessKey | ||
|
||
newEntry, err := logical.StorageEntryJSON("config/root", config) | ||
if err != nil { | ||
return nil, errwrap.Wrapf("error generating new config/root JSON: {{err}}", err) | ||
} | ||
if err := req.Storage.Put(ctx, newEntry); err != nil { | ||
return nil, errwrap.Wrapf("error saving new config/root: {{err}}", err) | ||
} | ||
|
||
b.iamClient = nil | ||
b.stsClient = nil | ||
|
||
deleteAccessKeyInput := iam.DeleteAccessKeyInput{ | ||
AccessKeyId: aws.String(oldAccessKey), | ||
UserName: getUserRes.User.UserName, | ||
} | ||
_, err = client.DeleteAccessKey(&deleteAccessKeyInput) | ||
if err != nil { | ||
return nil, errwrap.Wrapf("error deleting old access key: {{err}}", err) | ||
} | ||
|
||
return &logical.Response{ | ||
Data: map[string]interface{}{ | ||
"access_key": config.AccessKey, | ||
}, | ||
}, nil | ||
} | ||
|
||
const pathConfigRotateRootHelpSyn = ` | ||
Request to rotate the AWS credentials used by Vault | ||
` | ||
|
||
const pathConfigRotateRootHelpDesc = ` | ||
This path attempts to rotate the AWS credentials used by Vault for this mount. | ||
It is only valid if Vault has been configured to use AWS IAM credentials via the | ||
config/root endpoint. | ||
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this just be a warning response instead of returning an err? In this event, the access key was successfully rotated, but it just failed to clean up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be an error.