1package awsauth 2 3import ( 4 "context" 5 "time" 6 7 "github.com/hashicorp/vault/logical" 8 "github.com/hashicorp/vault/logical/framework" 9) 10 11func pathIdentityWhitelist(b *backend) *framework.Path { 12 return &framework.Path{ 13 Pattern: "identity-whitelist/" + framework.GenericNameRegex("instance_id"), 14 Fields: map[string]*framework.FieldSchema{ 15 "instance_id": &framework.FieldSchema{ 16 Type: framework.TypeString, 17 Description: `EC2 instance ID. A successful login operation from an EC2 instance 18gets cached in this whitelist, keyed off of instance ID.`, 19 }, 20 }, 21 22 Callbacks: map[logical.Operation]framework.OperationFunc{ 23 logical.ReadOperation: b.pathIdentityWhitelistRead, 24 logical.DeleteOperation: b.pathIdentityWhitelistDelete, 25 }, 26 27 HelpSynopsis: pathIdentityWhitelistSyn, 28 HelpDescription: pathIdentityWhitelistDesc, 29 } 30} 31 32func pathListIdentityWhitelist(b *backend) *framework.Path { 33 return &framework.Path{ 34 Pattern: "identity-whitelist/?", 35 36 Callbacks: map[logical.Operation]framework.OperationFunc{ 37 logical.ListOperation: b.pathWhitelistIdentitiesList, 38 }, 39 40 HelpSynopsis: pathListIdentityWhitelistHelpSyn, 41 HelpDescription: pathListIdentityWhitelistHelpDesc, 42 } 43} 44 45// pathWhitelistIdentitiesList is used to list all the instance IDs that are present 46// in the identity whitelist. This will list both valid and expired entries. 47func (b *backend) pathWhitelistIdentitiesList(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { 48 identities, err := req.Storage.List(ctx, "whitelist/identity/") 49 if err != nil { 50 return nil, err 51 } 52 return logical.ListResponse(identities), nil 53} 54 55// Fetch an item from the whitelist given an instance ID. 56func whitelistIdentityEntry(ctx context.Context, s logical.Storage, instanceID string) (*whitelistIdentity, error) { 57 entry, err := s.Get(ctx, "whitelist/identity/"+instanceID) 58 if err != nil { 59 return nil, err 60 } 61 if entry == nil { 62 return nil, nil 63 } 64 65 var result whitelistIdentity 66 if err := entry.DecodeJSON(&result); err != nil { 67 return nil, err 68 } 69 return &result, nil 70} 71 72// Stores an instance ID and the information required to validate further login/renewal attempts from 73// the same instance ID. 74func setWhitelistIdentityEntry(ctx context.Context, s logical.Storage, instanceID string, identity *whitelistIdentity) error { 75 entry, err := logical.StorageEntryJSON("whitelist/identity/"+instanceID, identity) 76 if err != nil { 77 return err 78 } 79 80 if err := s.Put(ctx, entry); err != nil { 81 return err 82 } 83 return nil 84} 85 86// pathIdentityWhitelistDelete is used to delete an entry from the identity whitelist given an instance ID. 87func (b *backend) pathIdentityWhitelistDelete(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { 88 instanceID := data.Get("instance_id").(string) 89 if instanceID == "" { 90 return logical.ErrorResponse("missing instance_id"), nil 91 } 92 93 return nil, req.Storage.Delete(ctx, "whitelist/identity/"+instanceID) 94} 95 96// pathIdentityWhitelistRead is used to view an entry in the identity whitelist given an instance ID. 97func (b *backend) pathIdentityWhitelistRead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { 98 instanceID := data.Get("instance_id").(string) 99 if instanceID == "" { 100 return logical.ErrorResponse("missing instance_id"), nil 101 } 102 103 entry, err := whitelistIdentityEntry(ctx, req.Storage, instanceID) 104 if err != nil { 105 return nil, err 106 } 107 if entry == nil { 108 return nil, nil 109 } 110 111 return &logical.Response{ 112 Data: map[string]interface{}{ 113 "role": entry.Role, 114 "client_nonce": entry.ClientNonce, 115 "creation_time": entry.CreationTime.Format(time.RFC3339Nano), 116 "disallow_reauthentication": entry.DisallowReauthentication, 117 "pending_time": entry.PendingTime, 118 "expiration_time": entry.ExpirationTime.Format(time.RFC3339Nano), 119 "last_updated_time": entry.LastUpdatedTime.Format(time.RFC3339Nano), 120 }, 121 }, nil 122} 123 124// Struct to represent each item in the identity whitelist. 125type whitelistIdentity struct { 126 Role string `json:"role"` 127 ClientNonce string `json:"client_nonce"` 128 CreationTime time.Time `json:"creation_time"` 129 DisallowReauthentication bool `json:"disallow_reauthentication"` 130 PendingTime string `json:"pending_time"` 131 ExpirationTime time.Time `json:"expiration_time"` 132 LastUpdatedTime time.Time `json:"last_updated_time"` 133} 134 135const pathIdentityWhitelistSyn = ` 136Read or delete entries in the identity whitelist. 137` 138 139const pathIdentityWhitelistDesc = ` 140Each login from an EC2 instance creates/updates an entry in the identity whitelist. 141 142Entries in this list can be viewed or deleted using this endpoint. 143 144By default, a cron task will periodically look for expired entries in the whitelist 145and deletes them. The duration to periodically run this, is one hour by default. 146However, this can be configured using the 'config/tidy/identities' endpoint. This tidy 147action can be triggered via the API as well, using the 'tidy/identities' endpoint. 148` 149 150const pathListIdentityWhitelistHelpSyn = ` 151Lists the items present in the identity whitelist. 152` 153 154const pathListIdentityWhitelistHelpDesc = ` 155The entries in the identity whitelist is keyed off of the EC2 instance IDs. 156This endpoint lists all the entries present in the identity whitelist, both 157expired and un-expired entries. Use 'tidy/identities' endpoint to clean-up 158the whitelist of identities. 159` 160