Share one client across components¶
You want configuration from Vault and signing or encryption through Vault's transit engine, over one client rather than three.
Build one source, inject the client¶
import (
configvault "gitlab.com/phpboyscout/go/config-vault"
"gitlab.com/phpboyscout/go/vaultclient"
)
src := vaultclient.Ambient(
vaultclient.WithAddress("https://vault.example.com:8200"),
)
client, err := src.VaultClient(ctx)
if err != nil {
return err
}
backend := configvault.FromClient(client, "secret", "app/config")
config-vault takes the client directly — Vault is the provider where the client
is the prerequisite, so no further seam is needed.
When you already assembled a config¶
cfg := vaultapi.DefaultConfig()
cfg.HttpClient = myInstrumentedClient
src, err := vaultclient.FromConfig(cfg)
That rung checks cfg.Error for you — the field DefaultConfig populates
instead of returning an error — so a broken config fails here rather than at the
first request.
When you already have a client¶
Useful when something else in your process owns the Vault connection and you want the same one used everywhere.
Namespaces¶
Or VAULT_NAMESPACE, which DefaultConfig reads. Vault Enterprise only.
Renewing the token¶
The client you get holds the token that was set when it was built, and nothing
renews it. If your process outlives the token's TTL, keep a
vaultapi.LifetimeWatcher running against the client and rebuild the source when
renewal finally fails:
client, err := src.VaultClient(ctx)
if err != nil {
return err
}
watcher, err := client.NewLifetimeWatcher(&vaultapi.LifetimeWatcherInput{
Secret: authSecret,
})
if err != nil {
return err
}
go watcher.Start()
defer watcher.Stop()
This is the caller's job rather than the module's, and why is worth reading before you decide it is not your problem.
Bounding and scoping¶
src := vaultclient.Ambient(
vaultclient.WithBuildTimeout(5*time.Second),
vaultclient.WithLifetimeContext(appCtx),
)
Per attempt, not a total budget. vaultapi.NewClient does no network I/O, so the
bound matters less here than for a provider whose resolution reaches a metadata
service — but it costs nothing to set.