bug(vault): Correctly handle credential stores with expired tokens (#2399)
* bug(vault): Correctly handle credential stores with expired tokens Boundary makes use of a database view to perform CRUD operations on Vault credential stores and libraries. This view did not include credential stores with tokens that have expired in Vault, causing errors when attempting to perform any action against them.
This commit is contained in:
1 parent
ef4000fe08
commit
d7c4c648ec
33 files changed
+965
-287
No files matched your search
@@ -675,6 +675,7 @@ func toProto(ctx context.Context, in credential.Store, opt ...handlers.Option) (
|
||||
}
|
||||
if vaultIn.Token() != nil {
|
||||
attrs.TokenHmac = base64.RawURLEncoding.EncodeToString(vaultIn.Token().GetTokenHmac())
|
||||
attrs.TokenStatus = vaultIn.Token().GetStatus()
|
||||
}
|
||||
if vaultIn.GetWorkerFilter() != "" {
|
||||
if vaultWorkerFilterToProto {
|
||||
|
||||
@@ -96,6 +96,7 @@ func TestList(t *testing.T) {
|
||||
VaultCredentialStoreAttributes: &pb.VaultCredentialStoreAttributes{
|
||||
Address: wrapperspb.String(s.GetVaultAddress()),
|
||||
TokenHmac: base64.RawURLEncoding.EncodeToString(s.Token().GetTokenHmac()),
|
||||
TokenStatus: s.Token().GetStatus(),
|
||||
ClientCertificate: wrapperspb.String(string(s.ClientCertificate().GetCertificate())),
|
||||
ClientCertificateKeyHmac: base64.RawURLEncoding.EncodeToString(s.ClientCertificate().GetCertificateKeyHmac()),
|
||||
// TODO: Add all fields including tls related fields, namespace, etc...
|
||||
@@ -471,6 +472,7 @@ func TestCreateVault(t *testing.T) {
|
||||
CaCert: wrapperspb.String(string(v.CaCert)),
|
||||
Address: wrapperspb.String(v.Addr),
|
||||
TokenHmac: "<hmac>",
|
||||
TokenStatus: "current",
|
||||
ClientCertificate: wrapperspb.String(string(v.ClientCert)),
|
||||
ClientCertificateKeyHmac: "<hmac>",
|
||||
},
|
||||
@@ -512,6 +514,7 @@ func TestCreateVault(t *testing.T) {
|
||||
CaCert: wrapperspb.String(string(v.CaCert)),
|
||||
Address: wrapperspb.String(v.Addr),
|
||||
TokenHmac: "<hmac>",
|
||||
TokenStatus: "current",
|
||||
ClientCertificate: wrapperspb.String(string(v.ClientCert)),
|
||||
ClientCertificateKeyHmac: "<hmac>",
|
||||
},
|
||||
@@ -795,6 +798,7 @@ func TestGet(t *testing.T) {
|
||||
VaultCredentialStoreAttributes: &pb.VaultCredentialStoreAttributes{
|
||||
Address: wrapperspb.String(vaultStore.GetVaultAddress()),
|
||||
TokenHmac: base64.RawURLEncoding.EncodeToString(vaultStore.Token().GetTokenHmac()),
|
||||
TokenStatus: vaultStore.Token().GetStatus(),
|
||||
ClientCertificate: wrapperspb.String(string(vaultStore.ClientCertificate().GetCertificate())),
|
||||
ClientCertificateKeyHmac: base64.RawURLEncoding.EncodeToString(vaultStore.ClientCertificate().GetCertificateKeyHmac()),
|
||||
},
|
||||
@@ -1068,6 +1072,7 @@ func TestUpdateVault(t *testing.T) {
|
||||
res: func(in *pb.CredentialStore) *pb.CredentialStore {
|
||||
out := proto.Clone(in).(*pb.CredentialStore)
|
||||
out.GetVaultCredentialStoreAttributes().TokenHmac = "<hmac>"
|
||||
out.GetVaultCredentialStoreAttributes().TokenStatus = "current"
|
||||
return out
|
||||
},
|
||||
},
|
||||
|
||||
@@ -3257,6 +3257,17 @@ func TestAuthorizeSession_Errors(t *testing.T) {
|
||||
sec, tok := v.CreateToken(t, vault.WithPolicies([]string{"default", "database"}))
|
||||
store := vault.TestCredentialStore(t, conn, wrapper, proj.GetPublicId(), v.Addr, tok, sec.Auth.Accessor)
|
||||
|
||||
sec1, tok1 := v.CreateToken(t, vault.WithPolicies([]string{"default", "database"}))
|
||||
expiredStore := vault.TestCredentialStore(t, conn, wrapper, proj.GetPublicId(), v.Addr, tok1, sec1.Auth.Accessor)
|
||||
|
||||
// Set previous token to expired in the database and revoke in Vault to validate a
|
||||
// credential store with an expired token is correctly returned over the API
|
||||
num, err := rw.Exec(context.Background(), "update credential_vault_token set status = ? where store_id = ?",
|
||||
[]interface{}{vault.ExpiredToken, expiredStore.PublicId})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 1, num)
|
||||
v.RevokeToken(t, tok1)
|
||||
|
||||
workerExists := func(tar target.Target) (version uint32) {
|
||||
server.TestKmsWorker(t, conn, wrapper)
|
||||
return tar.GetVersion()
|
||||
@@ -3356,6 +3367,30 @@ func TestAuthorizeSession_Errors(t *testing.T) {
|
||||
return tr.GetItem().GetVersion()
|
||||
}
|
||||
|
||||
expiredTokenLibrary := func(tar target.Target) (version uint32) {
|
||||
credService, err := credentiallibraries.NewService(vaultCredRepoFn, iamRepoFn)
|
||||
require.NoError(t, err)
|
||||
clsResp, err := credService.CreateCredentialLibrary(ctx, &pbs.CreateCredentialLibraryRequest{Item: &credlibpb.CredentialLibrary{
|
||||
CredentialStoreId: expiredStore.GetPublicId(),
|
||||
Description: wrapperspb.String(fmt.Sprintf("Library Description for target %q", tar.GetName())),
|
||||
Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{
|
||||
VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{
|
||||
Path: wrapperspb.String(path.Join("database", "creds", "opened")),
|
||||
},
|
||||
},
|
||||
}})
|
||||
require.NoError(t, err)
|
||||
|
||||
tr, err := s.AddTargetCredentialSources(ctx,
|
||||
&pbs.AddTargetCredentialSourcesRequest{
|
||||
Id: tar.GetPublicId(),
|
||||
BrokeredCredentialSourceIds: []string{clsResp.GetItem().GetId()},
|
||||
Version: tar.GetVersion(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return tr.GetItem().GetVersion()
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
setup []func(target.Target) uint32
|
||||
@@ -3386,6 +3421,11 @@ func TestAuthorizeSession_Errors(t *testing.T) {
|
||||
setup: []func(tcpTarget target.Target) uint32{workerExists, hostExists, misConfiguredlibraryExists},
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
name: "expired token library",
|
||||
setup: []func(tcpTarget target.Target) uint32{workerExists, hostExists, expiredTokenLibrary},
|
||||
err: true,
|
||||
},
|
||||
}
|
||||
for i, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
|
||||
Reference in new issue
Block a user