Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

spindle/secrets: rework openbao manager to use bao proxy

Signed-off-by: Anirudh Oppiliappan <anirudh@tangled.sh>

authored by

Anirudh Oppiliappan and committed by
Tangled
cccf0b0b 60437654

+133 -255
+2 -4
spindle/config/config.go
··· 28 28 } 29 29 30 30 type OpenBaoConfig struct { 31 - Addr string `env:"ADDR"` 32 - RoleID string `env:"ROLE_ID"` 33 - SecretID string `env:"SECRET_ID"` 34 - Mount string `env:"MOUNT, default=spindle"` 31 + ProxyAddr string `env:"PROXY_ADDR, default=http://127.0.0.1:8200"` 32 + Mount string `env:"MOUNT, default=spindle"` 35 33 } 36 34 37 35 type Pipelines struct {
+55 -149
spindle/secrets/openbao.go
··· 6 6 "log/slog" 7 7 "path" 8 8 "strings" 9 - "sync" 10 9 "time" 11 10 12 11 "github.com/bluesky-social/indigo/atproto/syntax" ··· 15 16 type OpenBaoManager struct { 16 17 client *vault.Client 17 18 mountPath string 18 - roleID string 19 - secretID string 20 - stopCh chan struct{} 21 - tokenMu sync.RWMutex 22 19 logger *slog.Logger 23 20 } 24 21 ··· 26 31 } 27 32 } 28 33 29 - func NewOpenBaoManager(address, roleID, secretID string, logger *slog.Logger, opts ...OpenBaoManagerOpt) (*OpenBaoManager, error) { 30 - if address == "" { 31 - return nil, fmt.Errorf("address cannot be empty") 32 - } 33 - if roleID == "" { 34 - return nil, fmt.Errorf("role_id cannot be empty") 35 - } 36 - if secretID == "" { 37 - return nil, fmt.Errorf("secret_id cannot be empty") 34 + // NewOpenBaoManager creates a new OpenBao manager that connects to a Bao Proxy 35 + // The proxyAddress should point to the local Bao Proxy (e.g., "http://127.0.0.1:8200") 36 + // The proxy handles all authentication automatically via Auto-Auth 37 + func NewOpenBaoManager(proxyAddress string, logger *slog.Logger, opts ...OpenBaoManagerOpt) (*OpenBaoManager, error) { 38 + if proxyAddress == "" { 39 + return nil, fmt.Errorf("proxy address cannot be empty") 38 40 } 39 41 40 42 config := vault.DefaultConfig() 41 - config.Address = address 43 + config.Address = proxyAddress 42 44 43 45 client, err := vault.NewClient(config) 44 46 if err != nil { 45 47 return nil, fmt.Errorf("failed to create openbao client: %w", err) 46 48 } 47 49 48 - // Authenticate using AppRole 49 - err = authenticateAppRole(client, roleID, secretID) 50 - if err != nil { 51 - return nil, fmt.Errorf("failed to authenticate with AppRole: %w", err) 52 - } 53 - 54 50 manager := &OpenBaoManager{ 55 51 client: client, 56 52 mountPath: "spindle", // default KV v2 mount path 57 - roleID: roleID, 58 - secretID: secretID, 59 - stopCh: make(chan struct{}), 60 53 logger: logger, 61 54 } 62 55 ··· 52 69 opt(manager) 53 70 } 54 71 55 - go manager.tokenRenewalLoop() 72 + if err := manager.testConnection(); err != nil { 73 + return nil, fmt.Errorf("failed to connect to bao proxy: %w", err) 74 + } 56 75 76 + logger.Info("successfully connected to bao proxy", "address", proxyAddress) 57 77 return manager, nil 58 78 } 59 79 60 - // authenticateAppRole authenticates the client using AppRole method 61 - func authenticateAppRole(client *vault.Client, roleID, secretID string) error { 62 - authData := map[string]interface{}{ 63 - "role_id": roleID, 64 - "secret_id": secretID, 65 - } 80 + // testConnection verifies that we can connect to the proxy 81 + func (v *OpenBaoManager) testConnection() error { 82 + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 83 + defer cancel() 66 84 67 - resp, err := client.Logical().Write("auth/approle/login", authData) 85 + // try token self-lookup as a quick way to verify proxy works 86 + // and is authenticated 87 + _, err := v.client.Auth().Token().LookupSelfWithContext(ctx) 68 88 if err != nil { 69 - return fmt.Errorf("failed to login with AppRole: %w", err) 89 + return fmt.Errorf("proxy connection test failed: %w", err) 70 90 } 71 91 72 - if resp == nil || resp.Auth == nil { 73 - return fmt.Errorf("no auth info returned from AppRole login") 74 - } 75 - 76 - client.SetToken(resp.Auth.ClientToken) 77 - return nil 78 - } 79 - 80 - // stop stops the token renewal goroutine 81 - func (v *OpenBaoManager) Stop() { 82 - close(v.stopCh) 83 - } 84 - 85 - // tokenRenewalLoop runs in a background goroutine to automatically renew or re-authenticate tokens 86 - func (v *OpenBaoManager) tokenRenewalLoop() { 87 - ticker := time.NewTicker(30 * time.Second) // Check every 30 seconds 88 - defer ticker.Stop() 89 - 90 - for { 91 - select { 92 - case <-v.stopCh: 93 - return 94 - case <-ticker.C: 95 - ctx := context.Background() 96 - if err := v.ensureValidToken(ctx); err != nil { 97 - v.logger.Error("openbao token renewal failed", "error", err) 98 - } 99 - } 100 - } 101 - } 102 - 103 - // ensureValidToken checks if the current token is valid and renews or re-authenticates if needed 104 - func (v *OpenBaoManager) ensureValidToken(ctx context.Context) error { 105 - v.tokenMu.Lock() 106 - defer v.tokenMu.Unlock() 107 - 108 - // check current token info 109 - tokenInfo, err := v.client.Auth().Token().LookupSelf() 110 - if err != nil { 111 - // token is invalid, need to re-authenticate 112 - v.logger.Warn("token lookup failed, re-authenticating", "error", err) 113 - return v.reAuthenticate() 114 - } 115 - 116 - if tokenInfo == nil || tokenInfo.Data == nil { 117 - return v.reAuthenticate() 118 - } 119 - 120 - // check TTL 121 - ttlRaw, ok := tokenInfo.Data["ttl"] 122 - if !ok { 123 - return v.reAuthenticate() 124 - } 125 - 126 - var ttl int64 127 - switch t := ttlRaw.(type) { 128 - case int64: 129 - ttl = t 130 - case float64: 131 - ttl = int64(t) 132 - case int: 133 - ttl = int64(t) 134 - default: 135 - return v.reAuthenticate() 136 - } 137 - 138 - // if TTL is less than 5 minutes, try to renew 139 - if ttl < 300 { 140 - v.logger.Info("token ttl low, attempting renewal", "ttl_seconds", ttl) 141 - 142 - renewResp, err := v.client.Auth().Token().RenewSelf(3600) // 1h 143 - if err != nil { 144 - v.logger.Warn("token renewal failed, re-authenticating", "error", err) 145 - return v.reAuthenticate() 146 - } 147 - 148 - if renewResp == nil || renewResp.Auth == nil { 149 - v.logger.Warn("token renewal returned no auth info, re-authenticating") 150 - return v.reAuthenticate() 151 - } 152 - 153 - v.logger.Info("token renewed successfully", "new_ttl_seconds", renewResp.Auth.LeaseDuration) 154 - } 155 - 156 - return nil 157 - } 158 - 159 - // reAuthenticate performs a fresh authentication using AppRole 160 - func (v *OpenBaoManager) reAuthenticate() error { 161 - v.logger.Info("re-authenticating with approle") 162 - 163 - err := authenticateAppRole(v.client, v.roleID, v.secretID) 164 - if err != nil { 165 - return fmt.Errorf("re-authentication failed: %w", err) 166 - } 167 - 168 - v.logger.Info("re-authentication successful") 169 92 return nil 170 93 } 171 94 172 95 func (v *OpenBaoManager) AddSecret(ctx context.Context, secret UnlockedSecret) error { 173 - v.tokenMu.RLock() 174 - defer v.tokenMu.RUnlock() 175 96 if err := ValidateKey(secret.Key); err != nil { 176 97 return err 177 98 } 178 99 179 100 secretPath := v.buildSecretPath(secret.Repo, secret.Key) 101 + v.logger.Debug("adding secret", "repo", secret.Repo, "key", secret.Key, "path", secretPath) 180 102 181 - fmt.Println(v.mountPath, secretPath) 182 - 103 + // Check if secret already exists 183 104 existing, err := v.client.KVv2(v.mountPath).Get(ctx, secretPath) 184 105 if err == nil && existing != nil { 106 + v.logger.Debug("secret already exists", "path", secretPath) 185 107 return ErrKeyAlreadyPresent 186 108 } 187 109 ··· 98 210 "created_by": secret.CreatedBy.String(), 99 211 } 100 212 101 - _, err = v.client.KVv2(v.mountPath).Put(ctx, secretPath, secretData) 213 + v.logger.Debug("writing secret to openbao", "path", secretPath, "mount", v.mountPath) 214 + resp, err := v.client.KVv2(v.mountPath).Put(ctx, secretPath, secretData) 102 215 if err != nil { 216 + v.logger.Error("failed to write secret", "path", secretPath, "error", err) 103 217 return fmt.Errorf("failed to store secret in openbao: %w", err) 104 218 } 105 219 220 + v.logger.Debug("secret write response", "version", resp.VersionMetadata.Version, "created_time", resp.VersionMetadata.CreatedTime) 221 + 222 + v.logger.Debug("verifying secret was written", "path", secretPath) 223 + readBack, err := v.client.KVv2(v.mountPath).Get(ctx, secretPath) 224 + if err != nil { 225 + v.logger.Error("failed to verify secret after write", "path", secretPath, "error", err) 226 + return fmt.Errorf("secret not found after writing to %s/%s: %w", v.mountPath, secretPath, err) 227 + } 228 + 229 + if readBack == nil || readBack.Data == nil { 230 + v.logger.Error("secret verification returned empty data", "path", secretPath) 231 + return fmt.Errorf("secret verification failed: empty data returned for %s/%s", v.mountPath, secretPath) 232 + } 233 + 234 + v.logger.Info("secret added and verified successfully", "repo", secret.Repo, "key", secret.Key, "version", readBack.VersionMetadata.Version) 106 235 return nil 107 236 } 108 237 109 238 func (v *OpenBaoManager) RemoveSecret(ctx context.Context, secret Secret[any]) error { 110 - v.tokenMu.RLock() 111 - defer v.tokenMu.RUnlock() 112 239 secretPath := v.buildSecretPath(secret.Repo, secret.Key) 113 240 241 + // check if secret exists 114 242 existing, err := v.client.KVv2(v.mountPath).Get(ctx, secretPath) 115 243 if err != nil || existing == nil { 116 244 return ErrKeyNotFound ··· 137 233 return fmt.Errorf("failed to delete secret from openbao: %w", err) 138 234 } 139 235 236 + v.logger.Debug("secret removed successfully", "repo", secret.Repo, "key", secret.Key) 140 237 return nil 141 238 } 142 239 143 240 func (v *OpenBaoManager) GetSecretsLocked(ctx context.Context, repo DidSlashRepo) ([]LockedSecret, error) { 144 - v.tokenMu.RLock() 145 - defer v.tokenMu.RUnlock() 146 241 repoPath := v.buildRepoPath(repo) 147 242 148 - secretsList, err := v.client.Logical().List(fmt.Sprintf("%s/metadata/%s", v.mountPath, repoPath)) 243 + secretsList, err := v.client.Logical().ListWithContext(ctx, fmt.Sprintf("%s/metadata/%s", v.mountPath, repoPath)) 149 244 if err != nil { 150 245 if strings.Contains(err.Error(), "no secret found") || strings.Contains(err.Error(), "no handler for route") { 151 246 return []LockedSecret{}, nil ··· 169 266 continue 170 267 } 171 268 172 - secretPath := path.Join(repoPath, key) 269 + secretPath := fmt.Sprintf("%s/%s", repoPath, key) 173 270 secretData, err := v.client.KVv2(v.mountPath).Get(ctx, secretPath) 174 271 if err != nil { 175 - continue // Skip secrets we can't read 272 + v.logger.Warn("failed to read secret metadata", "path", secretPath, "error", err) 273 + continue 176 274 } 177 275 178 276 if secretData == nil || secretData.Data == nil { ··· 212 308 secrets = append(secrets, secret) 213 309 } 214 310 311 + v.logger.Debug("retrieved locked secrets", "repo", repo, "count", len(secrets)) 215 312 return secrets, nil 216 313 } 217 314 218 315 func (v *OpenBaoManager) GetSecretsUnlocked(ctx context.Context, repo DidSlashRepo) ([]UnlockedSecret, error) { 219 - v.tokenMu.RLock() 220 - defer v.tokenMu.RUnlock() 221 316 repoPath := v.buildRepoPath(repo) 222 317 223 - secretsList, err := v.client.Logical().List(fmt.Sprintf("%s/metadata/%s", v.mountPath, repoPath)) 318 + secretsList, err := v.client.Logical().ListWithContext(ctx, fmt.Sprintf("%s/metadata/%s", v.mountPath, repoPath)) 224 319 if err != nil { 225 320 if strings.Contains(err.Error(), "no secret found") || strings.Contains(err.Error(), "no handler for route") { 226 321 return []UnlockedSecret{}, nil ··· 244 341 continue 245 342 } 246 343 247 - secretPath := path.Join(repoPath, key) 344 + secretPath := fmt.Sprintf("%s/%s", repoPath, key) 248 345 secretData, err := v.client.KVv2(v.mountPath).Get(ctx, secretPath) 249 346 if err != nil { 347 + v.logger.Warn("failed to read secret", "path", secretPath, "error", err) 250 348 continue 251 349 } 252 350 ··· 259 355 260 356 valueStr, ok := data["value"].(string) 261 357 if !ok { 262 - continue // skip secrets without values 358 + v.logger.Warn("secret missing value", "path", secretPath) 359 + continue 263 360 } 264 361 265 362 createdAtStr, ok := data["created_at"].(string) ··· 294 389 secrets = append(secrets, secret) 295 390 } 296 391 392 + v.logger.Debug("retrieved unlocked secrets", "repo", repo, "count", len(secrets)) 297 393 return secrets, nil 298 394 } 299 395 300 - // buildRepoPath creates an OpenBao path for a repository 396 + // buildRepoPath creates a safe path for a repository 301 397 func (v *OpenBaoManager) buildRepoPath(repo DidSlashRepo) string { 302 398 // convert DidSlashRepo to a safe path by replacing special characters 303 399 repoPath := strings.ReplaceAll(string(repo), "/", "_") ··· 307 401 return fmt.Sprintf("repos/%s", repoPath) 308 402 } 309 403 310 - // buildSecretPath creates an OpenBao path for a specific secret 404 + // buildSecretPath creates a path for a specific secret 311 405 func (v *OpenBaoManager) buildSecretPath(repo DidSlashRepo, key string) string { 312 406 return path.Join(v.buildRepoPath(repo), key) 313 407 }
+59 -84
spindle/secrets/openbao_test.go
··· 16 16 secrets map[string]UnlockedSecret // key: repo_key format 17 17 shouldError bool 18 18 errorToReturn error 19 - stopped bool 20 19 } 21 20 22 21 func NewMockOpenBaoManager() *MockOpenBaoManager { ··· 30 31 func (m *MockOpenBaoManager) ClearError() { 31 32 m.shouldError = false 32 33 m.errorToReturn = nil 33 - } 34 - 35 - func (m *MockOpenBaoManager) Stop() { 36 - m.stopped = true 37 - } 38 - 39 - func (m *MockOpenBaoManager) IsStopped() bool { 40 - return m.stopped 41 34 } 42 35 43 36 func (m *MockOpenBaoManager) buildKey(repo DidSlashRepo, key string) string { ··· 109 118 } 110 119 } 111 120 121 + // Test MockOpenBaoManager interface compliance 122 + func TestMockOpenBaoManagerInterface(t *testing.T) { 123 + var _ Manager = (*MockOpenBaoManager)(nil) 124 + } 125 + 112 126 func TestOpenBaoManagerInterface(t *testing.T) { 113 127 var _ Manager = (*OpenBaoManager)(nil) 114 128 } ··· 121 125 func TestNewOpenBaoManager(t *testing.T) { 122 126 tests := []struct { 123 127 name string 124 - address string 125 - roleID string 126 - secretID string 128 + proxyAddr string 127 129 opts []OpenBaoManagerOpt 128 130 expectError bool 129 131 errorContains string 130 132 }{ 131 133 { 132 - name: "empty address", 133 - address: "", 134 - roleID: "test-role-id", 135 - secretID: "test-secret-id", 134 + name: "empty proxy address", 135 + proxyAddr: "", 136 136 opts: nil, 137 137 expectError: true, 138 - errorContains: "address cannot be empty", 138 + errorContains: "proxy address cannot be empty", 139 139 }, 140 140 { 141 - name: "empty role_id", 142 - address: "http://localhost:8200", 143 - roleID: "", 144 - secretID: "test-secret-id", 141 + name: "valid proxy address", 142 + proxyAddr: "http://localhost:8200", 145 143 opts: nil, 146 - expectError: true, 147 - errorContains: "role_id cannot be empty", 144 + expectError: true, // Will fail because no real proxy is running 145 + errorContains: "failed to connect to bao proxy", 148 146 }, 149 147 { 150 - name: "empty secret_id", 151 - address: "http://localhost:8200", 152 - roleID: "test-role-id", 153 - secretID: "", 154 - opts: nil, 155 - expectError: true, 156 - errorContains: "secret_id cannot be empty", 148 + name: "with mount path option", 149 + proxyAddr: "http://localhost:8200", 150 + opts: []OpenBaoManagerOpt{WithMountPath("custom-mount")}, 151 + expectError: true, // Will fail because no real proxy is running 152 + errorContains: "failed to connect to bao proxy", 157 153 }, 158 154 } 159 155 160 156 for _, tt := range tests { 161 157 t.Run(tt.name, func(t *testing.T) { 162 158 logger := slog.New(slog.NewTextHandler(os.Stderr, nil)) 163 - manager, err := NewOpenBaoManager(tt.address, tt.roleID, tt.secretID, logger, tt.opts...) 159 + manager, err := NewOpenBaoManager(tt.proxyAddr, logger, tt.opts...) 164 160 165 161 if tt.expectError { 166 162 assert.Error(t, err) 167 163 assert.Nil(t, manager) 168 164 assert.Contains(t, err.Error(), tt.errorContains) 169 165 } else { 170 - // For valid configurations, we expect an error during authentication 171 - // since we're not connecting to a real OpenBao server 172 - assert.Error(t, err) 173 - assert.Nil(t, manager) 166 + assert.NoError(t, err) 167 + assert.NotNil(t, manager) 174 168 } 175 169 }) 176 170 } ··· 237 251 opt(manager) 238 252 239 253 assert.Equal(t, "custom-mount", manager.mountPath) 240 - } 241 - 242 - func TestOpenBaoManager_Stop(t *testing.T) { 243 - // Create a manager with minimal setup 244 - manager := &OpenBaoManager{ 245 - mountPath: "test", 246 - stopCh: make(chan struct{}), 247 - } 248 - 249 - // Verify the manager implements Stopper interface 250 - var stopper Stopper = manager 251 - assert.NotNil(t, stopper) 252 - 253 - // Call Stop and verify it doesn't panic 254 - assert.NotPanics(t, func() { 255 - manager.Stop() 256 - }) 257 - 258 - // Verify the channel was closed 259 - select { 260 - case <-manager.stopCh: 261 - // Channel was closed as expected 262 - default: 263 - t.Error("Expected stop channel to be closed after Stop()") 264 - } 265 - } 266 - 267 - func TestOpenBaoManager_StopperInterface(t *testing.T) { 268 - manager := &OpenBaoManager{} 269 - 270 - // Verify that OpenBaoManager implements the Stopper interface 271 - _, ok := interface{}(manager).(Stopper) 272 - assert.True(t, ok, "OpenBaoManager should implement Stopper interface") 273 - } 274 - 275 - // Test MockOpenBaoManager interface compliance 276 - func TestMockOpenBaoManagerInterface(t *testing.T) { 277 - var _ Manager = (*MockOpenBaoManager)(nil) 278 - var _ Stopper = (*MockOpenBaoManager)(nil) 279 254 } 280 255 281 256 func TestMockOpenBaoManager_AddSecret(t *testing.T) { ··· 510 563 assert.NoError(t, err) 511 564 } 512 565 513 - func TestMockOpenBaoManager_Stop(t *testing.T) { 514 - mock := NewMockOpenBaoManager() 515 - 516 - assert.False(t, mock.IsStopped()) 517 - 518 - mock.Stop() 519 - 520 - assert.True(t, mock.IsStopped()) 521 - } 522 - 523 566 func TestMockOpenBaoManager_Integration(t *testing.T) { 524 567 tests := []struct { 525 568 name string ··· 562 625 t.Run(tt.name, func(t *testing.T) { 563 626 mock := NewMockOpenBaoManager() 564 627 tt.scenario(t, mock) 628 + }) 629 + } 630 + } 631 + 632 + func TestOpenBaoManager_ProxyConfiguration(t *testing.T) { 633 + tests := []struct { 634 + name string 635 + proxyAddr string 636 + description string 637 + }{ 638 + { 639 + name: "default_localhost", 640 + proxyAddr: "http://127.0.0.1:8200", 641 + description: "Should connect to default localhost proxy", 642 + }, 643 + { 644 + name: "custom_host", 645 + proxyAddr: "http://bao-proxy:8200", 646 + description: "Should connect to custom proxy host", 647 + }, 648 + { 649 + name: "https_proxy", 650 + proxyAddr: "https://127.0.0.1:8200", 651 + description: "Should connect to HTTPS proxy", 652 + }, 653 + } 654 + 655 + for _, tt := range tests { 656 + t.Run(tt.name, func(t *testing.T) { 657 + t.Log("Testing scenario:", tt.description) 658 + logger := slog.New(slog.NewTextHandler(os.Stderr, nil)) 659 + 660 + // All these will fail because no real proxy is running 661 + // but we can test that the configuration is properly accepted 662 + manager, err := NewOpenBaoManager(tt.proxyAddr, logger) 663 + assert.Error(t, err) // Expected because no real proxy 664 + assert.Nil(t, manager) 665 + assert.Contains(t, err.Error(), "failed to connect to bao proxy") 565 666 }) 566 667 } 567 668 }
+13 -6
spindle/secrets/policy.hcl
··· 1 - # KV v2 data operations 2 - path "spindle/data/*" { 1 + # Allow full access to the spindle KV mount 2 + path "spindle/*" { 3 3 capabilities = ["create", "read", "update", "delete", "list"] 4 4 } 5 5 6 - # KV v2 metadata operations (needed for listing) 6 + path "spindle/data/*" { 7 + capabilities = ["create", "read", "update", "delete"] 8 + } 9 + 7 10 path "spindle/metadata/*" { 8 11 capabilities = ["list", "read", "delete"] 9 12 } 10 13 11 - # Root path access (needed for mount-level operations) 12 - path "spindle/*" { 13 - capabilities = ["list"] 14 + # Allow listing mounts (for connection testing) 15 + path "sys/mounts" { 16 + capabilities = ["read"] 14 17 } 15 18 19 + # Allow token self-lookup (for health checks) 20 + path "auth/token/lookup-self" { 21 + capabilities = ["read"] 22 + }
+4 -12
spindle/server.go
··· 71 71 var vault secrets.Manager 72 72 switch cfg.Server.Secrets.Provider { 73 73 case "openbao": 74 - if cfg.Server.Secrets.OpenBao.Addr == "" { 75 - return fmt.Errorf("openbao address is required when using openbao secrets provider") 76 - } 77 - if cfg.Server.Secrets.OpenBao.RoleID == "" { 78 - return fmt.Errorf("openbao role_id is required when using openbao secrets provider") 79 - } 80 - if cfg.Server.Secrets.OpenBao.SecretID == "" { 81 - return fmt.Errorf("openbao secret_id is required when using openbao secrets provider") 74 + if cfg.Server.Secrets.OpenBao.ProxyAddr == "" { 75 + return fmt.Errorf("openbao proxy address is required when using openbao secrets provider") 82 76 } 83 77 vault, err = secrets.NewOpenBaoManager( 84 - cfg.Server.Secrets.OpenBao.Addr, 85 - cfg.Server.Secrets.OpenBao.RoleID, 86 - cfg.Server.Secrets.OpenBao.SecretID, 78 + cfg.Server.Secrets.OpenBao.ProxyAddr, 87 79 logger, 88 80 secrets.WithMountPath(cfg.Server.Secrets.OpenBao.Mount), 89 81 ) 90 82 if err != nil { 91 83 return fmt.Errorf("failed to setup openbao secrets provider: %w", err) 92 84 } 93 - logger.Info("using openbao secrets provider", "address", cfg.Server.Secrets.OpenBao.Addr, "mount", cfg.Server.Secrets.OpenBao.Mount) 85 + logger.Info("using openbao secrets provider", "proxy_address", cfg.Server.Secrets.OpenBao.ProxyAddr, "mount", cfg.Server.Secrets.OpenBao.Mount) 94 86 case "sqlite", "": 95 87 vault, err = secrets.NewSQLiteManager(cfg.Server.DBPath, secrets.WithTableName("secrets")) 96 88 if err != nil {