6 KiB
Secrets
Le package secretstore supporte plusieurs politiques de backend :
auto: comportement par défaut, utilise un backend keyring disponible et peut retomber sur l'environnement siLookupEnvest fournikwallet-only: impose KWallet et retourne une erreur explicite si KWallet n'est pas disponiblekeyring-any: impose l'utilisation d'un backend keyring disponibleenv-only: lecture seule depuis les variables d'environnementbitwarden-cli: utilise le CLI Bitwarden (bw) comme backend de vault
Backends keyring typiques :
- macOS : Keychain
- Linux : Secret Service ou KWallet selon l'environnement
- Windows : Credential Manager
Ouverture recommandée depuis la policy du manifeste runtime (mcp.toml résolu près de l'exécutable) :
store, err := secretstore.OpenFromManifest(secretstore.OpenFromManifestOptions{
ServiceName: "my-mcp",
LookupEnv: os.LookupEnv,
})
if err != nil {
return err
}
Exemple bas niveau :
store, err := secretstore.Open(secretstore.Options{
ServiceName: "my-mcp",
BackendPolicy: secretstore.BackendAuto,
})
if err != nil {
return err
}
if err := store.SetSecret("api-token", "My MCP API token", token); err != nil {
return err
}
token, err = store.GetSecret("api-token")
switch {
case err == nil:
// secret found
case errors.Is(err, secretstore.ErrNotFound):
// first run
default:
return err
}
Pour imposer KWallet sur Linux :
store, err := secretstore.Open(secretstore.Options{
ServiceName: "email-mcp",
BackendPolicy: secretstore.BackendKWalletOnly,
})
Pour imposer Bitwarden via son CLI :
store, err := secretstore.Open(secretstore.Options{
ServiceName: "email-mcp",
BackendPolicy: secretstore.BackendBitwardenCLI,
// Optionnel si `bw` n'est pas dans le PATH :
// BitwardenCommand: "/usr/local/bin/bw",
})
Pour vérifier explicitement que Bitwarden est prêt (login + unlock + BW_SESSION) :
if err := secretstore.EnsureBitwardenReady(secretstore.Options{
BitwardenCommand: "bw",
LookupEnv: os.LookupEnv,
}); err != nil {
switch {
case errors.Is(err, secretstore.ErrBWNotLoggedIn):
// guider vers `bw login`
case errors.Is(err, secretstore.ErrBWLocked):
// guider vers `bw unlock --raw` puis export BW_SESSION
default:
// indisponibilité CLI/réseau
}
return err
}
Pour lancer un flux interactif bw login / bw unlock --raw, récupérer BW_SESSION
et le persister localement (fichier 0600 sous le répertoire de config utilisateur) :
session, err := secretstore.LoginBitwarden(secretstore.BitwardenLoginOptions{
ServiceName: "email-mcp",
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
})
if err != nil {
return err
}
fmt.Println("session chargée:", len(session) > 0)
Pour réinjecter automatiquement une session persistée dans l'environnement courant :
loaded, err := secretstore.EnsureBitwardenSessionEnv(secretstore.BitwardenSessionOptions{
ServiceName: "email-mcp",
})
if err != nil {
return err
}
fmt.Println("session restaurée depuis disque:", loaded)
Pour stocker un secret structuré en JSON :
type Credentials struct {
Host string `json:"host"`
Username string `json:"username"`
Password string `json:"password"`
}
err = secretstore.SetJSON(store, "imap-credentials", "IMAP credentials", Credentials{
Host: "imap.example.com",
Username: "alice",
Password: token,
})
if err != nil {
return err
}
creds, err := secretstore.GetJSON[Credentials](store, "imap-credentials")
if err != nil {
return err
}
_ = creds
Pour écrire puis confirmer immédiatement une relecture :
if err := secretstore.SetSecretVerified(store, "api-token", "My MCP API token", token); err != nil {
return err
}
Pour connaître le backend effectif utilisé :
effective := secretstore.EffectiveBackendPolicy(store)
fmt.Println("backend effectif:", effective) // bitwarden-cli, env-only, keyring-any...
Pour obtenir en un seul appel une description runtime (source manifeste, policy déclarée/effective, disponibilité) :
desc, err := secretstore.DescribeRuntime(secretstore.DescribeRuntimeOptions{
ServiceName: "my-mcp",
LookupEnv: os.LookupEnv,
})
if err != nil {
return err
}
fmt.Println(secretstore.FormatBackendStatus(desc))
// declared=... effective=... display=... ready=... source=...
Pour un préflight réutilisable dans setup, config show et config test :
report, err := secretstore.PreflightFromManifest(secretstore.PreflightOptions{
ServiceName: "my-mcp",
LookupEnv: os.LookupEnv,
})
if err != nil {
return err
}
fmt.Println(report.Status) // ready | fail
fmt.Println(report.Summary) // message court
fmt.Println(report.Remediation) // action recommandée
Debug Bitwarden en 60 secondes
Tu peux activer les traces d'appels Bitwarden avec le flag CLI global --debug
(via bootstrap) ou en exportant MCP_FRAMEWORK_BITWARDEN_DEBUG=1.
Les commandes bw exécutées seront affichées (avec redaction des payloads sensibles).
- Vérifier l'état de session :
bw status
- Déverrouiller le vault et exporter
BW_SESSION(ou utiliserLoginBitwarden) :
- Bash/Zsh :
export BW_SESSION="$(bw unlock --raw)"
- Fish :
set -x BW_SESSION (bw unlock --raw)
- PowerShell :
$env:BW_SESSION = (bw unlock --raw)
- Vérifier lecture/écriture rapide :
if err := store.SetSecret("debug-token", "Debug token", "ok"); err != nil {
return err
}
_, err := store.GetSecret("debug-token")
return err
- Interpréter les erreurs typées :
secretstore.ErrBWNotLoggedIn:bw loginrequis.secretstore.ErrBWLocked: vault verrouillé ouBW_SESSIONabsent.secretstore.ErrBWUnavailable: CLI/réseau indisponible.secretstore.ErrBackendUnavailable: policy non satisfiable dans le contexte courant.
En mode env-only, GetSecret("API_TOKEN") lit la variable d'environnement API_TOKEN.
Les opérations d'écriture et de suppression retournent secretstore.ErrReadOnly.