feat: wire Infisical secret store into API server and MCP tools
- Wire secretsManager in NewHandler() — instantiate InfisicalBackend when OIKOS_INFISICAL_SITE_URL is set (previously always nil) - Add get_secret, list_secrets, set_secret MCP tools with nil-backend graceful degradation - Add oikos secret get|set|list CLI subcommands for Infisical - Fix Set() bug: create-before-update so new keys are created; add Type: "shared" to Update so it finds the right secret; disable SDK cache so Get returns fresh data after Set - Clean enrollment response: remove fake infisical_client_id/ infisical_client_secret stubs, store age key in Infisical for real
This commit is contained in:
@@ -31,14 +31,13 @@ type InfisicalConfig struct {
|
||||
// NewInfisicalBackend creates an Infisical backend. Connects lazily on first Get.
|
||||
func NewInfisicalBackend(cfg InfisicalConfig) *InfisicalBackend {
|
||||
autoRefresh := true
|
||||
cacheExpiry := 300 // 5 min cache
|
||||
|
||||
return &InfisicalBackend{
|
||||
cfg: cfg,
|
||||
client: infisical.NewInfisicalClient(context.Background(), infisical.Config{
|
||||
SiteUrl: cfg.SiteURL,
|
||||
AutoTokenRefresh: &autoRefresh,
|
||||
CacheExpiryInSeconds: cacheExpiry,
|
||||
CacheExpiryInSeconds: 0, // no caching — live reads over localhost
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -130,22 +129,24 @@ func (b *InfisicalBackend) Set(ctx context.Context, key string, value string) er
|
||||
return err
|
||||
}
|
||||
|
||||
// Try update first, fall back to create
|
||||
_, err := b.client.Secrets().Update(infisical.UpdateSecretOptions{
|
||||
SecretKey: key,
|
||||
NewSecretValue: value,
|
||||
Environment: b.cfg.Env,
|
||||
SecretPath: b.cfg.SecretPath,
|
||||
ProjectID: b.cfg.ProjectID,
|
||||
// Try create first (idempotent — upserts); fall back to update on conflict.
|
||||
_, err := b.client.Secrets().Create(infisical.CreateSecretOptions{
|
||||
SecretKey: key,
|
||||
SecretValue: value,
|
||||
Environment: b.cfg.Env,
|
||||
SecretPath: b.cfg.SecretPath,
|
||||
ProjectID: b.cfg.ProjectID,
|
||||
Type: "shared",
|
||||
})
|
||||
if err != nil {
|
||||
_, err = b.client.Secrets().Create(infisical.CreateSecretOptions{
|
||||
SecretKey: key,
|
||||
SecretValue: value,
|
||||
Environment: b.cfg.Env,
|
||||
SecretPath: b.cfg.SecretPath,
|
||||
ProjectID: b.cfg.ProjectID,
|
||||
Type: "shared",
|
||||
// Create failed (key may already exist) — update instead.
|
||||
_, err = b.client.Secrets().Update(infisical.UpdateSecretOptions{
|
||||
SecretKey: key,
|
||||
NewSecretValue: value,
|
||||
Environment: b.cfg.Env,
|
||||
SecretPath: b.cfg.SecretPath,
|
||||
ProjectID: b.cfg.ProjectID,
|
||||
Type: "shared",
|
||||
})
|
||||
}
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user