1785b1bd00
* 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.
128 lines
4.1 KiB
Go
128 lines
4.1 KiB
Go
package awsauth
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"github.com/hashicorp/errwrap"
|
|
"github.com/hashicorp/vault/sdk/framework"
|
|
"github.com/hashicorp/vault/sdk/helper/consts"
|
|
"github.com/hashicorp/vault/sdk/logical"
|
|
)
|
|
|
|
func (b *backend) pathTidyIdentityAccessList() *framework.Path {
|
|
return &framework.Path{
|
|
Pattern: "tidy/identity-accesslist$",
|
|
Fields: map[string]*framework.FieldSchema{
|
|
"safety_buffer": {
|
|
Type: framework.TypeDurationSecond,
|
|
Default: 259200,
|
|
Description: `The amount of extra time that must have passed beyond the identity's
|
|
expiration, before it is removed from the backend storage.`,
|
|
},
|
|
},
|
|
|
|
Operations: map[logical.Operation]framework.OperationHandler{
|
|
logical.UpdateOperation: &framework.PathOperation{
|
|
Callback: b.pathTidyIdentityAccessListUpdate,
|
|
},
|
|
},
|
|
|
|
HelpSynopsis: pathTidyIdentityAccessListSyn,
|
|
HelpDescription: pathTidyIdentityAccessListDesc,
|
|
}
|
|
}
|
|
|
|
// 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.tidyAccessListCASGuard, 0, 1) {
|
|
resp := &logical.Response{}
|
|
resp.AddWarning("Tidy operation already in progress.")
|
|
return resp, nil
|
|
}
|
|
|
|
s := req.Storage
|
|
|
|
go func() {
|
|
defer atomic.StoreUint32(b.tidyAccessListCASGuard, 0)
|
|
|
|
// Don't cancel when the original client request goes away
|
|
ctx = context.Background()
|
|
|
|
logger := b.Logger().Named("wltidy")
|
|
|
|
bufferDuration := time.Duration(safetyBuffer) * time.Second
|
|
|
|
doTidy := func() error {
|
|
identities, err := s.List(ctx, identityAccessListStorage)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, instanceID := range identities {
|
|
identityEntry, err := s.Get(ctx, identityAccessListStorage+instanceID)
|
|
if err != nil {
|
|
return errwrap.Wrapf(fmt.Sprintf("error fetching identity of instanceID %q: {{err}}", instanceID), err)
|
|
}
|
|
|
|
if identityEntry == nil {
|
|
return fmt.Errorf("identity entry for instanceID %q is nil", instanceID)
|
|
}
|
|
|
|
if identityEntry.Value == nil || len(identityEntry.Value) == 0 {
|
|
return fmt.Errorf("found identity entry for instanceID %q but actual identity is empty", instanceID)
|
|
}
|
|
|
|
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, identityAccessListStorage+instanceID); err != nil {
|
|
return errwrap.Wrapf(fmt.Sprintf("error deleting identity of instanceID %q from storage: {{err}}", instanceID), err)
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
if err := doTidy(); err != nil {
|
|
logger.Error("error running access list tidy", "error", err)
|
|
return
|
|
}
|
|
}()
|
|
|
|
resp := &logical.Response{}
|
|
resp.AddWarning("Tidy operation successfully started. Any information from the operation will be printed to Vault's server logs.")
|
|
return logical.RespondWithStatusCode(resp, req, http.StatusAccepted)
|
|
}
|
|
|
|
// 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 pathTidyIdentityAccessListSyn = `
|
|
Clean-up the access list instance identity entries.
|
|
`
|
|
|
|
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.
|
|
|
|
When this endpoint is invoked, all the entries that are expired will be deleted.
|
|
A 'safety_buffer' (duration in seconds) can be provided, to ensure deletion of
|
|
only those entries that are expired before 'safety_buffer' seconds.
|
|
`
|