From 42d95890667a9adbac46e38c64980c4e170d71f6 Mon Sep 17 00:00:00 2001 From: Jim Kalafut Date: Thu, 25 Feb 2021 23:23:34 -0800 Subject: [PATCH] Replace deprecated terms in AWS Auth (#10997) * Replace deprecated terms in AWS Auth This PR is part of an effort to remove non-inclusive language throughout Vault. The AWS Auth backend uses the "whitelist" and "blacklist" term extensively, and these are the focus of the PR: * Add new API endpoints that use the preferred terminology, while deprecating the old endpoints. These endpoints offer identical functionality and are basically aliases. This is the only functional change in the PR except for terms in error messages. * Replace "whitelist" -> "access list", "blacklist" -> "deny list" in variable names, comments, etc. Note that storage locations were *not* changed at this time, as that is a more complex process involving versioning that we may tackle in a future revision. We have reduced the occurrences of non-inclusive language, however. Reviewers should be sure to "Ignore Whitespace" in diffs, especially for the tests, which were basically indented one level as part of looping over the tests with both the old and new names. --- builtin/credential/aws/backend.go | 95 +- builtin/credential/aws/backend_test.go | 1027 +++++++++-------- ...> path_config_tidy_identity_accesslist.go} | 44 +- ...o => path_config_tidy_roletag_denylist.go} | 55 +- ...itelist.go => path_identity_accesslist.go} | 84 +- builtin/credential/aws/path_login.go | 48 +- builtin/credential/aws/path_role.go | 4 +- builtin/credential/aws/path_role_tag.go | 2 +- ..._blacklist.go => path_roletag_denylist.go} | 106 +- ...st.go => path_tidy_identity_accesslist.go} | 42 +- ...klist.go => path_tidy_roletag_denylist.go} | 44 +- changelog/10997.txt | 13 + ui/app/adapters/auth-config/_base.js | 1 + ui/app/helpers/tabs-for-auth-section.js | 8 +- ui/app/models/role-ssh.js | 3 +- .../settings/auth/configure/section.js | 1 + .../addon/components/form-field-groups.js | 2 +- ui/lib/core/stories/form-field-groups.md | 2 +- 18 files changed, 827 insertions(+), 754 deletions(-) rename builtin/credential/aws/{path_config_tidy_identity_whitelist.go => path_config_tidy_identity_accesslist.go} (65%) rename builtin/credential/aws/{path_config_tidy_roletag_blacklist.go => path_config_tidy_roletag_denylist.go} (61%) rename builtin/credential/aws/{path_identity_whitelist.go => path_identity_accesslist.go} (51%) rename builtin/credential/aws/{path_roletag_blacklist.go => path_roletag_denylist.go} (61%) rename builtin/credential/aws/{path_tidy_identity_whitelist.go => path_tidy_identity_accesslist.go} (65%) rename builtin/credential/aws/{path_tidy_roletag_blacklist.go => path_tidy_roletag_denylist.go} (65%) create mode 100644 changelog/10997.txt diff --git a/builtin/credential/aws/backend.go b/builtin/credential/aws/backend.go index 7af257520d..5a555ddac3 100644 --- a/builtin/credential/aws/backend.go +++ b/builtin/credential/aws/backend.go @@ -48,15 +48,15 @@ type backend struct { // Lock to make changes to role entries roleMutex sync.Mutex - // Lock to make changes to the blacklist entries - blacklistMutex sync.RWMutex + // Lock to make changes to the deny list entries + denyListMutex sync.RWMutex - // Guards the blacklist/whitelist tidy functions - tidyBlacklistCASGuard *uint32 - tidyWhitelistCASGuard *uint32 + // Guards the deny list/access list tidy functions + tidyDenyListCASGuard *uint32 + tidyAccessListCASGuard *uint32 // Duration after which the periodic function of the backend needs to - // tidy the blacklist and whitelist entries. + // tidy the deny list and access list entries. tidyCooldownPeriod time.Duration // nextTidyTime holds the time at which the periodic func should initiate @@ -101,19 +101,29 @@ type backend struct { // upgradeCancelFunc is used to cancel the context used in the upgrade // function upgradeCancelFunc context.CancelFunc + + // deprecatedTerms is used to downgrade preferred terminology (e.g. accesslist) + // to the legacy term. This allows for consolidated aliasing of the affected + // endpoints until the legacy terms are removed. + deprecatedTerms *strings.Replacer } func Backend(_ *logical.BackendConfig) (*backend, error) { b := &backend{ // Setting the periodic func to be run once in an hour. // If there is a real need, this can be made configurable. - tidyCooldownPeriod: time.Hour, - EC2ClientsMap: make(map[string]map[string]*ec2.EC2), - IAMClientsMap: make(map[string]map[string]*iam.IAM), - iamUserIdToArnCache: cache.New(7*24*time.Hour, 24*time.Hour), - tidyBlacklistCASGuard: new(uint32), - tidyWhitelistCASGuard: new(uint32), - roleCache: cache.New(cache.NoExpiration, cache.NoExpiration), + tidyCooldownPeriod: time.Hour, + EC2ClientsMap: make(map[string]map[string]*ec2.EC2), + IAMClientsMap: make(map[string]map[string]*iam.IAM), + iamUserIdToArnCache: cache.New(7*24*time.Hour, 24*time.Hour), + tidyDenyListCASGuard: new(uint32), + tidyAccessListCASGuard: new(uint32), + roleCache: cache.New(cache.NoExpiration, cache.NoExpiration), + + deprecatedTerms: strings.NewReplacer( + "accesslist", "whitelist", + "denylist", "blacklist", + ), } b.resolveArnToUniqueIDFunc = b.resolveArnToRealUniqueId @@ -127,7 +137,7 @@ func Backend(_ *logical.BackendConfig) (*backend, error) { "login", }, LocalStorage: []string{ - "whitelist/identity/", + identityAccessListStorage, }, SealWrapStorage: []string{ "config/client", @@ -145,15 +155,34 @@ func Backend(_ *logical.BackendConfig) (*backend, error) { b.pathConfigRotateRoot(), b.pathConfigSts(), b.pathListSts(), - b.pathConfigTidyRoletagBlacklist(), - b.pathConfigTidyIdentityWhitelist(), b.pathListCertificates(), - b.pathListRoletagBlacklist(), - b.pathRoletagBlacklist(), - b.pathTidyRoletagBlacklist(), - b.pathListIdentityWhitelist(), - b.pathIdentityWhitelist(), - b.pathTidyIdentityWhitelist(), + + // The following pairs of functions are path aliases. The first is the + // primary endpoint, and the second is version using deprecated language, + // for backwards compatibility. The functionality is identical between the two. + b.pathConfigTidyRoletagDenyList(), + b.genDeprecatedPath(b.pathConfigTidyRoletagDenyList()), + + b.pathConfigTidyIdentityAccessList(), + b.genDeprecatedPath(b.pathConfigTidyIdentityAccessList()), + + b.pathListRoletagDenyList(), + b.genDeprecatedPath(b.pathListRoletagDenyList()), + + b.pathRoletagDenyList(), + b.genDeprecatedPath(b.pathRoletagDenyList()), + + b.pathTidyRoletagDenyList(), + b.genDeprecatedPath(b.pathTidyRoletagDenyList()), + + b.pathListIdentityAccessList(), + b.genDeprecatedPath(b.pathListIdentityAccessList()), + + b.pathIdentityAccessList(), + b.genDeprecatedPath(b.pathIdentityAccessList()), + + b.pathTidyIdentityAccessList(), + b.genDeprecatedPath(b.pathTidyIdentityAccessList()), }, Invalidate: b.invalidate, InitializeFunc: b.initialize, @@ -170,16 +199,16 @@ func Backend(_ *logical.BackendConfig) (*backend, error) { // Currently this will be triggered once in a minute by the RollbackManager. // // The tasks being done currently by this function are to cleanup the expired -// entries of both blacklist role tags and whitelist identities. Tidying is done +// entries of both deny list role tags and access list identities. Tidying is done // not once in a minute, but once in an hour, controlled by 'tidyCooldownPeriod'. -// Tidying of blacklist and whitelist are by default enabled. This can be +// Tidying of deny list and access list are by default enabled. This can be // changed using `config/tidy/roletags` and `config/tidy/identities` endpoints. func (b *backend) periodicFunc(ctx context.Context, req *logical.Request) error { // Run the tidy operations for the first time. Then run it when current // time matches the nextTidyTime. if b.nextTidyTime.IsZero() || !time.Now().Before(b.nextTidyTime) { if b.System().LocalMount() || !b.System().ReplicationState().HasState(consts.ReplicationPerformanceSecondary|consts.ReplicationPerformanceStandby) { - // safetyBuffer defaults to 180 days for roletag blacklist + // safetyBuffer defaults to 180 days for roletag deny list safetyBuffer := 15552000 tidyBlacklistConfigEntry, err := b.lockedConfigTidyRoleTags(ctx, req.Storage) if err != nil { @@ -197,11 +226,11 @@ func (b *backend) periodicFunc(ctx context.Context, req *logical.Request) error } // tidy role tags if explicitly not disabled if !skipBlacklistTidy { - b.tidyBlacklistRoleTag(ctx, req, safetyBuffer) + b.tidyDenyListRoleTag(ctx, req, safetyBuffer) } } - // We don't check for replication state for whitelist identities as + // We don't check for replication state for access list identities as // these are locally stored safety_buffer := 259200 @@ -221,7 +250,7 @@ func (b *backend) periodicFunc(ctx context.Context, req *logical.Request) error } // tidy identities if explicitly not disabled if !skipWhitelistTidy { - b.tidyWhitelistIdentity(ctx, req, safety_buffer) + b.tidyAccessListIdentity(ctx, req, safety_buffer) } // Update the time at which to run the tidy functions again. @@ -310,6 +339,16 @@ func (b *backend) resolveArnToRealUniqueId(ctx context.Context, s logical.Storag } } +// genDeprecatedPath will return a deprecated version of a framework.Path. The will include +// using deprecated terms in the path pattern, and marking the path as deprecated. +func (b *backend) genDeprecatedPath(path *framework.Path) *framework.Path { + pathDeprecated := *path + pathDeprecated.Pattern = b.deprecatedTerms.Replace(path.Pattern) + pathDeprecated.Deprecated = true + + return &pathDeprecated +} + // Adapted from https://docs.aws.amazon.com/sdk-for-go/api/aws/endpoints/ // the "Enumerating Regions and Endpoint Metadata" section func generatePartitionToRegionMap() map[string]*endpoints.Region { diff --git a/builtin/credential/aws/backend_test.go b/builtin/credential/aws/backend_test.go index 4ce0d4eac3..4ea90b7b17 100644 --- a/builtin/credential/aws/backend_test.go +++ b/builtin/credential/aws/backend_test.go @@ -250,209 +250,217 @@ func TestBackend_CreateRoleTagNonce(t *testing.T) { } func TestBackend_ConfigTidyIdentities(t *testing.T) { - // create a backend - config := logical.TestBackendConfig() - storage := &logical.InmemStorage{} - config.StorageView = storage + for _, path := range []string{"config/tidy/identity-whitelist", "config/tidy/identity-accesslist"} { + // create a backend + config := logical.TestBackendConfig() + storage := &logical.InmemStorage{} + config.StorageView = storage - b, err := Backend(config) - if err != nil { - t.Fatal(err) - } + b, err := Backend(config) + if err != nil { + t.Fatal(err) + } - err = b.Setup(context.Background(), config) - if err != nil { - t.Fatal(err) - } + err = b.Setup(context.Background(), config) + if err != nil { + t.Fatal(err) + } - // test update operation - tidyRequest := &logical.Request{ - Operation: logical.UpdateOperation, - Path: "config/tidy/identity-whitelist", - Storage: storage, - } - data := map[string]interface{}{ - "safety_buffer": "60", - "disable_periodic_tidy": true, - } - tidyRequest.Data = data - _, err = b.HandleRequest(context.Background(), tidyRequest) - if err != nil { - t.Fatal(err) - } + // test update operation + tidyRequest := &logical.Request{ + Operation: logical.UpdateOperation, + Path: path, + Storage: storage, + } + data := map[string]interface{}{ + "safety_buffer": "60", + "disable_periodic_tidy": true, + } + tidyRequest.Data = data + _, err = b.HandleRequest(context.Background(), tidyRequest) + if err != nil { + t.Fatal(err) + } - // test read operation - tidyRequest.Operation = logical.ReadOperation - resp, err := b.HandleRequest(context.Background(), tidyRequest) - if err != nil { - t.Fatal(err) - } - if resp == nil || resp.IsError() { - t.Fatalf("failed to read config/tidy/identity-whitelist endpoint") - } - if resp.Data["safety_buffer"].(int) != 60 || !resp.Data["disable_periodic_tidy"].(bool) { - t.Fatalf("bad: expected: safety_buffer:60 disable_periodic_tidy:true actual: safety_buffer:%d disable_periodic_tidy:%t\n", resp.Data["safety_buffer"].(int), resp.Data["disable_periodic_tidy"].(bool)) - } + // test read operation + tidyRequest.Operation = logical.ReadOperation + resp, err := b.HandleRequest(context.Background(), tidyRequest) + if err != nil { + t.Fatal(err) + } + if resp == nil || resp.IsError() { + t.Fatalf("failed to read %q endpoint", path) + } + if resp.Data["safety_buffer"].(int) != 60 || !resp.Data["disable_periodic_tidy"].(bool) { + t.Fatalf("bad: expected: safety_buffer:60 disable_periodic_tidy:true actual: safety_buffer:%d disable_periodic_tidy:%t\n", resp.Data["safety_buffer"].(int), resp.Data["disable_periodic_tidy"].(bool)) + } - // test delete operation - tidyRequest.Operation = logical.DeleteOperation - resp, err = b.HandleRequest(context.Background(), tidyRequest) - if err != nil { - t.Fatal(err) - } - if resp != nil { - t.Fatalf("failed to delete config/tidy/identity-whitelist") + // test delete operation + tidyRequest.Operation = logical.DeleteOperation + resp, err = b.HandleRequest(context.Background(), tidyRequest) + if err != nil { + t.Fatal(err) + } + if resp != nil { + t.Fatalf("failed to delete %q", path) + } } } func TestBackend_ConfigTidyRoleTags(t *testing.T) { - config := logical.TestBackendConfig() - storage := &logical.InmemStorage{} - config.StorageView = storage + for _, path := range []string{"config/tidy/roletag-blacklist", "config/tidy/roletag-denylist"} { + config := logical.TestBackendConfig() + storage := &logical.InmemStorage{} + config.StorageView = storage - b, err := Backend(config) - if err != nil { - t.Fatal(err) - } + b, err := Backend(config) + if err != nil { + t.Fatal(err) + } - err = b.Setup(context.Background(), config) - if err != nil { - t.Fatal(err) - } + err = b.Setup(context.Background(), config) + if err != nil { + t.Fatal(err) + } - // test update operation - tidyRequest := &logical.Request{ - Operation: logical.UpdateOperation, - Path: "config/tidy/roletag-blacklist", - Storage: storage, - } - data := map[string]interface{}{ - "safety_buffer": "60", - "disable_periodic_tidy": true, - } - tidyRequest.Data = data - _, err = b.HandleRequest(context.Background(), tidyRequest) - if err != nil { - t.Fatal(err) - } + // test update operation + tidyRequest := &logical.Request{ + Operation: logical.UpdateOperation, + Path: path, + Storage: storage, + } + data := map[string]interface{}{ + "safety_buffer": "60", + "disable_periodic_tidy": true, + } + tidyRequest.Data = data + _, err = b.HandleRequest(context.Background(), tidyRequest) + if err != nil { + t.Fatal(err) + } - // test read operation - tidyRequest.Operation = logical.ReadOperation - resp, err := b.HandleRequest(context.Background(), tidyRequest) - if err != nil { - t.Fatal(err) - } - if resp == nil || resp.IsError() { - t.Fatalf("failed to read config/tidy/roletag-blacklist endpoint") - } - if resp.Data["safety_buffer"].(int) != 60 || !resp.Data["disable_periodic_tidy"].(bool) { - t.Fatalf("bad: expected: safety_buffer:60 disable_periodic_tidy:true actual: safety_buffer:%d disable_periodic_tidy:%t\n", resp.Data["safety_buffer"].(int), resp.Data["disable_periodic_tidy"].(bool)) - } + // test read operation + tidyRequest.Operation = logical.ReadOperation + resp, err := b.HandleRequest(context.Background(), tidyRequest) + if err != nil { + t.Fatal(err) + } + if resp == nil || resp.IsError() { + t.Fatalf("failed to read %s endpoint", path) + } + if resp.Data["safety_buffer"].(int) != 60 || !resp.Data["disable_periodic_tidy"].(bool) { + t.Fatalf("bad: expected: safety_buffer:60 disable_periodic_tidy:true actual: safety_buffer:%d disable_periodic_tidy:%t\n", resp.Data["safety_buffer"].(int), resp.Data["disable_periodic_tidy"].(bool)) + } - // test delete operation - tidyRequest.Operation = logical.DeleteOperation - resp, err = b.HandleRequest(context.Background(), tidyRequest) - if err != nil { - t.Fatal(err) - } - if resp != nil { - t.Fatalf("failed to delete config/tidy/roletag-blacklist") + // test delete operation + tidyRequest.Operation = logical.DeleteOperation + resp, err = b.HandleRequest(context.Background(), tidyRequest) + if err != nil { + t.Fatal(err) + } + if resp != nil { + t.Fatalf("failed to delete %s", path) + } } } func TestBackend_TidyIdentities(t *testing.T) { - config := logical.TestBackendConfig() - storage := &logical.InmemStorage{} - config.StorageView = storage + for _, path := range []string{"tidy/identity-whitelist", "tidy/identity-accesslist"} { + config := logical.TestBackendConfig() + storage := &logical.InmemStorage{} + config.StorageView = storage - b, err := Backend(config) - if err != nil { - t.Fatal(err) - } + b, err := Backend(config) + if err != nil { + t.Fatal(err) + } - err = b.Setup(context.Background(), config) - if err != nil { - t.Fatal(err) - } + err = b.Setup(context.Background(), config) + if err != nil { + t.Fatal(err) + } - expiredIdentityWhitelist := &whitelistIdentity{ - ExpirationTime: time.Now().Add(-1 * 24 * 365 * time.Hour), - } - entry, err := logical.StorageEntryJSON("whitelist/identity/id1", expiredIdentityWhitelist) - if err != nil { - t.Fatal(err) - } - if err := storage.Put(context.Background(), entry); err != nil { - t.Fatal(err) - } + expiredIdentityWhitelist := &accessListIdentity{ + ExpirationTime: time.Now().Add(-1 * 24 * 365 * time.Hour), + } + entry, err := logical.StorageEntryJSON("whitelist/identity/id1", expiredIdentityWhitelist) + if err != nil { + t.Fatal(err) + } + if err := storage.Put(context.Background(), entry); err != nil { + t.Fatal(err) + } - // test update operation - _, err = b.HandleRequest(context.Background(), &logical.Request{ - Operation: logical.UpdateOperation, - Path: "tidy/identity-whitelist", - Storage: storage, - }) - if err != nil { - t.Fatal(err) - } + // test update operation + _, err = b.HandleRequest(context.Background(), &logical.Request{ + Operation: logical.UpdateOperation, + Path: path, + Storage: storage, + }) + if err != nil { + t.Fatal(err) + } - // let tidy finish in the background - time.Sleep(1 * time.Second) + // let tidy finish in the background + time.Sleep(1 * time.Second) - entry, err = storage.Get(context.Background(), "whitelist/identity/id1") - if err != nil { - t.Fatal(err) - } - if entry != nil { - t.Fatal("wl tidy did not remove expired entry") + entry, err = storage.Get(context.Background(), "whitelist/identity/id1") + if err != nil { + t.Fatal(err) + } + if entry != nil { + t.Fatal("wl tidy did not remove expired entry") + } } } func TestBackend_TidyRoleTags(t *testing.T) { - config := logical.TestBackendConfig() - storage := &logical.InmemStorage{} - config.StorageView = storage + for _, path := range []string{"tidy/roletag-blacklist", "tidy/roletag-denylist"} { + config := logical.TestBackendConfig() + storage := &logical.InmemStorage{} + config.StorageView = storage - b, err := Backend(config) - if err != nil { - t.Fatal(err) - } + b, err := Backend(config) + if err != nil { + t.Fatal(err) + } - err = b.Setup(context.Background(), config) - if err != nil { - t.Fatal(err) - } + err = b.Setup(context.Background(), config) + if err != nil { + t.Fatal(err) + } - expiredIdentityWhitelist := &roleTagBlacklistEntry{ - ExpirationTime: time.Now().Add(-1 * 24 * 365 * time.Hour), - } - entry, err := logical.StorageEntryJSON("blacklist/roletag/id1", expiredIdentityWhitelist) - if err != nil { - t.Fatal(err) - } - if err := storage.Put(context.Background(), entry); err != nil { - t.Fatal(err) - } + expiredIdentityWhitelist := &roleTagBlacklistEntry{ + ExpirationTime: time.Now().Add(-1 * 24 * 365 * time.Hour), + } + entry, err := logical.StorageEntryJSON("blacklist/roletag/id1", expiredIdentityWhitelist) + if err != nil { + t.Fatal(err) + } + if err := storage.Put(context.Background(), entry); err != nil { + t.Fatal(err) + } - // test update operation - _, err = b.HandleRequest(context.Background(), &logical.Request{ - Operation: logical.UpdateOperation, - Path: "tidy/roletag-blacklist", - Storage: storage, - }) - if err != nil { - t.Fatal(err) - } + // test update operation + _, err = b.HandleRequest(context.Background(), &logical.Request{ + Operation: logical.UpdateOperation, + Path: path, + Storage: storage, + }) + if err != nil { + t.Fatal(err) + } - // let tidy finish in the background - time.Sleep(1 * time.Second) + // let tidy finish in the background + time.Sleep(1 * time.Second) - entry, err = storage.Get(context.Background(), "blacklist/roletag/id1") - if err != nil { - t.Fatal(err) - } - if entry != nil { - t.Fatal("bl tidy did not remove expired entry") + entry, err = storage.Get(context.Background(), "blacklist/roletag/id1") + if err != nil { + t.Fatal(err) + } + if entry != nil { + t.Fatal("bl tidy did not remove expired entry") + } } } @@ -899,110 +907,113 @@ func TestBackend_PathRoleTag(t *testing.T) { } func TestBackend_PathBlacklistRoleTag(t *testing.T) { - // create the backend - storage := &logical.InmemStorage{} - config := logical.TestBackendConfig() - config.StorageView = storage - b, err := Backend(config) - if err != nil { - t.Fatal(err) - } - err = b.Setup(context.Background(), config) - if err != nil { - t.Fatal(err) - } + for _, path := range []string{"roletag-blacklist/", "roletag-denylist/"} { + // create the backend + storage := &logical.InmemStorage{} + config := logical.TestBackendConfig() + config.StorageView = storage + b, err := Backend(config) + if err != nil { + t.Fatal(err) + } - // create an role entry - data := map[string]interface{}{ - "auth_type": "ec2", - "policies": "p,q,r,s", - "role_tag": "VaultRole", - "bound_ami_id": "abcd-123", - } - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Operation: logical.CreateOperation, - Path: "role/abcd-123", - Storage: storage, - Data: data, - }) - if resp != nil && resp.IsError() { - t.Fatalf("failed to create role") - } - if err != nil { - t.Fatal(err) - } + err = b.Setup(context.Background(), config) + if err != nil { + t.Fatal(err) + } - // create a role tag against an role registered before - data2 := map[string]interface{}{ - "policies": "p,q,r,s", - } - resp, err = b.HandleRequest(context.Background(), &logical.Request{ - Operation: logical.UpdateOperation, - Path: "role/abcd-123/tag", - Storage: storage, - Data: data2, - }) - if err != nil { - t.Fatal(err) - } - if resp == nil || resp.Data == nil { - t.Fatalf("failed to create a tag on role: abcd-123") - } - if resp.IsError() { - t.Fatalf("failed to create a tag on role: abcd-123: %s\n", resp.Data["error"]) - } - tag := resp.Data["tag_value"].(string) - if tag == "" { - t.Fatalf("role tag not present in the response data: %#v\n", resp.Data) - } + // create an role entry + data := map[string]interface{}{ + "auth_type": "ec2", + "policies": "p,q,r,s", + "role_tag": "VaultRole", + "bound_ami_id": "abcd-123", + } + resp, err := b.HandleRequest(context.Background(), &logical.Request{ + Operation: logical.CreateOperation, + Path: "role/abcd-123", + Storage: storage, + Data: data, + }) + if resp != nil && resp.IsError() { + t.Fatalf("failed to create role") + } + if err != nil { + t.Fatal(err) + } - // blacklist that role tag - resp, err = b.HandleRequest(context.Background(), &logical.Request{ - Operation: logical.UpdateOperation, - Path: "roletag-blacklist/" + tag, - Storage: storage, - }) - if err != nil { - t.Fatal(err) - } - if resp != nil { - t.Fatalf("failed to blacklist the roletag: %s\n", tag) - } + // create a role tag against an role registered before + data2 := map[string]interface{}{ + "policies": "p,q,r,s", + } + resp, err = b.HandleRequest(context.Background(), &logical.Request{ + Operation: logical.UpdateOperation, + Path: "role/abcd-123/tag", + Storage: storage, + Data: data2, + }) + if err != nil { + t.Fatal(err) + } + if resp == nil || resp.Data == nil { + t.Fatalf("failed to create a tag on role: abcd-123") + } + if resp.IsError() { + t.Fatalf("failed to create a tag on role: abcd-123: %s\n", resp.Data["error"]) + } + tag := resp.Data["tag_value"].(string) + if tag == "" { + t.Fatalf("role tag not present in the response data: %#v\n", resp.Data) + } - // read the blacklist entry - resp, err = b.HandleRequest(context.Background(), &logical.Request{ - Operation: logical.ReadOperation, - Path: "roletag-blacklist/" + tag, - Storage: storage, - }) - if err != nil { - t.Fatal(err) - } - if resp == nil || resp.Data == nil { - t.Fatalf("failed to read the blacklisted role tag: %s\n", tag) - } - if resp.IsError() { - t.Fatalf("failed to read the blacklisted role tag:%s. Err: %s\n", tag, resp.Data["error"]) - } + // deny list that role tag + resp, err = b.HandleRequest(context.Background(), &logical.Request{ + Operation: logical.UpdateOperation, + Path: path + tag, + Storage: storage, + }) + if err != nil { + t.Fatal(err) + } + if resp != nil { + t.Fatalf("failed to deny list the roletag: %s\n", tag) + } - // delete the blacklisted entry - _, err = b.HandleRequest(context.Background(), &logical.Request{ - Operation: logical.DeleteOperation, - Path: "roletag-blacklist/" + tag, - Storage: storage, - }) - if err != nil { - t.Fatal(err) - } + // read the deny list entry + resp, err = b.HandleRequest(context.Background(), &logical.Request{ + Operation: logical.ReadOperation, + Path: path + tag, + Storage: storage, + }) + if err != nil { + t.Fatal(err) + } + if resp == nil || resp.Data == nil { + t.Fatalf("failed to read the deny list role tag: %s\n", tag) + } + if resp.IsError() { + t.Fatalf("failed to read the deny list role tag:%s. Err: %s\n", tag, resp.Data["error"]) + } - // try to read the deleted entry - tagEntry, err := b.lockedBlacklistRoleTagEntry(context.Background(), storage, tag) - if err != nil { - t.Fatal(err) - } - if tagEntry != nil { - t.Fatalf("role tag should not have been present: %s\n", tag) + // delete the deny listed entry + _, err = b.HandleRequest(context.Background(), &logical.Request{ + Operation: logical.DeleteOperation, + Path: path + tag, + Storage: storage, + }) + if err != nil { + t.Fatal(err) + } + + // try to read the deleted entry + tagEntry, err := b.lockedDenyLististRoleTagEntry(context.Background(), storage, tag) + if err != nil { + t.Fatal(err) + } + if tagEntry != nil { + t.Fatalf("role tag should not have been present: %s\n", tag) + } } } @@ -1030,271 +1041,273 @@ func TestBackend_PathBlacklistRoleTag(t *testing.T) { TEST_AWS_SECRET_KEY TEST_AWS_ACCESS_KEY */ -func TestBackendAcc_LoginWithInstanceIdentityDocAndWhitelistIdentity(t *testing.T) { - // This test case should be run only when certain env vars are set and - // executed as an acceptance test. - if os.Getenv(logicaltest.TestEnvVar) == "" { - t.Skip(fmt.Sprintf("Acceptance tests skipped unless env '%s' set", logicaltest.TestEnvVar)) - return - } - - pkcs7 := os.Getenv("TEST_AWS_EC2_PKCS7") - if pkcs7 == "" { - t.Skipf("env var TEST_AWS_EC2_PKCS7 not set, skipping test") - } - - identityDoc := os.Getenv("TEST_AWS_EC2_IDENTITY_DOCUMENT") - if identityDoc == "" { - t.Skipf("env var TEST_AWS_EC2_IDENTITY_DOCUMENT not set, skipping test") - } - - identityDocSig := os.Getenv("TEST_AWS_EC2_IDENTITY_DOCUMENT_SIG") - if identityDocSig == "" { - t.Skipf("env var TEST_AWS_EC2_IDENTITY_DOCUMENT_SIG not set, skipping test") - } - - amiID := os.Getenv("TEST_AWS_EC2_AMI_ID") - if amiID == "" { - t.Skipf("env var TEST_AWS_EC2_AMI_ID not set, skipping test") - } - - iamARN := os.Getenv("TEST_AWS_EC2_IAM_ROLE_ARN") - if iamARN == "" { - t.Skipf("env var TEST_AWS_EC2_IAM_ROLE_ARN not set, skipping test") - } - - accountID := os.Getenv("TEST_AWS_EC2_ACCOUNT_ID") - if accountID == "" { - t.Skipf("env var TEST_AWS_EC2_ACCOUNT_ID not set, skipping test") - } - - roleName := amiID - - // create the backend - storage := &logical.InmemStorage{} - config := logical.TestBackendConfig() - config.StorageView = storage - b, err := Backend(config) - if err != nil { - t.Fatal(err) - } - - err = b.Setup(context.Background(), config) - if err != nil { - t.Fatal(err) - } - - accessKey := os.Getenv("TEST_AWS_ACCESS_KEY") - secretKey := os.Getenv("TEST_AWS_SECRET_KEY") - - // In case of problems with making API calls using the credentials (2FA enabled, - // for instance), the keys need not be set if the test is running on an EC2 - // instance with permissions to get the credentials using EC2RoleProvider. - if accessKey != "" && secretKey != "" { - // get the API credentials from env vars - clientConfig := map[string]interface{}{ - "access_key": accessKey, - "secret_key": secretKey, - } - if clientConfig["access_key"] == "" || - clientConfig["secret_key"] == "" { - t.Fatalf("credentials not configured") +func TestBackendAcc_LoginWithInstanceIdentityDocAndAccessListIdentity(t *testing.T) { + for _, path := range []string{"identity-whitelist/", "identity-accesslist/"} { + // This test case should be run only when certain env vars are set and + // executed as an acceptance test. + if os.Getenv(logicaltest.TestEnvVar) == "" { + t.Skip(fmt.Sprintf("Acceptance tests skipped unless env '%s' set", logicaltest.TestEnvVar)) + return } - // store the credentials - _, err = b.HandleRequest(context.Background(), &logical.Request{ - Operation: logical.UpdateOperation, - Storage: storage, - Path: "config/client", - Data: clientConfig, - }) + pkcs7 := os.Getenv("TEST_AWS_EC2_PKCS7") + if pkcs7 == "" { + t.Skipf("env var TEST_AWS_EC2_PKCS7 not set, skipping test") + } + + identityDoc := os.Getenv("TEST_AWS_EC2_IDENTITY_DOCUMENT") + if identityDoc == "" { + t.Skipf("env var TEST_AWS_EC2_IDENTITY_DOCUMENT not set, skipping test") + } + + identityDocSig := os.Getenv("TEST_AWS_EC2_IDENTITY_DOCUMENT_SIG") + if identityDocSig == "" { + t.Skipf("env var TEST_AWS_EC2_IDENTITY_DOCUMENT_SIG not set, skipping test") + } + + amiID := os.Getenv("TEST_AWS_EC2_AMI_ID") + if amiID == "" { + t.Skipf("env var TEST_AWS_EC2_AMI_ID not set, skipping test") + } + + iamARN := os.Getenv("TEST_AWS_EC2_IAM_ROLE_ARN") + if iamARN == "" { + t.Skipf("env var TEST_AWS_EC2_IAM_ROLE_ARN not set, skipping test") + } + + accountID := os.Getenv("TEST_AWS_EC2_ACCOUNT_ID") + if accountID == "" { + t.Skipf("env var TEST_AWS_EC2_ACCOUNT_ID not set, skipping test") + } + + roleName := amiID + + // create the backend + storage := &logical.InmemStorage{} + config := logical.TestBackendConfig() + config.StorageView = storage + b, err := Backend(config) if err != nil { t.Fatal(err) } - } - loginInput := map[string]interface{}{ - "pkcs7": pkcs7, - "nonce": "vault-client-nonce", - } + err = b.Setup(context.Background(), config) + if err != nil { + t.Fatal(err) + } - parsedIdentityDoc, err := b.parseIdentityDocument(context.Background(), storage, pkcs7) - if err != nil { - t.Fatal(err) - } + accessKey := os.Getenv("TEST_AWS_ACCESS_KEY") + secretKey := os.Getenv("TEST_AWS_SECRET_KEY") - // Perform the login operation with a AMI ID that is not matching - // the bound on the role. - loginRequest := &logical.Request{ - Operation: logical.UpdateOperation, - Path: "login", - Storage: storage, - Data: loginInput, - } + // In case of problems with making API calls using the credentials (2FA enabled, + // for instance), the keys need not be set if the test is running on an EC2 + // instance with permissions to get the credentials using EC2RoleProvider. + if accessKey != "" && secretKey != "" { + // get the API credentials from env vars + clientConfig := map[string]interface{}{ + "access_key": accessKey, + "secret_key": secretKey, + } + if clientConfig["access_key"] == "" || + clientConfig["secret_key"] == "" { + t.Fatalf("credentials not configured") + } - // Baseline role data that should succeed permit login - data := map[string]interface{}{ - "auth_type": "ec2", - "policies": "root", - "max_ttl": "120s", - "bound_ami_id": []string{"wrong_ami_id", amiID, "wrong_ami_id2"}, - "bound_account_id": accountID, - "bound_iam_role_arn": iamARN, - "bound_ec2_instance_id": []string{parsedIdentityDoc.InstanceID, "i-1234567"}, - } + // store the credentials + _, err = b.HandleRequest(context.Background(), &logical.Request{ + Operation: logical.UpdateOperation, + Storage: storage, + Path: "config/client", + Data: clientConfig, + }) + if err != nil { + t.Fatal(err) + } + } - roleReq := &logical.Request{ - Operation: logical.CreateOperation, - Path: "role/" + roleName, - Storage: storage, - Data: data, - } + loginInput := map[string]interface{}{ + "pkcs7": pkcs7, + "nonce": "vault-client-nonce", + } - updateRoleExpectLoginFail := func(roleRequest, loginRequest *logical.Request) error { - resp, err := b.HandleRequest(context.Background(), roleRequest) + parsedIdentityDoc, err := b.parseIdentityDocument(context.Background(), storage, pkcs7) + if err != nil { + t.Fatal(err) + } + + // Perform the login operation with a AMI ID that is not matching + // the bound on the role. + loginRequest := &logical.Request{ + Operation: logical.UpdateOperation, + Path: "login", + Storage: storage, + Data: loginInput, + } + + // Baseline role data that should succeed permit login + data := map[string]interface{}{ + "auth_type": "ec2", + "policies": "root", + "max_ttl": "120s", + "bound_ami_id": []string{"wrong_ami_id", amiID, "wrong_ami_id2"}, + "bound_account_id": accountID, + "bound_iam_role_arn": iamARN, + "bound_ec2_instance_id": []string{parsedIdentityDoc.InstanceID, "i-1234567"}, + } + + roleReq := &logical.Request{ + Operation: logical.CreateOperation, + Path: "role/" + roleName, + Storage: storage, + Data: data, + } + + updateRoleExpectLoginFail := func(roleRequest, loginRequest *logical.Request) error { + resp, err := b.HandleRequest(context.Background(), roleRequest) + if err != nil || (resp != nil && resp.IsError()) { + return fmt.Errorf("bad: failed to create role: resp:%#v\nerr:%v", resp, err) + } + resp, err = b.HandleRequest(context.Background(), loginRequest) + if err != nil || resp == nil || (resp != nil && !resp.IsError()) { + return fmt.Errorf("bad: expected login failure: resp:%#v\nerr:%v", resp, err) + } + return nil + } + + // Test a role with the wrong AMI ID + data["bound_ami_id"] = []string{"ami-1234567", "ami-7654321"} + if err := updateRoleExpectLoginFail(roleReq, loginRequest); err != nil { + t.Fatal(err) + } + + roleReq.Operation = logical.UpdateOperation + // Place the correct AMI ID in one of the values, but make the AccountID wrong + data["bound_ami_id"] = []string{"wrong_ami_id_1", amiID, "wrong_ami_id_2"} + data["bound_account_id"] = []string{"wrong-account-id", "wrong-account-id-2"} + if err := updateRoleExpectLoginFail(roleReq, loginRequest); err != nil { + t.Fatal(err) + } + + // Place the correct AccountID in one of the values, but make the wrong IAMRoleARN + data["bound_account_id"] = []string{"wrong-account-id-1", accountID, "wrong-account-id-2"} + data["bound_iam_role_arn"] = []string{"wrong_iam_role_arn", "wrong_iam_role_arn_2"} + if err := updateRoleExpectLoginFail(roleReq, loginRequest); err != nil { + t.Fatal(err) + } + + // Place correct IAM role ARN, but incorrect instance ID + data["bound_iam_role_arn"] = []string{"wrong_iam_role_arn_1", iamARN, "wrong_iam_role_arn_2"} + data["bound_ec2_instance_id"] = "i-1234567" + if err := updateRoleExpectLoginFail(roleReq, loginRequest); err != nil { + t.Fatal(err) + } + + // Place correct instance ID, but substring of the IAM role ARN + data["bound_ec2_instance_id"] = []string{parsedIdentityDoc.InstanceID, "i-1234567"} + data["bound_iam_role_arn"] = []string{"wrong_iam_role_arn", iamARN[:len(iamARN)-2], "wrong_iam_role_arn_2"} + if err := updateRoleExpectLoginFail(roleReq, loginRequest); err != nil { + t.Fatal(err) + } + + // place a wildcard in the middle of the role ARN + // The :31 gets arn:aws:iam::123456789012:role/ + // This test relies on the role name having at least two characters + data["bound_iam_role_arn"] = []string{"wrong_iam_role_arn", fmt.Sprintf("%s*%s", iamARN[:31], iamARN[32:])} + if err := updateRoleExpectLoginFail(roleReq, loginRequest); err != nil { + t.Fatal(err) + } + + // globbed IAM role ARN + data["bound_iam_role_arn"] = []string{"wrong_iam_role_arn_1", fmt.Sprintf("%s*", iamARN[:len(iamARN)-2]), "wrong_iam_role_arn_2"} + resp, err := b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { - return fmt.Errorf("bad: failed to create role: resp:%#v\nerr:%v", resp, err) + t.Fatalf("bad: failed to create role: resp:%#v\nerr:%v", resp, err) } + + // Now, the login attempt should succeed resp, err = b.HandleRequest(context.Background(), loginRequest) - if err != nil || resp == nil || (resp != nil && !resp.IsError()) { - return fmt.Errorf("bad: expected login failure: resp:%#v\nerr:%v", resp, err) + if err != nil { + t.Fatal(err) + } + if resp == nil || resp.Auth == nil || resp.IsError() { + t.Fatalf("bad: failed to login: resp:%#v\nerr:%v", resp, err) } - return nil - } - // Test a role with the wrong AMI ID - data["bound_ami_id"] = []string{"ami-1234567", "ami-7654321"} - if err := updateRoleExpectLoginFail(roleReq, loginRequest); err != nil { - t.Fatal(err) - } + // Attempt to re-login with the identity signature + delete(loginInput, "pkcs7") + loginInput["identity"] = identityDoc + loginInput["signature"] = identityDocSig + resp, err = b.HandleRequest(context.Background(), loginRequest) + if err != nil { + t.Fatal(err) + } + if resp == nil || resp.Auth == nil || resp.IsError() { + t.Fatalf("bad: failed to login: resp:%#v\nerr:%v", resp, err) + } - roleReq.Operation = logical.UpdateOperation - // Place the correct AMI ID in one of the values, but make the AccountID wrong - data["bound_ami_id"] = []string{"wrong_ami_id_1", amiID, "wrong_ami_id_2"} - data["bound_account_id"] = []string{"wrong-account-id", "wrong-account-id-2"} - if err := updateRoleExpectLoginFail(roleReq, loginRequest); err != nil { - t.Fatal(err) - } + // verify the presence of instance_id in the response object. + instanceID := resp.Auth.Metadata["instance_id"] + if instanceID == "" { + t.Fatalf("instance ID not present in the response object") + } + if instanceID != parsedIdentityDoc.InstanceID { + t.Fatalf("instance ID in response (%q) did not match instance ID from identity document (%q)", instanceID, parsedIdentityDoc.InstanceID) + } - // Place the correct AccountID in one of the values, but make the wrong IAMRoleARN - data["bound_account_id"] = []string{"wrong-account-id-1", accountID, "wrong-account-id-2"} - data["bound_iam_role_arn"] = []string{"wrong_iam_role_arn", "wrong_iam_role_arn_2"} - if err := updateRoleExpectLoginFail(roleReq, loginRequest); err != nil { - t.Fatal(err) - } + _, ok := resp.Auth.Metadata["nonce"] + if ok { + t.Fatalf("client nonce should not have been returned") + } - // Place correct IAM role ARN, but incorrect instance ID - data["bound_iam_role_arn"] = []string{"wrong_iam_role_arn_1", iamARN, "wrong_iam_role_arn_2"} - data["bound_ec2_instance_id"] = "i-1234567" - if err := updateRoleExpectLoginFail(roleReq, loginRequest); err != nil { - t.Fatal(err) - } + loginInput["nonce"] = "changed-vault-client-nonce" + // try to login again with changed nonce + resp, err = b.HandleRequest(context.Background(), loginRequest) + if err != nil { + t.Fatal(err) + } + if resp == nil || !resp.IsError() { + t.Fatalf("login attempt should have failed due to client nonce mismatch") + } - // Place correct instance ID, but substring of the IAM role ARN - data["bound_ec2_instance_id"] = []string{parsedIdentityDoc.InstanceID, "i-1234567"} - data["bound_iam_role_arn"] = []string{"wrong_iam_role_arn", iamARN[:len(iamARN)-2], "wrong_iam_role_arn_2"} - if err := updateRoleExpectLoginFail(roleReq, loginRequest); err != nil { - t.Fatal(err) - } + // Check if a access list identity entry is created after the login. + wlRequest := &logical.Request{ + Operation: logical.ReadOperation, + Path: path + instanceID, + Storage: storage, + } + resp, err = b.HandleRequest(context.Background(), wlRequest) + if err != nil { + t.Fatal(err) + } + if resp == nil || resp.Data == nil || resp.Data["role"] != roleName { + t.Fatalf("failed to read access list identity") + } - // place a wildcard in the middle of the role ARN - // The :31 gets arn:aws:iam::123456789012:role/ - // This test relies on the role name having at least two characters - data["bound_iam_role_arn"] = []string{"wrong_iam_role_arn", fmt.Sprintf("%s*%s", iamARN[:31], iamARN[32:])} - if err := updateRoleExpectLoginFail(roleReq, loginRequest); err != nil { - t.Fatal(err) - } + // Delete the access list identity entry. + wlRequest.Operation = logical.DeleteOperation + resp, err = b.HandleRequest(context.Background(), wlRequest) + if err != nil { + t.Fatal(err) + } + if resp.IsError() { + t.Fatalf("failed to delete access list identity") + } - // globbed IAM role ARN - data["bound_iam_role_arn"] = []string{"wrong_iam_role_arn_1", fmt.Sprintf("%s*", iamARN[:len(iamARN)-2]), "wrong_iam_role_arn_2"} - resp, err := b.HandleRequest(context.Background(), roleReq) - if err != nil || (resp != nil && resp.IsError()) { - t.Fatalf("bad: failed to create role: resp:%#v\nerr:%v", resp, err) - } + // Allow a fresh login without supplying the nonce + delete(loginInput, "nonce") - // Now, the login attempt should succeed - resp, err = b.HandleRequest(context.Background(), loginRequest) - if err != nil { - t.Fatal(err) - } - if resp == nil || resp.Auth == nil || resp.IsError() { - t.Fatalf("bad: failed to login: resp:%#v\nerr:%v", resp, err) - } + resp, err = b.HandleRequest(context.Background(), loginRequest) + if err != nil { + t.Fatal(err) + } + if resp == nil || resp.Auth == nil || resp.IsError() { + t.Fatalf("login attempt failed") + } - // Attempt to re-login with the identity signature - delete(loginInput, "pkcs7") - loginInput["identity"] = identityDoc - loginInput["signature"] = identityDocSig - resp, err = b.HandleRequest(context.Background(), loginRequest) - if err != nil { - t.Fatal(err) - } - if resp == nil || resp.Auth == nil || resp.IsError() { - t.Fatalf("bad: failed to login: resp:%#v\nerr:%v", resp, err) - } - - // verify the presence of instance_id in the response object. - instanceID := resp.Auth.Metadata["instance_id"] - if instanceID == "" { - t.Fatalf("instance ID not present in the response object") - } - if instanceID != parsedIdentityDoc.InstanceID { - t.Fatalf("instance ID in response (%q) did not match instance ID from identity document (%q)", instanceID, parsedIdentityDoc.InstanceID) - } - - _, ok := resp.Auth.Metadata["nonce"] - if ok { - t.Fatalf("client nonce should not have been returned") - } - - loginInput["nonce"] = "changed-vault-client-nonce" - // try to login again with changed nonce - resp, err = b.HandleRequest(context.Background(), loginRequest) - if err != nil { - t.Fatal(err) - } - if resp == nil || !resp.IsError() { - t.Fatalf("login attempt should have failed due to client nonce mismatch") - } - - // Check if a whitelist identity entry is created after the login. - wlRequest := &logical.Request{ - Operation: logical.ReadOperation, - Path: "identity-whitelist/" + instanceID, - Storage: storage, - } - resp, err = b.HandleRequest(context.Background(), wlRequest) - if err != nil { - t.Fatal(err) - } - if resp == nil || resp.Data == nil || resp.Data["role"] != roleName { - t.Fatalf("failed to read whitelist identity") - } - - // Delete the whitelist identity entry. - wlRequest.Operation = logical.DeleteOperation - resp, err = b.HandleRequest(context.Background(), wlRequest) - if err != nil { - t.Fatal(err) - } - if resp.IsError() { - t.Fatalf("failed to delete whitelist identity") - } - - // Allow a fresh login without supplying the nonce - delete(loginInput, "nonce") - - resp, err = b.HandleRequest(context.Background(), loginRequest) - if err != nil { - t.Fatal(err) - } - if resp == nil || resp.Auth == nil || resp.IsError() { - t.Fatalf("login attempt failed") - } - - _, ok = resp.Auth.Metadata["nonce"] - if !ok { - t.Fatalf("expected nonce to be returned") + _, ok = resp.Auth.Metadata["nonce"] + if !ok { + t.Fatalf("expected nonce to be returned") + } } } diff --git a/builtin/credential/aws/path_config_tidy_identity_whitelist.go b/builtin/credential/aws/path_config_tidy_identity_accesslist.go similarity index 65% rename from builtin/credential/aws/path_config_tidy_identity_whitelist.go rename to builtin/credential/aws/path_config_tidy_identity_accesslist.go index ec942cc9ef..f09586c29c 100644 --- a/builtin/credential/aws/path_config_tidy_identity_whitelist.go +++ b/builtin/credential/aws/path_config_tidy_identity_accesslist.go @@ -9,12 +9,12 @@ import ( ) const ( - identityWhitelistConfigPath = "config/tidy/identity-whitelist" + identityAccessListConfigStorage = "config/tidy/identity-whitelist" ) -func (b *backend) pathConfigTidyIdentityWhitelist() *framework.Path { +func (b *backend) pathConfigTidyIdentityAccessList() *framework.Path { return &framework.Path{ - Pattern: fmt.Sprintf("%s$", identityWhitelistConfigPath), + Pattern: fmt.Sprintf("%s$", "config/tidy/identity-accesslist"), Fields: map[string]*framework.FieldSchema{ "safety_buffer": { Type: framework.TypeDurationSecond, @@ -25,33 +25,33 @@ expiration, before it is removed from the backend storage.`, "disable_periodic_tidy": { Type: framework.TypeBool, Default: false, - Description: "If set to 'true', disables the periodic tidying of the 'identity-whitelist/' entries.", + Description: "If set to 'true', disables the periodic tidying of the 'identity-accesslist/' entries.", }, }, - ExistenceCheck: b.pathConfigTidyIdentityWhitelistExistenceCheck, + ExistenceCheck: b.pathConfigTidyIdentityAccessListExistenceCheck, Operations: map[logical.Operation]framework.OperationHandler{ logical.CreateOperation: &framework.PathOperation{ - Callback: b.pathConfigTidyIdentityWhitelistCreateUpdate, + Callback: b.pathConfigTidyIdentityAccessListCreateUpdate, }, logical.UpdateOperation: &framework.PathOperation{ - Callback: b.pathConfigTidyIdentityWhitelistCreateUpdate, + Callback: b.pathConfigTidyIdentityAccessListCreateUpdate, }, logical.ReadOperation: &framework.PathOperation{ - Callback: b.pathConfigTidyIdentityWhitelistRead, + Callback: b.pathConfigTidyIdentityAccessListRead, }, logical.DeleteOperation: &framework.PathOperation{ - Callback: b.pathConfigTidyIdentityWhitelistDelete, + Callback: b.pathConfigTidyIdentityAccessListDelete, }, }, - HelpSynopsis: pathConfigTidyIdentityWhitelistHelpSyn, - HelpDescription: pathConfigTidyIdentityWhitelistHelpDesc, + HelpSynopsis: pathConfigTidyIdentityAccessListHelpSyn, + HelpDescription: pathConfigTidyIdentityAccessListHelpDesc, } } -func (b *backend) pathConfigTidyIdentityWhitelistExistenceCheck(ctx context.Context, req *logical.Request, data *framework.FieldData) (bool, error) { +func (b *backend) pathConfigTidyIdentityAccessListExistenceCheck(ctx context.Context, req *logical.Request, data *framework.FieldData) (bool, error) { entry, err := b.lockedConfigTidyIdentities(ctx, req.Storage) if err != nil { return false, err @@ -67,7 +67,7 @@ func (b *backend) lockedConfigTidyIdentities(ctx context.Context, s logical.Stor } func (b *backend) nonLockedConfigTidyIdentities(ctx context.Context, s logical.Storage) (*tidyWhitelistIdentityConfig, error) { - entry, err := s.Get(ctx, identityWhitelistConfigPath) + entry, err := s.Get(ctx, identityAccessListConfigStorage) if err != nil { return nil, err } @@ -82,7 +82,7 @@ func (b *backend) nonLockedConfigTidyIdentities(ctx context.Context, s logical.S return &result, nil } -func (b *backend) pathConfigTidyIdentityWhitelistCreateUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { +func (b *backend) pathConfigTidyIdentityAccessListCreateUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { b.configMutex.Lock() defer b.configMutex.Unlock() @@ -108,7 +108,7 @@ func (b *backend) pathConfigTidyIdentityWhitelistCreateUpdate(ctx context.Contex configEntry.DisablePeriodicTidy = data.Get("disable_periodic_tidy").(bool) } - entry, err := logical.StorageEntryJSON(identityWhitelistConfigPath, configEntry) + entry, err := logical.StorageEntryJSON(identityAccessListConfigStorage, configEntry) if err != nil { return nil, err } @@ -120,7 +120,7 @@ func (b *backend) pathConfigTidyIdentityWhitelistCreateUpdate(ctx context.Contex return nil, nil } -func (b *backend) pathConfigTidyIdentityWhitelistRead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { +func (b *backend) pathConfigTidyIdentityAccessListRead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { clientConfig, err := b.lockedConfigTidyIdentities(ctx, req.Storage) if err != nil { return nil, err @@ -137,11 +137,11 @@ func (b *backend) pathConfigTidyIdentityWhitelistRead(ctx context.Context, req * }, nil } -func (b *backend) pathConfigTidyIdentityWhitelistDelete(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { +func (b *backend) pathConfigTidyIdentityAccessListDelete(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { b.configMutex.Lock() defer b.configMutex.Unlock() - return nil, req.Storage.Delete(ctx, identityWhitelistConfigPath) + return nil, req.Storage.Delete(ctx, identityAccessListConfigStorage) } type tidyWhitelistIdentityConfig struct { @@ -149,11 +149,11 @@ type tidyWhitelistIdentityConfig struct { DisablePeriodicTidy bool `json:"disable_periodic_tidy"` } -const pathConfigTidyIdentityWhitelistHelpSyn = ` -Configures the periodic tidying operation of the whitelisted identity entries. +const pathConfigTidyIdentityAccessListHelpSyn = ` +Configures the periodic tidying operation of the access list identity entries. ` -const pathConfigTidyIdentityWhitelistHelpDesc = ` -By default, the expired entries in the whitelist will be attempted to be removed +const pathConfigTidyIdentityAccessListHelpDesc = ` +By default, the expired entries in the access list will be attempted to be removed periodically. This operation will look for expired items in the list and purges them. However, there is a safety buffer duration (defaults to 72h), purges the entries only if they have been persisting this duration, past its expiration time. diff --git a/builtin/credential/aws/path_config_tidy_roletag_blacklist.go b/builtin/credential/aws/path_config_tidy_roletag_denylist.go similarity index 61% rename from builtin/credential/aws/path_config_tidy_roletag_blacklist.go rename to builtin/credential/aws/path_config_tidy_roletag_denylist.go index 1511a20fdd..66e5168e7b 100644 --- a/builtin/credential/aws/path_config_tidy_roletag_blacklist.go +++ b/builtin/credential/aws/path_config_tidy_roletag_denylist.go @@ -2,19 +2,18 @@ package awsauth import ( "context" - "fmt" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/logical" ) const ( - roletagBlacklistConfigPath = "config/tidy/roletag-blacklist" + roletagDenyListConfigStorage = "config/tidy/roletag-blacklist" ) -func (b *backend) pathConfigTidyRoletagBlacklist() *framework.Path { +func (b *backend) pathConfigTidyRoletagDenyList() *framework.Path { return &framework.Path{ - Pattern: fmt.Sprintf("%s$", roletagBlacklistConfigPath), + Pattern: "config/tidy/roletag-denylist$", Fields: map[string]*framework.FieldSchema{ "safety_buffer": { Type: framework.TypeDurationSecond, @@ -27,33 +26,33 @@ Defaults to 4320h (180 days).`, "disable_periodic_tidy": { Type: framework.TypeBool, Default: false, - Description: "If set to 'true', disables the periodic tidying of blacklisted entries.", + Description: "If set to 'true', disables the periodic tidying of deny listed entries.", }, }, - ExistenceCheck: b.pathConfigTidyRoletagBlacklistExistenceCheck, + ExistenceCheck: b.pathConfigTidyRoletagDenyListExistenceCheck, Operations: map[logical.Operation]framework.OperationHandler{ logical.CreateOperation: &framework.PathOperation{ - Callback: b.pathConfigTidyRoletagBlacklistCreateUpdate, + Callback: b.pathConfigTidyRoletagDenyListCreateUpdate, }, logical.UpdateOperation: &framework.PathOperation{ - Callback: b.pathConfigTidyRoletagBlacklistCreateUpdate, + Callback: b.pathConfigTidyRoletagDenyListCreateUpdate, }, logical.ReadOperation: &framework.PathOperation{ - Callback: b.pathConfigTidyRoletagBlacklistRead, + Callback: b.pathConfigTidyRoletagDenyListRead, }, logical.DeleteOperation: &framework.PathOperation{ - Callback: b.pathConfigTidyRoletagBlacklistDelete, + Callback: b.pathConfigTidyRoletagDenyListDelete, }, }, - HelpSynopsis: pathConfigTidyRoletagBlacklistHelpSyn, - HelpDescription: pathConfigTidyRoletagBlacklistHelpDesc, + HelpSynopsis: pathConfigTidyRoletagDenyListHelpSyn, + HelpDescription: pathConfigTidyRoletagDenyListHelpDesc, } } -func (b *backend) pathConfigTidyRoletagBlacklistExistenceCheck(ctx context.Context, req *logical.Request, data *framework.FieldData) (bool, error) { +func (b *backend) pathConfigTidyRoletagDenyListExistenceCheck(ctx context.Context, req *logical.Request, data *framework.FieldData) (bool, error) { entry, err := b.lockedConfigTidyRoleTags(ctx, req.Storage) if err != nil { return false, err @@ -61,15 +60,15 @@ func (b *backend) pathConfigTidyRoletagBlacklistExistenceCheck(ctx context.Conte return entry != nil, nil } -func (b *backend) lockedConfigTidyRoleTags(ctx context.Context, s logical.Storage) (*tidyBlacklistRoleTagConfig, error) { +func (b *backend) lockedConfigTidyRoleTags(ctx context.Context, s logical.Storage) (*tidyDenyListRoleTagConfig, error) { b.configMutex.RLock() defer b.configMutex.RUnlock() return b.nonLockedConfigTidyRoleTags(ctx, s) } -func (b *backend) nonLockedConfigTidyRoleTags(ctx context.Context, s logical.Storage) (*tidyBlacklistRoleTagConfig, error) { - entry, err := s.Get(ctx, roletagBlacklistConfigPath) +func (b *backend) nonLockedConfigTidyRoleTags(ctx context.Context, s logical.Storage) (*tidyDenyListRoleTagConfig, error) { + entry, err := s.Get(ctx, roletagDenyListConfigStorage) if err != nil { return nil, err } @@ -77,7 +76,7 @@ func (b *backend) nonLockedConfigTidyRoleTags(ctx context.Context, s logical.Sto return nil, nil } - var result tidyBlacklistRoleTagConfig + var result tidyDenyListRoleTagConfig if err := entry.DecodeJSON(&result); err != nil { return nil, err } @@ -85,7 +84,7 @@ func (b *backend) nonLockedConfigTidyRoleTags(ctx context.Context, s logical.Sto return &result, nil } -func (b *backend) pathConfigTidyRoletagBlacklistCreateUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { +func (b *backend) pathConfigTidyRoletagDenyListCreateUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { b.configMutex.Lock() defer b.configMutex.Unlock() @@ -94,7 +93,7 @@ func (b *backend) pathConfigTidyRoletagBlacklistCreateUpdate(ctx context.Context return nil, err } if configEntry == nil { - configEntry = &tidyBlacklistRoleTagConfig{} + configEntry = &tidyDenyListRoleTagConfig{} } safetyBufferInt, ok := data.GetOk("safety_buffer") if ok { @@ -109,7 +108,7 @@ func (b *backend) pathConfigTidyRoletagBlacklistCreateUpdate(ctx context.Context configEntry.DisablePeriodicTidy = data.Get("disable_periodic_tidy").(bool) } - entry, err := logical.StorageEntryJSON(roletagBlacklistConfigPath, configEntry) + entry, err := logical.StorageEntryJSON(roletagDenyListConfigStorage, configEntry) if err != nil { return nil, err } @@ -121,7 +120,7 @@ func (b *backend) pathConfigTidyRoletagBlacklistCreateUpdate(ctx context.Context return nil, nil } -func (b *backend) pathConfigTidyRoletagBlacklistRead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { +func (b *backend) pathConfigTidyRoletagDenyListRead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { clientConfig, err := b.lockedConfigTidyRoleTags(ctx, req.Storage) if err != nil { return nil, err @@ -138,23 +137,23 @@ func (b *backend) pathConfigTidyRoletagBlacklistRead(ctx context.Context, req *l }, nil } -func (b *backend) pathConfigTidyRoletagBlacklistDelete(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { +func (b *backend) pathConfigTidyRoletagDenyListDelete(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { b.configMutex.Lock() defer b.configMutex.Unlock() - return nil, req.Storage.Delete(ctx, roletagBlacklistConfigPath) + return nil, req.Storage.Delete(ctx, roletagDenyListConfigStorage) } -type tidyBlacklistRoleTagConfig struct { +type tidyDenyListRoleTagConfig struct { SafetyBuffer int `json:"safety_buffer"` DisablePeriodicTidy bool `json:"disable_periodic_tidy"` } -const pathConfigTidyRoletagBlacklistHelpSyn = ` -Configures the periodic tidying operation of the blacklisted role tag entries. +const pathConfigTidyRoletagDenyListHelpSyn = ` +Configures the periodic tidying operation of the deny listed role tag entries. ` -const pathConfigTidyRoletagBlacklistHelpDesc = ` -By default, the expired entries in the blacklist will be attempted to be removed +const pathConfigTidyRoletagDenyListHelpDesc = ` +By default, the expired entries in the deny list will be attempted to be removed periodically. This operation will look for expired items in the list and purges them. However, there is a safety buffer duration (defaults to 72h), purges the entries only if they have been persisting this duration, past its expiration time. diff --git a/builtin/credential/aws/path_identity_whitelist.go b/builtin/credential/aws/path_identity_accesslist.go similarity index 51% rename from builtin/credential/aws/path_identity_whitelist.go rename to builtin/credential/aws/path_identity_accesslist.go index dc77c27483..a622b7d8f9 100644 --- a/builtin/credential/aws/path_identity_whitelist.go +++ b/builtin/credential/aws/path_identity_accesslist.go @@ -8,59 +8,61 @@ import ( "github.com/hashicorp/vault/sdk/logical" ) -func (b *backend) pathIdentityWhitelist() *framework.Path { +const identityAccessListStorage = "whitelist/identity/" + +func (b *backend) pathIdentityAccessList() *framework.Path { return &framework.Path{ - Pattern: "identity-whitelist/" + framework.GenericNameRegex("instance_id"), + Pattern: "identity-accesslist/" + framework.GenericNameRegex("instance_id"), Fields: map[string]*framework.FieldSchema{ "instance_id": { Type: framework.TypeString, Description: `EC2 instance ID. A successful login operation from an EC2 instance -gets cached in this whitelist, keyed off of instance ID.`, +gets cached in this accesslist, keyed off of instance ID.`, }, }, Operations: map[logical.Operation]framework.OperationHandler{ logical.ReadOperation: &framework.PathOperation{ - Callback: b.pathIdentityWhitelistRead, + Callback: b.pathIdentityAccesslistRead, }, logical.DeleteOperation: &framework.PathOperation{ - Callback: b.pathIdentityWhitelistDelete, + Callback: b.pathIdentityAccesslistDelete, }, }, - HelpSynopsis: pathIdentityWhitelistSyn, - HelpDescription: pathIdentityWhitelistDesc, + HelpSynopsis: pathIdentityAccessListSyn, + HelpDescription: pathIdentityAccessListDesc, } } -func (b *backend) pathListIdentityWhitelist() *framework.Path { +func (b *backend) pathListIdentityAccessList() *framework.Path { return &framework.Path{ - Pattern: "identity-whitelist/?", + Pattern: "identity-accesslist/?", Operations: map[logical.Operation]framework.OperationHandler{ logical.ListOperation: &framework.PathOperation{ - Callback: b.pathWhitelistIdentitiesList, + Callback: b.pathAccessListIdentitiesList, }, }, - HelpSynopsis: pathListIdentityWhitelistHelpSyn, - HelpDescription: pathListIdentityWhitelistHelpDesc, + HelpSynopsis: pathListIdentityAccessListHelpSyn, + HelpDescription: pathListIdentityAccessListHelpDesc, } } -// pathWhitelistIdentitiesList is used to list all the instance IDs that are present -// in the identity whitelist. This will list both valid and expired entries. -func (b *backend) pathWhitelistIdentitiesList(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - identities, err := req.Storage.List(ctx, "whitelist/identity/") +// pathAccessListIdentitiesList is used to list all the instance IDs that are present +// in the identity access list. This will list both valid and expired entries. +func (b *backend) pathAccessListIdentitiesList(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { + identities, err := req.Storage.List(ctx, identityAccessListStorage) if err != nil { return nil, err } return logical.ListResponse(identities), nil } -// Fetch an item from the whitelist given an instance ID. -func whitelistIdentityEntry(ctx context.Context, s logical.Storage, instanceID string) (*whitelistIdentity, error) { - entry, err := s.Get(ctx, "whitelist/identity/"+instanceID) +// Fetch an item from the access list given an instance ID. +func accessListIdentityEntry(ctx context.Context, s logical.Storage, instanceID string) (*accessListIdentity, error) { + entry, err := s.Get(ctx, identityAccessListStorage+instanceID) if err != nil { return nil, err } @@ -68,7 +70,7 @@ func whitelistIdentityEntry(ctx context.Context, s logical.Storage, instanceID s return nil, nil } - var result whitelistIdentity + var result accessListIdentity if err := entry.DecodeJSON(&result); err != nil { return nil, err } @@ -77,8 +79,8 @@ func whitelistIdentityEntry(ctx context.Context, s logical.Storage, instanceID s // Stores an instance ID and the information required to validate further login/renewal attempts from // the same instance ID. -func setWhitelistIdentityEntry(ctx context.Context, s logical.Storage, instanceID string, identity *whitelistIdentity) error { - entry, err := logical.StorageEntryJSON("whitelist/identity/"+instanceID, identity) +func setAccessListIdentityEntry(ctx context.Context, s logical.Storage, instanceID string, identity *accessListIdentity) error { + entry, err := logical.StorageEntryJSON(identityAccessListStorage+instanceID, identity) if err != nil { return err } @@ -89,24 +91,24 @@ func setWhitelistIdentityEntry(ctx context.Context, s logical.Storage, instanceI return nil } -// pathIdentityWhitelistDelete is used to delete an entry from the identity whitelist given an instance ID. -func (b *backend) pathIdentityWhitelistDelete(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { +// pathIdentityAccesslistDelete is used to delete an entry from the identity access list given an instance ID. +func (b *backend) pathIdentityAccesslistDelete(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { instanceID := data.Get("instance_id").(string) if instanceID == "" { return logical.ErrorResponse("missing instance_id"), nil } - return nil, req.Storage.Delete(ctx, "whitelist/identity/"+instanceID) + return nil, req.Storage.Delete(ctx, identityAccessListStorage+instanceID) } -// pathIdentityWhitelistRead is used to view an entry in the identity whitelist given an instance ID. -func (b *backend) pathIdentityWhitelistRead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { +// pathIdentityAccesslistRead is used to view an entry in the identity access list given an instance ID. +func (b *backend) pathIdentityAccesslistRead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { instanceID := data.Get("instance_id").(string) if instanceID == "" { return logical.ErrorResponse("missing instance_id"), nil } - entry, err := whitelistIdentityEntry(ctx, req.Storage, instanceID) + entry, err := accessListIdentityEntry(ctx, req.Storage, instanceID) if err != nil { return nil, err } @@ -127,8 +129,8 @@ func (b *backend) pathIdentityWhitelistRead(ctx context.Context, req *logical.Re }, nil } -// Struct to represent each item in the identity whitelist. -type whitelistIdentity struct { +// Struct to represent each item in the identity access list. +type accessListIdentity struct { Role string `json:"role"` ClientNonce string `json:"client_nonce"` CreationTime time.Time `json:"creation_time"` @@ -138,28 +140,28 @@ type whitelistIdentity struct { LastUpdatedTime time.Time `json:"last_updated_time"` } -const pathIdentityWhitelistSyn = ` -Read or delete entries in the identity whitelist. +const pathIdentityAccessListSyn = ` +Read or delete entries in the identity access list. ` -const pathIdentityWhitelistDesc = ` -Each login from an EC2 instance creates/updates an entry in the identity whitelist. +const pathIdentityAccessListDesc = ` +Each login from an EC2 instance creates/updates an entry in the identity access list. Entries in this list can be viewed or deleted using this endpoint. -By default, a cron task will periodically look for expired entries in the whitelist +By default, a cron task will periodically look for expired entries in the access list and deletes them. The duration to periodically run this, is one hour by default. However, this can be configured using the 'config/tidy/identities' endpoint. This tidy action can be triggered via the API as well, using the 'tidy/identities' endpoint. ` -const pathListIdentityWhitelistHelpSyn = ` -Lists the items present in the identity whitelist. +const pathListIdentityAccessListHelpSyn = ` +Lists the items present in the identity access list. ` -const pathListIdentityWhitelistHelpDesc = ` -The entries in the identity whitelist is keyed off of the EC2 instance IDs. -This endpoint lists all the entries present in the identity whitelist, both +const pathListIdentityAccessListHelpDesc = ` +The entries in the identity access list is keyed off of the EC2 instance IDs. +This endpoint lists all the entries present in the identity access list, both expired and un-expired entries. Use 'tidy/identities' endpoint to clean-up -the whitelist of identities. +the access list of identities. ` diff --git a/builtin/credential/aws/path_login.go b/builtin/credential/aws/path_login.go index e030c3faae..499c734aeb 100644 --- a/builtin/credential/aws/path_login.go +++ b/builtin/credential/aws/path_login.go @@ -72,7 +72,7 @@ of ec2.`, Description: `The nonce to be used for subsequent login requests when auth_type is ec2. If this parameter is not specified at all and if reauthentication is allowed, then the backend will generate a random -nonce, attaches it to the instance's identity-whitelist entry and returns the +nonce, attaches it to the instance's identity access list entry and returns the nonce back as part of auth metadata. This value should be used with further login requests, to establish client authenticity. Clients can choose to set a custom nonce if preferred, in which case, it is recommended that clients provide @@ -211,9 +211,9 @@ func (b *backend) validateInstance(ctx context.Context, s logical.Storage, insta } // validateMetadata matches the given client nonce and pending time with the -// one cached in the identity whitelist during the previous login. But, if +// one cached in the identity access list during the previous login. But, if // reauthentication is disabled, login attempt is failed immediately. -func validateMetadata(clientNonce, pendingTime string, storedIdentity *whitelistIdentity, roleEntry *awsRoleEntry) error { +func validateMetadata(clientNonce, pendingTime string, storedIdentity *accessListIdentity, roleEntry *awsRoleEntry) error { // For sanity if !storedIdentity.DisallowReauthentication && storedIdentity.ClientNonce == "" { return fmt.Errorf("client nonce missing in stored identity") @@ -243,7 +243,7 @@ func validateMetadata(clientNonce, pendingTime string, storedIdentity *whitelist // pendingTime in the instance metadata, which sadly is only updated // when an instance is stopped and started but *not* when the instance // is rebooted. If reboot survivability is needed, either - // instrumentation to delete the instance ID from the whitelist is + // instrumentation to delete the instance ID from the access list is // necessary, or the client must durably store the nonce. // // If the `allow_instance_migration` property of the registered role is @@ -686,14 +686,14 @@ func (b *backend) pathLoginUpdateEc2(ctx context.Context, req *logical.Request, return logical.ErrorResponse(fmt.Sprintf("Error validating instance: %v", validationError)), nil } - // Get the entry from the identity whitelist, if there is one - storedIdentity, err := whitelistIdentityEntry(ctx, req.Storage, identityDocParsed.InstanceID) + // Get the entry from the identity access list, if there is one + storedIdentity, err := accessListIdentityEntry(ctx, req.Storage, identityDocParsed.InstanceID) if err != nil { return nil, err } // disallowReauthentication value that gets cached at the stored - // identity-whitelist entry is determined not just by the role entry. + // identity access list entry is determined not just by the role entry. // If client explicitly sets nonce to be empty, it implies intent to // disable reauthentication. Also, role tag can override the 'false' // value with 'true' (the other way around is not allowed). @@ -714,7 +714,7 @@ func (b *backend) pathLoginUpdateEc2(ctx context.Context, req *logical.Request, if clientNonce == "" { clientNonce = reauthenticationDisabledNonce - // Ensure that the intent lands in the whitelist + // Ensure that the intent lands in the access list disallowReauthentication = true } } @@ -735,7 +735,7 @@ func (b *backend) pathLoginUpdateEc2(ctx context.Context, req *logical.Request, // to 'false', a role-tag login sets the value to 'true', then // role gets updated to not use a role-tag, and a login attempt // is made with role's value set to 'false'. Removing the entry - // from the identity-whitelist should be the only way to be + // from the identity access list should be the only way to be // able to login from the instance again. disallowReauthentication = disallowReauthentication || storedIdentity.DisallowReauthentication } @@ -753,7 +753,7 @@ func (b *backend) pathLoginUpdateEc2(ctx context.Context, req *logical.Request, // Load the current values for max TTL and policies from the role entry, // before checking for overriding max TTL in the role tag. The shortest // max TTL is used to cap the token TTL; the longest max TTL is used to - // make the whitelist entry as long as possible as it controls for replay + // make the access list entry as long as possible as it controls for replay // attacks. shortestMaxTTL := b.System().MaxLeaseTTL() longestMaxTTL := b.System().MaxLeaseTTL() @@ -807,12 +807,12 @@ func (b *backend) pathLoginUpdateEc2(ctx context.Context, req *logical.Request, } } - // Save the login attempt in the identity whitelist + // Save the login attempt in the identity access list currentTime := time.Now() if storedIdentity == nil { // Role, ClientNonce and CreationTime of the identity entry, // once set, should never change. - storedIdentity = &whitelistIdentity{ + storedIdentity = &accessListIdentity{ Role: roleName, ClientNonce: clientNonce, CreationTime: currentTime, @@ -836,7 +836,7 @@ func (b *backend) pathLoginUpdateEc2(ctx context.Context, req *logical.Request, return logical.ErrorResponse("client nonce exceeding the limit of 128 characters"), nil } - if err = setWhitelistIdentityEntry(ctx, req.Storage, identityDocParsed.InstanceID, storedIdentity); err != nil { + if err = setAccessListIdentityEntry(ctx, req.Storage, identityDocParsed.InstanceID, storedIdentity); err != nil { return nil, err } @@ -935,13 +935,13 @@ func (b *backend) handleRoleTagLogin(ctx context.Context, s logical.Storage, rol return nil, fmt.Errorf("role tag is being used by an unauthorized instance") } - // Check if the role tag is blacklisted - blacklistEntry, err := b.lockedBlacklistRoleTagEntry(ctx, s, rTagValue) + // Check if the role tag is deny listed + denyListEntry, err := b.lockedDenyLististRoleTagEntry(ctx, s, rTagValue) if err != nil { return nil, err } - if blacklistEntry != nil { - return nil, fmt.Errorf("role tag is blacklisted") + if denyListEntry != nil { + return nil, fmt.Errorf("role tag is deny listed") } // Ensure that the policies on the RoleTag is a subset of policies on the role @@ -1108,12 +1108,12 @@ func (b *backend) pathLoginRenewEc2(ctx context.Context, req *logical.Request, _ return nil, errwrap.Wrapf(fmt.Sprintf("failed to verify instance ID %q: {{err}}", instanceID), err) } - storedIdentity, err := whitelistIdentityEntry(ctx, req.Storage, instanceID) + storedIdentity, err := accessListIdentityEntry(ctx, req.Storage, instanceID) if err != nil { return nil, err } if storedIdentity == nil { - return nil, fmt.Errorf("failed to verify the whitelist identity entry for instance ID: %q", instanceID) + return nil, fmt.Errorf("failed to verify the access list identity entry for instance ID: %q", instanceID) } // Ensure that role entry is not deleted @@ -1155,8 +1155,8 @@ func (b *backend) pathLoginRenewEc2(ctx context.Context, req *logical.Request, _ storedIdentity.ExpirationTime = currentTime.Add(longestMaxTTL) // Updating the expiration time is required for the tidy operation on the - // whitelist identity storage items - if err = setWhitelistIdentityEntry(ctx, req.Storage, instanceID, storedIdentity); err != nil { + // access list identity storage items + if err = setAccessListIdentityEntry(ctx, req.Storage, instanceID, storedIdentity); err != nil { return nil, err } @@ -1818,11 +1818,11 @@ document and a client created nonce. This nonce should be unique and should be u the instance for all future logins, unless 'disallow_reauthentication' option on the registered role is enabled, in which case client nonce is optional. -First login attempt, creates a whitelist entry in Vault associating the instance to the nonce +First login attempt, creates a access list entry in Vault associating the instance to the nonce provided. All future logins will succeed only if the client nonce matches the nonce in the -whitelisted entry. +access list entry. -By default, a cron task will periodically look for expired entries in the whitelist +By default, a cron task will periodically look for expired entries in the access list and deletes them. The duration to periodically run this, is one hour by default. However, this can be configured using the 'config/tidy/identities' endpoint. This tidy action can be triggered via the API as well, using the 'tidy/identities' endpoint. diff --git a/builtin/credential/aws/path_role.go b/builtin/credential/aws/path_role.go index f1f71e1ce8..d439402a3e 100644 --- a/builtin/credential/aws/path_role.go +++ b/builtin/credential/aws/path_role.go @@ -166,9 +166,9 @@ auth_type is ec2.`, Type: framework.TypeBool, Default: false, Description: `If set, only allows a single token to be granted per - instance ID. In order to perform a fresh login, the entry in whitelist + instance ID. In order to perform a fresh login, the entry in the access list for the instance ID needs to be cleared using - 'auth/aws-ec2/identity-whitelist/' endpoint. This is only + 'auth/aws-ec2/identity-accesslist/' endpoint. This is only applicable when auth_type is ec2.`, }, }, diff --git a/builtin/credential/aws/path_role_tag.go b/builtin/credential/aws/path_role_tag.go index 7d10e8f854..f201c3ef71 100644 --- a/builtin/credential/aws/path_role_tag.go +++ b/builtin/credential/aws/path_role_tag.go @@ -55,7 +55,7 @@ If set, the created tag can only be used by the instance with the given ID.`, "disallow_reauthentication": { Type: framework.TypeBool, Default: false, - Description: "If set, only allows a single token to be granted per instance ID. In order to perform a fresh login, the entry in whitelist for the instance ID needs to be cleared using the 'auth/aws-ec2/identity-whitelist/' endpoint.", + Description: "If set, only allows a single token to be granted per instance ID. In order to perform a fresh login, the entry in access list for the instance ID needs to be cleared using the 'auth/aws-ec2/identity-accesslist/' endpoint.", }, }, diff --git a/builtin/credential/aws/path_roletag_blacklist.go b/builtin/credential/aws/path_roletag_denylist.go similarity index 61% rename from builtin/credential/aws/path_roletag_blacklist.go rename to builtin/credential/aws/path_roletag_denylist.go index 515bce2c8c..19520aab2f 100644 --- a/builtin/credential/aws/path_roletag_blacklist.go +++ b/builtin/credential/aws/path_roletag_denylist.go @@ -9,26 +9,26 @@ import ( "github.com/hashicorp/vault/sdk/logical" ) -func (b *backend) pathRoletagBlacklist() *framework.Path { +func (b *backend) pathRoletagDenyList() *framework.Path { return &framework.Path{ - Pattern: "roletag-blacklist/(?P.*)", + Pattern: "roletag-denylist/(?P.*)", Fields: map[string]*framework.FieldSchema{ "role_tag": { Type: framework.TypeString, - Description: `Role tag to be blacklisted. The tag can be supplied as-is. In order + Description: `Role tag to be deny listed. The tag can be supplied as-is. In order to avoid any encoding problems, it can be base64 encoded.`, }, }, Operations: map[logical.Operation]framework.OperationHandler{ logical.UpdateOperation: &framework.PathOperation{ - Callback: b.pathRoletagBlacklistUpdate, + Callback: b.pathRoletagDenyListUpdate, }, logical.ReadOperation: &framework.PathOperation{ - Callback: b.pathRoletagBlacklistRead, + Callback: b.pathRoletagDenyListRead, }, logical.DeleteOperation: &framework.PathOperation{ - Callback: b.pathRoletagBlacklistDelete, + Callback: b.pathRoletagDenyListDelete, }, }, @@ -37,28 +37,28 @@ to avoid any encoding problems, it can be base64 encoded.`, } } -// Path to list all the blacklisted tags. -func (b *backend) pathListRoletagBlacklist() *framework.Path { +// Path to list all the deny listed tags. +func (b *backend) pathListRoletagDenyList() *framework.Path { return &framework.Path{ - Pattern: "roletag-blacklist/?", + Pattern: "roletag-denylist/?", Operations: map[logical.Operation]framework.OperationHandler{ logical.ListOperation: &framework.PathOperation{ - Callback: b.pathRoletagBlacklistsList, + Callback: b.pathRoletagDenyListsList, }, }, - HelpSynopsis: pathListRoletagBlacklistHelpSyn, - HelpDescription: pathListRoletagBlacklistHelpDesc, + HelpSynopsis: pathListRoletagDenyListHelpSyn, + HelpDescription: pathListRoletagDenyListHelpDesc, } } -// Lists all the blacklisted role tags. -func (b *backend) pathRoletagBlacklistsList(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - b.blacklistMutex.RLock() - defer b.blacklistMutex.RUnlock() +// Lists all the deny listed role tags. +func (b *backend) pathRoletagDenyListsList(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { + b.denyListMutex.RLock() + defer b.denyListMutex.RUnlock() - tags, err := req.Storage.List(ctx, "blacklist/roletag/") + tags, err := req.Storage.List(ctx, denyListRoletagStorage) if err != nil { return nil, err } @@ -77,17 +77,17 @@ func (b *backend) pathRoletagBlacklistsList(ctx context.Context, req *logical.Re return logical.ListResponse(tags), nil } -// Fetch an entry from the role tag blacklist for a given tag. +// Fetch an entry from the role tag deny list for a given tag. // This method takes a role tag in its original form and not a base64 encoded form. -func (b *backend) lockedBlacklistRoleTagEntry(ctx context.Context, s logical.Storage, tag string) (*roleTagBlacklistEntry, error) { - b.blacklistMutex.RLock() - defer b.blacklistMutex.RUnlock() +func (b *backend) lockedDenyLististRoleTagEntry(ctx context.Context, s logical.Storage, tag string) (*roleTagBlacklistEntry, error) { + b.denyListMutex.RLock() + defer b.denyListMutex.RUnlock() - return b.nonLockedBlacklistRoleTagEntry(ctx, s, tag) + return b.nonLockedDenyListRoleTagEntry(ctx, s, tag) } -func (b *backend) nonLockedBlacklistRoleTagEntry(ctx context.Context, s logical.Storage, tag string) (*roleTagBlacklistEntry, error) { - entry, err := s.Get(ctx, "blacklist/roletag/"+base64.StdEncoding.EncodeToString([]byte(tag))) +func (b *backend) nonLockedDenyListRoleTagEntry(ctx context.Context, s logical.Storage, tag string) (*roleTagBlacklistEntry, error) { + entry, err := s.Get(ctx, denyListRoletagStorage+base64.StdEncoding.EncodeToString([]byte(tag))) if err != nil { return nil, err } @@ -102,28 +102,28 @@ func (b *backend) nonLockedBlacklistRoleTagEntry(ctx context.Context, s logical. return &result, nil } -// Deletes an entry from the role tag blacklist for a given tag. -func (b *backend) pathRoletagBlacklistDelete(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - b.blacklistMutex.Lock() - defer b.blacklistMutex.Unlock() +// Deletes an entry from the role tag deny list for a given tag. +func (b *backend) pathRoletagDenyListDelete(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { + b.denyListMutex.Lock() + defer b.denyListMutex.Unlock() tag := data.Get("role_tag").(string) if tag == "" { return logical.ErrorResponse("missing role_tag"), nil } - return nil, req.Storage.Delete(ctx, "blacklist/roletag/"+base64.StdEncoding.EncodeToString([]byte(tag))) + return nil, req.Storage.Delete(ctx, denyListRoletagStorage+base64.StdEncoding.EncodeToString([]byte(tag))) } -// If the given role tag is blacklisted, returns the details of the blacklist entry. +// If the given role tag is deny listed, returns the details of the deny list entry. // Returns 'nil' otherwise. -func (b *backend) pathRoletagBlacklistRead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { +func (b *backend) pathRoletagDenyListRead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { tag := data.Get("role_tag").(string) if tag == "" { return logical.ErrorResponse("missing role_tag"), nil } - entry, err := b.lockedBlacklistRoleTagEntry(ctx, req.Storage, tag) + entry, err := b.lockedDenyLististRoleTagEntry(ctx, req.Storage, tag) if err != nil { return nil, err } @@ -139,10 +139,10 @@ func (b *backend) pathRoletagBlacklistRead(ctx context.Context, req *logical.Req }, nil } -// pathRoletagBlacklistUpdate is used to blacklist a given role tag. -// Before a role tag is blacklisted, the correctness of the plaintext part +// pathRoletagDenyListUpdate is used to deny list a given role tag. +// Before a role tag is added to the deny list, the correctness of the plaintext part // in the role tag is verified using the associated HMAC. -func (b *backend) pathRoletagBlacklistUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { +func (b *backend) pathRoletagDenyListUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { // The role_tag value provided, optionally can be base64 encoded. tagInput := data.Get("role_tag").(string) if tagInput == "" { @@ -179,11 +179,11 @@ func (b *backend) pathRoletagBlacklistUpdate(ctx context.Context, req *logical.R return logical.ErrorResponse("role entry not found"), nil } - b.blacklistMutex.Lock() - defer b.blacklistMutex.Unlock() + b.denyListMutex.Lock() + defer b.denyListMutex.Unlock() - // Check if the role tag is already blacklisted. If yes, update it. - blEntry, err := b.nonLockedBlacklistRoleTagEntry(ctx, req.Storage, tag) + // Check if the role tag is already deny listed. If yes, update it. + blEntry, err := b.nonLockedDenyListRoleTagEntry(ctx, req.Storage, tag) if err != nil { return nil, err } @@ -193,11 +193,11 @@ func (b *backend) pathRoletagBlacklistUpdate(ctx context.Context, req *logical.R currentTime := time.Now() - // Check if this is a creation of blacklist entry. + // Check if this is a creation of deny list entry. if blEntry.CreationTime.IsZero() { - // Set the creation time for the blacklist entry. + // Set the creation time for the deny list entry. // This should not be updated after setting it once. - // If blacklist operation is invoked more than once, only update the expiration time. + // If deny list operation is invoked more than once, only update the expiration time. blEntry.CreationTime = currentTime } @@ -213,12 +213,12 @@ func (b *backend) pathRoletagBlacklistUpdate(ctx context.Context, req *logical.R blEntry.ExpirationTime = currentTime.Add(maxDur) - entry, err := logical.StorageEntryJSON("blacklist/roletag/"+base64.StdEncoding.EncodeToString([]byte(tag)), blEntry) + entry, err := logical.StorageEntryJSON(denyListRoletagStorage+base64.StdEncoding.EncodeToString([]byte(tag)), blEntry) if err != nil { return nil, err } - // Store the blacklist entry. + // Store the deny list entry. if err := req.Storage.Put(ctx, entry); err != nil { return nil, err } @@ -236,25 +236,25 @@ Blacklist a previously created role tag. ` const pathRoletagBlacklistDesc = ` -Blacklist a role tag so that it cannot be used by any EC2 instance to perform further +Add a role tag to the deny list so that it cannot be used by any EC2 instance to perform further logins. This can be used if the role tag is suspected or believed to be possessed by an unintended party. -By default, a cron task will periodically look for expired entries in the blacklist +By default, a cron task will periodically look for expired entries in the deny list and deletes them. The duration to periodically run this, is one hour by default. However, this can be configured using the 'config/tidy/roletags' endpoint. This tidy action can be triggered via the API as well, using the 'tidy/roletags' endpoint. Also note that delete operation is supported on this endpoint to remove specific -entries from the blacklist. +entries from the deny list. ` -const pathListRoletagBlacklistHelpSyn = ` -Lists the blacklisted role tags. +const pathListRoletagDenyListHelpSyn = ` +Lists the deny list role tags. ` -const pathListRoletagBlacklistHelpDesc = ` -Lists all the entries present in the blacklist. This will show both the valid -entries and the expired entries in the blacklist. Use 'tidy/roletags' endpoint -to clean-up the blacklist of role tags based on expiration time. +const pathListRoletagDenyListHelpDesc = ` +Lists all the entries present in the deny list. This will show both the valid +entries and the expired entries in the deny list. Use 'tidy/roletags' endpoint +to clean-up the deny list of role tags based on expiration time. ` diff --git a/builtin/credential/aws/path_tidy_identity_whitelist.go b/builtin/credential/aws/path_tidy_identity_accesslist.go similarity index 65% rename from builtin/credential/aws/path_tidy_identity_whitelist.go rename to builtin/credential/aws/path_tidy_identity_accesslist.go index b62d425e37..4e5592ce67 100644 --- a/builtin/credential/aws/path_tidy_identity_whitelist.go +++ b/builtin/credential/aws/path_tidy_identity_accesslist.go @@ -13,9 +13,9 @@ import ( "github.com/hashicorp/vault/sdk/logical" ) -func (b *backend) pathTidyIdentityWhitelist() *framework.Path { +func (b *backend) pathTidyIdentityAccessList() *framework.Path { return &framework.Path{ - Pattern: "tidy/identity-whitelist$", + Pattern: "tidy/identity-accesslist$", Fields: map[string]*framework.FieldSchema{ "safety_buffer": { Type: framework.TypeDurationSecond, @@ -27,23 +27,23 @@ expiration, before it is removed from the backend storage.`, Operations: map[logical.Operation]framework.OperationHandler{ logical.UpdateOperation: &framework.PathOperation{ - Callback: b.pathTidyIdentityWhitelistUpdate, + Callback: b.pathTidyIdentityAccessListUpdate, }, }, - HelpSynopsis: pathTidyIdentityWhitelistSyn, - HelpDescription: pathTidyIdentityWhitelistDesc, + HelpSynopsis: pathTidyIdentityAccessListSyn, + HelpDescription: pathTidyIdentityAccessListDesc, } } -// tidyWhitelistIdentity is used to delete entries in the whitelist that are expired. -func (b *backend) tidyWhitelistIdentity(ctx context.Context, req *logical.Request, safetyBuffer int) (*logical.Response, error) { +// tidyAccessListIdentity is used to delete entries in the access list that are expired. +func (b *backend) tidyAccessListIdentity(ctx context.Context, req *logical.Request, safetyBuffer int) (*logical.Response, error) { // If we are a performance standby forward the request to the active node if b.System().ReplicationState().HasState(consts.ReplicationPerformanceStandby) { return nil, logical.ErrReadOnly } - if !atomic.CompareAndSwapUint32(b.tidyWhitelistCASGuard, 0, 1) { + if !atomic.CompareAndSwapUint32(b.tidyAccessListCASGuard, 0, 1) { resp := &logical.Response{} resp.AddWarning("Tidy operation already in progress.") return resp, nil @@ -52,7 +52,7 @@ func (b *backend) tidyWhitelistIdentity(ctx context.Context, req *logical.Reques s := req.Storage go func() { - defer atomic.StoreUint32(b.tidyWhitelistCASGuard, 0) + defer atomic.StoreUint32(b.tidyAccessListCASGuard, 0) // Don't cancel when the original client request goes away ctx = context.Background() @@ -62,13 +62,13 @@ func (b *backend) tidyWhitelistIdentity(ctx context.Context, req *logical.Reques bufferDuration := time.Duration(safetyBuffer) * time.Second doTidy := func() error { - identities, err := s.List(ctx, "whitelist/identity/") + identities, err := s.List(ctx, identityAccessListStorage) if err != nil { return err } for _, instanceID := range identities { - identityEntry, err := s.Get(ctx, "whitelist/identity/"+instanceID) + identityEntry, err := s.Get(ctx, identityAccessListStorage+instanceID) if err != nil { return errwrap.Wrapf(fmt.Sprintf("error fetching identity of instanceID %q: {{err}}", instanceID), err) } @@ -81,13 +81,13 @@ func (b *backend) tidyWhitelistIdentity(ctx context.Context, req *logical.Reques return fmt.Errorf("found identity entry for instanceID %q but actual identity is empty", instanceID) } - var result whitelistIdentity + var result accessListIdentity if err := identityEntry.DecodeJSON(&result); err != nil { return err } if time.Now().After(result.ExpirationTime.Add(bufferDuration)) { - if err := s.Delete(ctx, "whitelist/identity/"+instanceID); err != nil { + if err := s.Delete(ctx, identityAccessListStorage+instanceID); err != nil { return errwrap.Wrapf(fmt.Sprintf("error deleting identity of instanceID %q from storage: {{err}}", instanceID), err) } } @@ -97,7 +97,7 @@ func (b *backend) tidyWhitelistIdentity(ctx context.Context, req *logical.Reques } if err := doTidy(); err != nil { - logger.Error("error running whitelist tidy", "error", err) + logger.Error("error running access list tidy", "error", err) return } }() @@ -107,17 +107,17 @@ func (b *backend) tidyWhitelistIdentity(ctx context.Context, req *logical.Reques return logical.RespondWithStatusCode(resp, req, http.StatusAccepted) } -// pathTidyIdentityWhitelistUpdate is used to delete entries in the whitelist that are expired. -func (b *backend) pathTidyIdentityWhitelistUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - return b.tidyWhitelistIdentity(ctx, req, data.Get("safety_buffer").(int)) +// pathTidyIdentityAccessListUpdate is used to delete entries in the access list that are expired. +func (b *backend) pathTidyIdentityAccessListUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { + return b.tidyAccessListIdentity(ctx, req, data.Get("safety_buffer").(int)) } -const pathTidyIdentityWhitelistSyn = ` -Clean-up the whitelist instance identity entries. +const pathTidyIdentityAccessListSyn = ` +Clean-up the access list instance identity entries. ` -const pathTidyIdentityWhitelistDesc = ` -When an instance identity is whitelisted, the expiration time of the whitelist +const pathTidyIdentityAccessListDesc = ` +When an instance identity is in the access list, the expiration time of the access list entry is set based on the maximum 'max_ttl' value set on: the role, the role tag and the backend's mount. diff --git a/builtin/credential/aws/path_tidy_roletag_blacklist.go b/builtin/credential/aws/path_tidy_roletag_denylist.go similarity index 65% rename from builtin/credential/aws/path_tidy_roletag_blacklist.go rename to builtin/credential/aws/path_tidy_roletag_denylist.go index d77a8ea05f..69389cbb0f 100644 --- a/builtin/credential/aws/path_tidy_roletag_blacklist.go +++ b/builtin/credential/aws/path_tidy_roletag_denylist.go @@ -13,9 +13,13 @@ import ( "github.com/hashicorp/vault/sdk/logical" ) -func (b *backend) pathTidyRoletagBlacklist() *framework.Path { +const ( + denyListRoletagStorage = "blacklist/roletag/" +) + +func (b *backend) pathTidyRoletagDenyList() *framework.Path { return &framework.Path{ - Pattern: "tidy/roletag-blacklist$", + Pattern: "tidy/roletag-denylist$", Fields: map[string]*framework.FieldSchema{ "safety_buffer": { Type: framework.TypeDurationSecond, @@ -27,23 +31,23 @@ expiration, before it is removed from the backend storage.`, Operations: map[logical.Operation]framework.OperationHandler{ logical.UpdateOperation: &framework.PathOperation{ - Callback: b.pathTidyRoletagBlacklistUpdate, + Callback: b.pathTidyRoletagDenylistUpdate, }, }, - HelpSynopsis: pathTidyRoletagBlacklistSyn, - HelpDescription: pathTidyRoletagBlacklistDesc, + HelpSynopsis: pathTidyRoletagDenylistSyn, + HelpDescription: pathTidyRoletagDenylistDesc, } } -// tidyBlacklistRoleTag is used to clean-up the entries in the role tag blacklist. -func (b *backend) tidyBlacklistRoleTag(ctx context.Context, req *logical.Request, safetyBuffer int) (*logical.Response, error) { +// tidyDenyListRoleTag is used to clean-up the entries in the role tag deny list. +func (b *backend) tidyDenyListRoleTag(ctx context.Context, req *logical.Request, safetyBuffer int) (*logical.Response, error) { // If we are a performance standby forward the request to the active node if b.System().ReplicationState().HasState(consts.ReplicationPerformanceStandby) { return nil, logical.ErrReadOnly } - if !atomic.CompareAndSwapUint32(b.tidyBlacklistCASGuard, 0, 1) { + if !atomic.CompareAndSwapUint32(b.tidyDenyListCASGuard, 0, 1) { resp := &logical.Response{} resp.AddWarning("Tidy operation already in progress.") return resp, nil @@ -52,7 +56,7 @@ func (b *backend) tidyBlacklistRoleTag(ctx context.Context, req *logical.Request s := req.Storage go func() { - defer atomic.StoreUint32(b.tidyBlacklistCASGuard, 0) + defer atomic.StoreUint32(b.tidyDenyListCASGuard, 0) // Don't cancel when the original client request goes away ctx = context.Background() @@ -62,13 +66,13 @@ func (b *backend) tidyBlacklistRoleTag(ctx context.Context, req *logical.Request bufferDuration := time.Duration(safetyBuffer) * time.Second doTidy := func() error { - tags, err := s.List(ctx, "blacklist/roletag/") + tags, err := s.List(ctx, denyListRoletagStorage) if err != nil { return err } for _, tag := range tags { - tagEntry, err := s.Get(ctx, "blacklist/roletag/"+tag) + tagEntry, err := s.Get(ctx, denyListRoletagStorage+tag) if err != nil { return errwrap.Wrapf(fmt.Sprintf("error fetching tag %q: {{err}}", tag), err) } @@ -87,7 +91,7 @@ func (b *backend) tidyBlacklistRoleTag(ctx context.Context, req *logical.Request } if time.Now().After(result.ExpirationTime.Add(bufferDuration)) { - if err := s.Delete(ctx, "blacklist/roletag/"+tag); err != nil { + if err := s.Delete(ctx, denyListRoletagStorage+tag); err != nil { return errwrap.Wrapf(fmt.Sprintf("error deleting tag %q from storage: {{err}}", tag), err) } } @@ -97,7 +101,7 @@ func (b *backend) tidyBlacklistRoleTag(ctx context.Context, req *logical.Request } if err := doTidy(); err != nil { - logger.Error("error running blacklist tidy", "error", err) + logger.Error("error running deny list tidy", "error", err) return } }() @@ -107,17 +111,17 @@ func (b *backend) tidyBlacklistRoleTag(ctx context.Context, req *logical.Request return logical.RespondWithStatusCode(resp, req, http.StatusAccepted) } -// pathTidyRoletagBlacklistUpdate is used to clean-up the entries in the role tag blacklist. -func (b *backend) pathTidyRoletagBlacklistUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - return b.tidyBlacklistRoleTag(ctx, req, data.Get("safety_buffer").(int)) +// pathTidyRoletagDenylistUpdate is used to clean-up the entries in the role tag deny list. +func (b *backend) pathTidyRoletagDenylistUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { + return b.tidyDenyListRoleTag(ctx, req, data.Get("safety_buffer").(int)) } -const pathTidyRoletagBlacklistSyn = ` -Clean-up the blacklist role tag entries. +const pathTidyRoletagDenylistSyn = ` +Clean-up the deny list role tag entries. ` -const pathTidyRoletagBlacklistDesc = ` -When a role tag is blacklisted, the expiration time of the blacklist entry is +const pathTidyRoletagDenylistDesc = ` +When a role tag is deny listed, the expiration time of the deny list entry is set based on the maximum 'max_ttl' value set on: the role, the role tag and the backend's mount. diff --git a/changelog/10997.txt b/changelog/10997.txt new file mode 100644 index 0000000000..871621c6ec --- /dev/null +++ b/changelog/10997.txt @@ -0,0 +1,13 @@ +```changelog:change +aws/auth: AWS Auth concepts and endpoints that use the "whitelist" and "blacklist" terms +have been updated to more inclusive language (e.g. `/auth/aws/identity-whitelist` has been +updated to`/auth/aws/identity-accesslist`). The legacy endpoint names have not been removed +but are considered **deprecated**. The old and new endpoints are essentially aliases, sharing +the same underlying data. The complete list of endpoint changes is available in the +[AWS Auth API docs](https://www.vaultproject.io/api-docs/auth/aws). +``` + +```changelog:deprecation +aws/auth: AWS Auth endpoints that use the "whitelist" and "blacklist" terms have been deprecated. +Refer to the CHANGES section for addition details. +``` diff --git a/ui/app/adapters/auth-config/_base.js b/ui/app/adapters/auth-config/_base.js index dce9522086..6baccc9cf7 100644 --- a/ui/app/adapters/auth-config/_base.js +++ b/ui/app/adapters/auth-config/_base.js @@ -6,6 +6,7 @@ export default ApplicationAdapter.extend({ pathForType(modelType) { // we want the last part of the path const type = modelType.split('/').pop(); + // TODO: Update endpoints from PR#10997 if (type === 'identity-whitelist' || type === 'roletag-blacklist') { return `tidy/${type}`; } diff --git a/ui/app/helpers/tabs-for-auth-section.js b/ui/app/helpers/tabs-for-auth-section.js index 84a77fd04a..7f08e0b414 100644 --- a/ui/app/helpers/tabs-for-auth-section.js +++ b/ui/app/helpers/tabs-for-auth-section.js @@ -9,12 +9,12 @@ const TABS_FOR_SETTINGS = { routeParams: ['vault.cluster.settings.auth.configure.section', 'client'], }, { - label: 'Identity Whitelist Tidy', - routeParams: ['vault.cluster.settings.auth.configure.section', 'identity-whitelist'], + label: 'Identity Allow List Tidy', + routeParams: ['vault.cluster.settings.auth.configure.section', 'identity-whitelist'], // TODO: Update endpoint from PR#10997 }, { - label: 'Role Tag Blacklist Tidy', - routeParams: ['vault.cluster.settings.auth.configure.section', 'roletag-blacklist'], + label: 'Role Tag Deny List Tidy', + routeParams: ['vault.cluster.settings.auth.configure.section', 'roletag-blacklist'], // TODO: Update endpoints from PR#10997 }, ], azure: [ diff --git a/ui/app/models/role-ssh.js b/ui/app/models/role-ssh.js index 44b201bae3..b5033fd86b 100644 --- a/ui/app/models/role-ssh.js +++ b/ui/app/models/role-ssh.js @@ -65,7 +65,8 @@ export default Model.extend({ helpText: "Username to use when one isn't specified", }), allowedUsers: attr('string', { - helpText: 'Create a whitelist of users that can use this key (e.g. `admin, dev`, use `*` to allow all.)', + helpText: + 'Create a list of users who are allowed to use this key (e.g. `admin, dev`, or use `*` to allow all.)', }), allowedUsersTemplate: attr('boolean', { helpText: diff --git a/ui/app/routes/vault/cluster/settings/auth/configure/section.js b/ui/app/routes/vault/cluster/settings/auth/configure/section.js index 7574c52025..26d47d7ff8 100644 --- a/ui/app/routes/vault/cluster/settings/auth/configure/section.js +++ b/ui/app/routes/vault/cluster/settings/auth/configure/section.js @@ -10,6 +10,7 @@ export default Route.extend(UnloadModelRoute, { pathHelp: service('path-help'), modelType(backendType, section) { + // TODO: Update endpoints from PR#10997 const MODELS = { 'aws-client': 'auth-config/aws/client', 'aws-identity-whitelist': 'auth-config/aws/identity-whitelist', diff --git a/ui/lib/core/addon/components/form-field-groups.js b/ui/lib/core/addon/components/form-field-groups.js index 3ba85b0a61..30d8f4e0f0 100644 --- a/ui/lib/core/addon/components/form-field-groups.js +++ b/ui/lib/core/addon/components/form-field-groups.js @@ -21,7 +21,7 @@ import layout from '../templates/components/form-field-groups'; * /> * ``` * - * @param [renderGroup=null] {String} - A whitelist of groups to include in the render. + * @param [renderGroup=null] {String} - An allow list of groups to include in the render. * @param model=null {DS.Model} - Model to be passed down to form-field component. If `fieldGroups` is present on the model then it will be iterated over and groups of `FormField` components will be rendered. * @param onChange=null {Func} - Handler that will get set on the `FormField` component. * diff --git a/ui/lib/core/stories/form-field-groups.md b/ui/lib/core/stories/form-field-groups.md index 94fbf46bdd..6942d4d825 100644 --- a/ui/lib/core/stories/form-field-groups.md +++ b/ui/lib/core/stories/form-field-groups.md @@ -6,7 +6,7 @@ | Param | Type | Default | Description | | --- | --- | --- | --- | -| [renderGroup] | String | | A whitelist of groups to include in the render. | +| [renderGroup] | String | | An allow list of groups to include in the render. | | model | DS.Model | | Model to be passed down to form-field component. If `fieldGroups` is present on the model then it will be iterated over and groups of `FormField` components will be rendered. | | onChange | Func | | Handler that will get set on the `FormField` component. |