Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e7ed488

Browse files
committedFeb 13, 2024·
VAULT-528 Fix Vault Agent being unable to render secrets with delete_version_after set. (#25387)
* VAULT-528 add test reproducing the failure that should pass after the fix * VAULT-528 Upgrade consul-template to version with the fix * VAULT-528 changelog
1 parent 7620b53 commit e7ed488

File tree

4 files changed

+337
-286
lines changed

4 files changed

+337
-286
lines changed
 

‎changelog/25387.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:bug
2+
agent: Fix issue where Vault Agent was unable to render KVv2 secrets with delete_version_after set.
3+
```

‎command/agent_test.go

+155
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ package command
55

66
import (
77
"bufio"
8+
"context"
89
"crypto/tls"
910
"crypto/x509"
1011
"encoding/json"
12+
"errors"
1113
"fmt"
1214
"io"
1315
"net"
@@ -3172,6 +3174,159 @@ auto_auth {
31723174
require.Truef(t, found, "unable to find consul-template partial message in logs", runnerLogMessage)
31733175
}
31743176

3177+
// TestAgent_DeleteAfterVersion_Rendering Validates that Vault Agent
3178+
// can correctly render a secret with delete_after_version set.
3179+
func TestAgent_DeleteAfterVersion_Rendering(t *testing.T) {
3180+
logger := logging.NewVaultLogger(hclog.Trace)
3181+
cluster := vault.NewTestCluster(t,
3182+
&vault.CoreConfig{
3183+
Logger: logger,
3184+
},
3185+
&vault.TestClusterOptions{
3186+
NumCores: 1,
3187+
HandlerFunc: vaulthttp.Handler,
3188+
})
3189+
cluster.Start()
3190+
defer cluster.Cleanup()
3191+
3192+
vault.TestWaitActive(t, cluster.Cores[0].Core)
3193+
serverClient := cluster.Cores[0].Client
3194+
3195+
// Set up KVv2
3196+
err := serverClient.Sys().Mount("kv-v2", &api.MountInput{
3197+
Type: "kv-v2",
3198+
})
3199+
require.NoError(t, err)
3200+
3201+
// Configure the mount to set delete_version_after on all of its secrets
3202+
_, err = serverClient.Logical().Write("kv-v2/config", map[string]interface{}{
3203+
"delete_version_after": "1h",
3204+
})
3205+
require.NoError(t, err)
3206+
3207+
// Set up the secret (which will have delete_version_after set to 1h)
3208+
data, err := serverClient.KVv2("kv-v2").Put(context.Background(), "foo", map[string]interface{}{
3209+
"bar": "baz",
3210+
})
3211+
require.NoError(t, err)
3212+
3213+
// Ensure Deletion Time was correctly set
3214+
require.NotZero(t, data.VersionMetadata.DeletionTime)
3215+
require.True(t, data.VersionMetadata.DeletionTime.After(time.Now()))
3216+
require.NotNil(t, data.VersionMetadata.CreatedTime)
3217+
require.True(t, data.VersionMetadata.DeletionTime.After(data.VersionMetadata.CreatedTime))
3218+
3219+
// Unset the environment variable so that Agent picks up the right test
3220+
// cluster address
3221+
defer os.Setenv(api.EnvVaultAddress, os.Getenv(api.EnvVaultAddress))
3222+
os.Setenv(api.EnvVaultAddress, serverClient.Address())
3223+
3224+
// create temp dir for this test run
3225+
tmpDir, err := os.MkdirTemp("", "TestAgent_DeleteAfterVersion_Rendering")
3226+
require.NoError(t, err)
3227+
3228+
tokenFileName := makeTempFile(t, "token-file", serverClient.Token())
3229+
defer os.Remove(tokenFileName)
3230+
3231+
autoAuthConfig := fmt.Sprintf(`
3232+
auto_auth {
3233+
method {
3234+
type = "token_file"
3235+
config = {
3236+
token_file_path = "%s"
3237+
}
3238+
}
3239+
}`, tokenFileName)
3240+
3241+
// Create a config file
3242+
config := `
3243+
vault {
3244+
address = "%s"
3245+
tls_skip_verify = true
3246+
}
3247+
3248+
%s
3249+
3250+
%s
3251+
`
3252+
3253+
fileName := "secret.txt"
3254+
templateConfig := fmt.Sprintf(`
3255+
template {
3256+
destination = "%s/%s"
3257+
contents = "{{ with secret \"kv-v2/foo\" }}{{ .Data.data.bar }}{{ end }}"
3258+
}
3259+
`, tmpDir, fileName)
3260+
3261+
config = fmt.Sprintf(config, serverClient.Address(), autoAuthConfig, templateConfig)
3262+
configPath := makeTempFile(t, "config.hcl", config)
3263+
defer os.Remove(configPath)
3264+
3265+
// Start the agent
3266+
ui, cmd := testAgentCommand(t, logger)
3267+
cmd.client = serverClient
3268+
cmd.startedCh = make(chan struct{})
3269+
3270+
wg := &sync.WaitGroup{}
3271+
wg.Add(1)
3272+
go func() {
3273+
code := cmd.Run([]string{"-config", configPath})
3274+
if code != 0 {
3275+
t.Errorf("non-zero return code when running agent: %d", code)
3276+
t.Logf("STDOUT from agent:\n%s", ui.OutputWriter.String())
3277+
t.Logf("STDERR from agent:\n%s", ui.ErrorWriter.String())
3278+
}
3279+
wg.Done()
3280+
}()
3281+
3282+
select {
3283+
case <-cmd.startedCh:
3284+
case <-time.After(5 * time.Second):
3285+
t.Errorf("timeout")
3286+
}
3287+
3288+
// We need to shut down the Agent command
3289+
defer func() {
3290+
cmd.ShutdownCh <- struct{}{}
3291+
wg.Wait()
3292+
}()
3293+
3294+
filePath := fmt.Sprintf("%s/%s", tmpDir, fileName)
3295+
3296+
waitForFiles := func() error {
3297+
tick := time.Tick(100 * time.Millisecond)
3298+
timeout := time.After(10 * time.Second)
3299+
// We need to wait for the templates to render...
3300+
for {
3301+
select {
3302+
case <-timeout:
3303+
t.Fatalf("timed out waiting for templates to render, last error: %v", err)
3304+
case <-tick:
3305+
}
3306+
3307+
_, err := os.Stat(filePath)
3308+
if err != nil {
3309+
if errors.Is(err, os.ErrNotExist) {
3310+
continue
3311+
}
3312+
return err
3313+
}
3314+
3315+
return nil
3316+
}
3317+
}
3318+
3319+
err = waitForFiles()
3320+
require.NoError(t, err)
3321+
3322+
// Ensure the file has the
3323+
fileData, err := os.ReadFile(filePath)
3324+
require.NoError(t, err)
3325+
if string(fileData) != "baz" {
3326+
t.Fatalf("Unexpected file contents. Expected 'baz', got %s", string(fileData))
3327+
}
3328+
}
3329+
31753330
// Get a randomly assigned port and then free it again before returning it.
31763331
// There is still a race when trying to use it, but should work better
31773332
// than a static port.

‎go.mod

+55-53
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ replace github.com/hashicorp/vault/sdk => ./sdk
2626

2727
require (
2828
cloud.google.com/go/cloudsqlconn v1.4.3
29-
cloud.google.com/go/monitoring v1.16.0
30-
cloud.google.com/go/spanner v1.49.0
29+
cloud.google.com/go/monitoring v1.17.0
30+
cloud.google.com/go/spanner v1.54.0
3131
cloud.google.com/go/storage v1.30.1
3232
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1
3333
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0
@@ -43,7 +43,7 @@ require (
4343
github.com/apple/foundationdb/bindings/go v0.0.0-20190411004307-cd5c9d91fad2
4444
github.com/armon/go-metrics v0.4.1
4545
github.com/armon/go-radix v1.0.0
46-
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef
46+
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
4747
github.com/aws/aws-sdk-go v1.49.22
4848
github.com/aws/aws-sdk-go-v2/config v1.18.19
4949
github.com/axiomhq/hyperloglog v0.0.0-20220105174342-98591331716a
@@ -54,7 +54,7 @@ require (
5454
github.com/denisenkom/go-mssqldb v0.12.3
5555
github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74
5656
github.com/dustin/go-humanize v1.0.1
57-
github.com/fatih/color v1.15.0
57+
github.com/fatih/color v1.16.0
5858
github.com/fatih/structs v1.1.0
5959
github.com/gammazero/workerpool v1.1.3
6060
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
@@ -73,9 +73,9 @@ require (
7373
github.com/google/go-metrics-stackdriver v0.2.0
7474
github.com/google/tink/go v1.7.0
7575
github.com/hashicorp-forge/bbolt v1.3.8-hc3
76-
github.com/hashicorp/cap v0.3.4
77-
github.com/hashicorp/consul-template v0.33.0
78-
github.com/hashicorp/consul/api v1.23.0
76+
github.com/hashicorp/cap v0.5.0
77+
github.com/hashicorp/consul-template v0.36.1-0.20240213145952-6c83e89b48af
78+
github.com/hashicorp/consul/api v1.27.0
7979
github.com/hashicorp/errwrap v1.1.0
8080
github.com/hashicorp/eventlogger v0.2.3
8181
github.com/hashicorp/go-bexpr v0.1.12
@@ -117,11 +117,11 @@ require (
117117
github.com/hashicorp/golang-lru v0.5.4
118118
github.com/hashicorp/hcl v1.0.1-vault-5
119119
github.com/hashicorp/hcl/v2 v2.16.2
120-
github.com/hashicorp/hcp-link v0.1.0
121-
github.com/hashicorp/hcp-scada-provider v0.2.1
122-
github.com/hashicorp/hcp-sdk-go v0.23.0
123-
github.com/hashicorp/nomad/api v0.0.0-20230519153805-2275a83cbfdf
124-
github.com/hashicorp/raft v1.3.10
120+
github.com/hashicorp/hcp-link v0.2.1
121+
github.com/hashicorp/hcp-scada-provider v0.2.2
122+
github.com/hashicorp/hcp-sdk-go v0.75.0
123+
github.com/hashicorp/nomad/api v0.0.0-20240213164230-c364cb57298d
124+
github.com/hashicorp/raft v1.6.0
125125
github.com/hashicorp/raft-autopilot v0.2.0
126126
github.com/hashicorp/raft-boltdb/v2 v2.0.0-20210421194847-a7e34179d62c
127127
github.com/hashicorp/raft-snapshot v1.0.4
@@ -167,7 +167,7 @@ require (
167167
github.com/kr/pretty v0.3.1
168168
github.com/kr/text v0.2.0
169169
github.com/mattn/go-colorable v0.1.13
170-
github.com/mattn/go-isatty v0.0.19
170+
github.com/mattn/go-isatty v0.0.20
171171
github.com/mholt/archiver/v3 v3.5.1
172172
github.com/michaelklishin/rabbit-hole/v2 v2.12.0
173173
github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a
@@ -211,17 +211,17 @@ require (
211211
go.opentelemetry.io/otel/trace v1.22.0
212212
go.uber.org/atomic v1.11.0
213213
go.uber.org/goleak v1.2.1
214-
golang.org/x/crypto v0.18.0
215-
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
216-
golang.org/x/net v0.20.0
217-
golang.org/x/oauth2 v0.15.0
218-
golang.org/x/sync v0.5.0
219-
golang.org/x/sys v0.16.0
220-
golang.org/x/term v0.16.0
214+
golang.org/x/crypto v0.19.0
215+
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a
216+
golang.org/x/net v0.21.0
217+
golang.org/x/oauth2 v0.17.0
218+
golang.org/x/sync v0.6.0
219+
golang.org/x/sys v0.17.0
220+
golang.org/x/term v0.17.0
221221
golang.org/x/text v0.14.0
222-
golang.org/x/tools v0.14.0
223-
google.golang.org/api v0.138.0
224-
google.golang.org/grpc v1.60.1
222+
golang.org/x/tools v0.18.0
223+
google.golang.org/api v0.163.0
224+
google.golang.org/grpc v1.61.0
225225
google.golang.org/protobuf v1.32.0
226226
gopkg.in/ory-am/dockertest.v3 v3.3.4
227227
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2
@@ -230,11 +230,11 @@ require (
230230
)
231231

232232
require (
233-
cloud.google.com/go v0.110.8 // indirect
234-
cloud.google.com/go/compute v1.23.0 // indirect
233+
cloud.google.com/go v0.111.0 // indirect
234+
cloud.google.com/go/compute v1.23.3 // indirect
235235
cloud.google.com/go/compute/metadata v0.2.3 // indirect
236-
cloud.google.com/go/iam v1.1.2 // indirect
237-
cloud.google.com/go/kms v1.15.2 // indirect
236+
cloud.google.com/go/iam v1.1.5 // indirect
237+
cloud.google.com/go/kms v1.15.5 // indirect
238238
dario.cat/mergo v1.0.0 // indirect
239239
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
240240
github.com/99designs/keyring v1.2.2 // indirect
@@ -305,16 +305,16 @@ require (
305305
github.com/cloudflare/circl v1.3.7 // indirect
306306
github.com/cloudfoundry-community/go-cfclient v0.0.0-20220930021109-9c4e6c59ccf1 // indirect
307307
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe // indirect
308-
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect
308+
github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 // indirect
309309
github.com/containerd/containerd v1.7.12 // indirect
310310
github.com/containerd/continuity v0.4.2 // indirect
311311
github.com/containerd/log v0.1.0 // indirect
312312
github.com/coreos/go-oidc v2.2.1+incompatible // indirect
313313
github.com/coreos/go-oidc/v3 v3.5.0 // indirect
314314
github.com/coreos/go-semver v0.3.0 // indirect
315315
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
316-
github.com/couchbase/gocb/v2 v2.6.3 // indirect
317-
github.com/couchbase/gocbcore/v10 v10.2.3 // indirect
316+
github.com/couchbase/gocb/v2 v2.6.5 // indirect
317+
github.com/couchbase/gocbcore/v10 v10.3.1 // indirect
318318
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
319319
github.com/danieljoos/wincred v1.1.2 // indirect
320320
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
@@ -345,16 +345,16 @@ require (
345345
github.com/go-logr/logr v1.4.1 // indirect
346346
github.com/go-logr/stdr v1.2.2 // indirect
347347
github.com/go-ole/go-ole v1.2.6 // indirect
348-
github.com/go-openapi/analysis v0.20.0 // indirect
349-
github.com/go-openapi/errors v0.20.1 // indirect
350-
github.com/go-openapi/jsonpointer v0.19.6 // indirect
348+
github.com/go-openapi/analysis v0.21.4 // indirect
349+
github.com/go-openapi/errors v0.20.4 // indirect
350+
github.com/go-openapi/jsonpointer v0.20.0 // indirect
351351
github.com/go-openapi/jsonreference v0.20.2 // indirect
352-
github.com/go-openapi/loads v0.20.2 // indirect
353-
github.com/go-openapi/runtime v0.19.24 // indirect
354-
github.com/go-openapi/spec v0.20.3 // indirect
355-
github.com/go-openapi/strfmt v0.20.0 // indirect
356-
github.com/go-openapi/swag v0.22.3 // indirect
357-
github.com/go-openapi/validate v0.20.2 // indirect
352+
github.com/go-openapi/loads v0.21.2 // indirect
353+
github.com/go-openapi/runtime v0.26.0 // indirect
354+
github.com/go-openapi/spec v0.20.9 // indirect
355+
github.com/go-openapi/strfmt v0.21.7 // indirect
356+
github.com/go-openapi/swag v0.22.4 // indirect
357+
github.com/go-openapi/validate v0.22.2 // indirect
358358
github.com/go-ozzo/ozzo-validation v3.6.0+incompatible // indirect
359359
github.com/goccy/go-json v0.10.2 // indirect
360360
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
@@ -369,16 +369,16 @@ require (
369369
github.com/google/gnostic-models v0.6.8 // indirect
370370
github.com/google/go-querystring v1.1.0 // indirect
371371
github.com/google/gofuzz v1.2.0 // indirect
372-
github.com/google/s2a-go v0.1.5 // indirect
372+
github.com/google/s2a-go v0.1.7 // indirect
373373
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
374-
github.com/google/uuid v1.3.1 // indirect
375-
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
374+
github.com/google/uuid v1.6.0 // indirect
375+
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
376376
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
377377
github.com/gophercloud/gophercloud v0.1.0 // indirect
378-
github.com/gorilla/websocket v1.5.0 // indirect
378+
github.com/gorilla/websocket v1.5.1 // indirect
379379
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
380380
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
381-
github.com/hashicorp/cronexpr v1.1.1 // indirect
381+
github.com/hashicorp/cronexpr v1.1.2 // indirect
382382
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
383383
github.com/hashicorp/go-msgpack/v2 v2.1.1 // indirect
384384
github.com/hashicorp/go-secure-stdlib/fileutil v0.1.0 // indirect
@@ -390,11 +390,11 @@ require (
390390
github.com/hashicorp/mdns v1.0.4 // indirect
391391
github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0 // indirect
392392
github.com/hashicorp/serf v0.10.1 // indirect
393-
github.com/hashicorp/vault/api/auth/kubernetes v0.4.1 // indirect
393+
github.com/hashicorp/vault/api/auth/kubernetes v0.6.0 // indirect
394394
github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443 // indirect
395395
github.com/hashicorp/yamux v0.1.1 // indirect
396396
github.com/huandu/xstrings v1.4.0 // indirect
397-
github.com/imdario/mergo v0.3.15 // indirect
397+
github.com/imdario/mergo v0.3.16 // indirect
398398
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
399399
github.com/jackc/pgconn v1.14.0 // indirect
400400
github.com/jackc/pgio v1.0.0 // indirect
@@ -449,6 +449,7 @@ require (
449449
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
450450
github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 // indirect
451451
github.com/nwaples/rardecode v1.1.2 // indirect
452+
github.com/oklog/ulid v1.3.1 // indirect
452453
github.com/opencontainers/go-digest v1.0.0 // indirect
453454
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect
454455
github.com/opencontainers/runc v1.1.6 // indirect
@@ -474,8 +475,8 @@ require (
474475
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
475476
github.com/snowflakedb/gosnowflake v1.7.2 // indirect
476477
github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d // indirect
477-
github.com/sony/gobreaker v0.4.2-0.20210216022020-dd874f9dd33b // indirect
478-
github.com/spf13/cast v1.5.1 // indirect
478+
github.com/sony/gobreaker v0.5.0 // indirect
479+
github.com/spf13/cast v1.6.0 // indirect
479480
github.com/spf13/pflag v1.0.5 // indirect
480481
github.com/stretchr/objx v0.5.0 // indirect
481482
github.com/tencentcloud/tencentcloud-sdk-go v1.0.162 // indirect
@@ -501,17 +502,18 @@ require (
501502
github.com/zeebo/xxh3 v1.0.2 // indirect
502503
go.etcd.io/etcd/api/v3 v3.5.7 // indirect
503504
go.opencensus.io v0.24.0 // indirect
505+
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect
504506
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect
505507
go.opentelemetry.io/otel/metric v1.22.0 // indirect
506508
go.uber.org/multierr v1.7.0 // indirect
507509
go.uber.org/zap v1.19.1 // indirect
508-
golang.org/x/mod v0.13.0 // indirect
509-
golang.org/x/time v0.3.0 // indirect
510+
golang.org/x/mod v0.15.0 // indirect
511+
golang.org/x/time v0.5.0 // indirect
510512
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
511513
google.golang.org/appengine v1.6.8 // indirect
512-
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect
513-
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect
514-
google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect
514+
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac // indirect
515+
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect
516+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe // indirect
515517
gopkg.in/inf.v0 v0.9.1 // indirect
516518
gopkg.in/ini.v1 v1.66.2 // indirect
517519
gopkg.in/jcmturner/goidentity.v3 v3.0.0 // indirect

‎go.sum

+124-233
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.