This commit is contained in:
2026-01-22 22:20:11 +01:00
parent acf740ff46
commit 51d3ea0600
3 changed files with 250 additions and 11 deletions

View File

@@ -84,7 +84,7 @@ Créez une policy Vault pour accéder aux secrets OVH :
```bash ```bash
vault policy write cert-manager-webhook-ovh-policy - <<EOF vault policy write cert-manager-webhook-ovh-policy - <<EOF
path "secret/data/ovh" { path "secret/data/cert-manager-webhook-ovh" {
capabilities = ["read"] capabilities = ["read"]
} }
EOF EOF
@@ -94,16 +94,18 @@ Stockez les credentials OVH dans Vault :
```bash ```bash
# Pour Vault KV v2, utilisez cette commande : # Pour Vault KV v2, utilisez cette commande :
vault kv put secret/ovh \ vault kv put secret/cert-manager-webhook-ovh \
application-key="VOTRE_APPLICATION_KEY" \ application-key="VOTRE_APPLICATION_KEY" \
application-secret="VOTRE_APPLICATION_SECRET" \ application-secret="VOTRE_APPLICATION_SECRET" \
consumer-key="VOTRE_CONSUMER_KEY" consumer-key="VOTRE_CONSUMER_KEY"
# Vérifiez que le secret est bien stocké : # Vérifiez que le secret est bien stocké :
vault kv get secret/ovh vault kv get secret/cert-manager-webhook-ovh
``` ```
**Important** : Le format du chemin dans `remoteRef` pour External Secrets est `ovh#application-key` (sans le préfixe `secret/data/`), car le mount path `secret` est déjà défini dans le ClusterSecretStore. **Important** :
- Le format du chemin dans `remoteRef` pour External Secrets est `cert-manager-webhook-ovh#application-key` (sans le préfixe `secret/data/`), car le mount path `secret` est déjà défini dans le ClusterSecretStore.
- Le nom du secret dans Vault (`cert-manager-webhook-ovh`) doit correspondre exactement au nom utilisé dans `remoteRef`.
#### Configuration dans values.yaml #### Configuration dans values.yaml
@@ -115,9 +117,9 @@ externalSecret:
refreshInterval: "1h" refreshInterval: "1h"
secretName: "cert-manager-webhook-ovh" secretName: "cert-manager-webhook-ovh"
remoteRef: remoteRef:
applicationKey: "ovh#application-key" applicationKey: "cert-manager-webhook-ovh#application-key"
applicationSecret: "ovh#application-secret" applicationSecret: "cert-manager-webhook-ovh#application-secret"
consumerKey: "ovh#consumer-key" consumerKey: "cert-manager-webhook-ovh#consumer-key"
vault: vault:
secretStoreName: "vault-backend" secretStoreName: "vault-backend"
server: "https://vault.example.com:8200" server: "https://vault.example.com:8200"
@@ -162,6 +164,93 @@ kubectl describe externalsecret cert-manager-webhook-ovh -n cert-manager-ops --c
## Dépannage ## Dépannage
### Erreur "could not get secret data from provider" ou "permission denied"
Cette erreur indique que External Secrets Operator ne peut pas lire les secrets depuis Vault. Vérifiez les points suivants :
#### 1. Vérifier que le secret existe dans Vault
```bash
# Vérifier que le secret existe
vault kv get secret/cert-manager-webhook-ovh
# Si le secret n'existe pas, créez-le :
vault kv put secret/cert-manager-webhook-ovh \
application-key="VOTRE_APPLICATION_KEY" \
application-secret="VOTRE_APPLICATION_SECRET" \
consumer-key="VOTRE_CONSUMER_KEY"
```
#### 2. Vérifier la policy Vault
```bash
# Vérifier que la policy existe
vault policy read cert-manager-webhook-ovh-policy
# Si la policy n'existe pas, créez-la :
vault policy write cert-manager-webhook-ovh-policy - <<EOF
path "secret/data/cert-manager-webhook-ovh" {
capabilities = ["read"]
}
EOF
```
#### 3. Vérifier le rôle Vault et les permissions
```bash
# Vérifier la configuration du rôle
vault read auth/kubernetes/role/cert-manager-webhook-ovh-role
# Vérifier que le rôle utilise la bonne policy
# Le rôle doit avoir : policies = cert-manager-webhook-ovh-policy
```
#### 4. Vérifier que le ServiceAccount peut s'authentifier
```bash
# Vérifier que le ServiceAccount existe
kubectl get serviceaccount cert-manager-webhook-ovh-sa -n cert-manager-webhook-ovh-ops
# Vérifier les permissions RBAC
kubectl auth can-i use secret --namespace=cert-manager-webhook-ovh-ops \
--as=system:serviceaccount:cert-manager-webhook-ovh-ops:cert-manager-webhook-ovh-sa
```
#### 5. Vérifier la connexion à Vault
```bash
# Vérifier que le ClusterSecretStore peut se connecter à Vault
kubectl describe clustersecretstore vault-backend
# Vérifier les logs d'External Secrets Operator
kubectl logs -n external-secrets-system \
-l app.kubernetes.io/name=external-secrets \
--tail=50 | grep -i "vault\|error\|failed"
```
#### 6. Vérifier le format des chemins
Le format correct pour Vault KV v2 est `cert-manager-webhook-ovh#application-key` (sans le préfixe `secret/data/`).
Vérifiez dans `values.yaml` :
```yaml
remoteRef:
applicationKey: "cert-manager-webhook-ovh#application-key" # ✅ Correct
# ❌ Incorrect: "secret/data/cert-manager-webhook-ovh#application-key"
```
**Important** : Le nom du secret dans Vault doit correspondre exactement au nom utilisé dans `remoteRef` (ici `cert-manager-webhook-ovh`).
#### 7. Forcer une nouvelle synchronisation
```bash
# Forcer une synchronisation immédiate
kubectl annotate externalsecret cert-manager-webhook-ovh \
-n cert-manager-ops \
force-sync=$(date +%s) \
--overwrite
```
### Erreur "invalid bound_service_account_namespace_selector configured" ### Erreur "invalid bound_service_account_namespace_selector configured"
Cette erreur se produit lors de la création d'un rôle Vault. **Ne configurez PAS** `bound_service_account_namespace_selector`. Utilisez plutôt `bound_service_account_namespaces` : Cette erreur se produit lors de la création d'un rôle Vault. **Ne configurez PAS** `bound_service_account_namespace_selector`. Utilisez plutôt `bound_service_account_namespaces` :

View File

@@ -91,13 +91,14 @@ externalSecret:
# Références aux clés dans Vault # Références aux clés dans Vault
# Format pour Vault KV v2 avec External Secrets: # Format pour Vault KV v2 avec External Secrets:
# - Si le mount path est "secret" et le secret est dans "ovh": "ovh#application-key" # - Si le mount path est "secret" et le secret est dans "cert-manager-webhook-ovh": "cert-manager-webhook-ovh#application-key"
# - Le préfixe "secret/data/" n'est PAS nécessaire car il est géré par le ClusterSecretStore # - Le préfixe "secret/data/" n'est PAS nécessaire car il est géré par le ClusterSecretStore
# - Le format est: "chemin-du-secret#clef-dans-le-json" # - Le format est: "chemin-du-secret#clef-dans-le-json"
# ⚠️ IMPORTANT: Le nom du secret dans Vault doit correspondre exactement ici
remoteRef: remoteRef:
applicationKey: "ovh#application-key" # ⚠️ Chemin: secret/ovh avec clé application-key applicationKey: "cert-manager-webhook-ovh#application-key" # ⚠️ Chemin: secret/cert-manager-webhook-ovh avec clé application-key
applicationSecret: "ovh#application-secret" # ⚠️ Chemin: secret/ovh avec clé application-secret applicationSecret: "cert-manager-webhook-ovh#application-secret" # ⚠️ Chemin: secret/cert-manager-webhook-ovh avec clé application-secret
consumerKey: "ovh#consumer-key" # ⚠️ Chemin: secret/ovh avec clé consumer-key consumerKey: "cert-manager-webhook-ovh#consumer-key" # ⚠️ Chemin: secret/cert-manager-webhook-ovh avec clé consumer-key
# Configuration HashiCorp Vault # Configuration HashiCorp Vault
vault: vault:

View File

@@ -0,0 +1,149 @@
#!/bin/bash
# Script de vérification des permissions Vault pour External Secrets
set -e
VAULT_ROLE="${1:-cert-manager-webhook-ovh-role}"
VAULT_POLICY="${2:-cert-manager-webhook-ovh-policy}"
SERVICE_ACCOUNT="${3:-cert-manager-webhook-ovh-sa}"
NAMESPACE="${4:-cert-manager-webhook-ovh-ops}"
VAULT_SECRET_PATH="${5:-secret/cert-manager-webhook-ovh}"
echo "=== Vérification des permissions Vault ==="
echo "Rôle Vault: $VAULT_ROLE"
echo "Policy Vault: $VAULT_POLICY"
echo "ServiceAccount: $SERVICE_ACCOUNT"
echo "Namespace: $NAMESPACE"
echo "Chemin secret: $VAULT_SECRET_PATH"
echo ""
# 1. Vérifier que le secret existe dans Vault
echo "1. Vérification du secret dans Vault..."
if vault kv get "$VAULT_SECRET_PATH" &>/dev/null; then
echo " ✅ Secret trouvé dans Vault"
echo ""
echo " Contenu du secret:"
vault kv get "$VAULT_SECRET_PATH" | grep -E "application-key|application-secret|consumer-key" || true
echo ""
else
echo " ❌ Secret '$VAULT_SECRET_PATH' non trouvé dans Vault"
echo ""
echo " Créez le secret avec:"
echo " vault kv put $VAULT_SECRET_PATH \\"
echo " application-key=\"VOTRE_APPLICATION_KEY\" \\"
echo " application-secret=\"VOTRE_APPLICATION_SECRET\" \\"
echo " consumer-key=\"VOTRE_CONSUMER_KEY\""
echo ""
fi
# 2. Vérifier la policy Vault
echo "2. Vérification de la policy Vault '$VAULT_POLICY'..."
if vault policy read "$VAULT_POLICY" &>/dev/null; then
echo " ✅ Policy existe"
echo ""
echo " Contenu de la policy:"
vault policy read "$VAULT_POLICY"
echo ""
# Vérifier que la policy autorise la lecture du secret
SECRET_NAME=$(basename "$VAULT_SECRET_PATH")
if vault policy read "$VAULT_POLICY" | grep -q "secret/data/$SECRET_NAME"; then
echo " ✅ Policy autorise l'accès à secret/data/$SECRET_NAME"
else
echo " ⚠️ Policy ne semble pas autoriser l'accès à secret/data/$SECRET_NAME"
echo " Créez la policy avec:"
echo " vault policy write $VAULT_POLICY - <<EOF"
echo " path \"secret/data/$SECRET_NAME\" {"
echo " capabilities = [\"read\"]"
echo " }"
echo " EOF"
fi
echo ""
else
echo " ❌ Policy '$VAULT_POLICY' n'existe pas"
echo ""
echo " Créez la policy avec:"
echo " vault policy write $VAULT_POLICY - <<EOF"
echo " path \"secret/data/ovh\" {"
echo " capabilities = [\"read\"]"
echo " }"
echo " EOF"
echo ""
fi
# 3. Vérifier le rôle Vault
echo "3. Vérification du rôle Vault '$VAULT_ROLE'..."
if vault read "auth/kubernetes/role/$VAULT_ROLE" &>/dev/null; then
echo " ✅ Rôle existe"
echo ""
echo " Configuration du rôle:"
vault read "auth/kubernetes/role/$VAULT_ROLE" | grep -E "bound_service_account|policies|ttl" || true
echo ""
# Vérifier que le rôle utilise la bonne policy
if vault read "auth/kubernetes/role/$VAULT_ROLE" | grep -q "$VAULT_POLICY"; then
echo " ✅ Rôle utilise la policy '$VAULT_POLICY'"
else
echo " ⚠️ Rôle ne semble pas utiliser la policy '$VAULT_POLICY'"
echo " Vérifiez avec: vault read auth/kubernetes/role/$VAULT_ROLE"
fi
# Vérifier les ServiceAccounts autorisés
BOUND_SA=$(vault read "auth/kubernetes/role/$VAULT_ROLE" -format=json 2>/dev/null | jq -r '.data.bound_service_account_names[]' 2>/dev/null || echo "")
if echo "$BOUND_SA" | grep -q "$SERVICE_ACCOUNT"; then
echo " ✅ ServiceAccount '$SERVICE_ACCOUNT' est autorisé"
else
echo " ⚠️ ServiceAccount '$SERVICE_ACCOUNT' n'est pas dans bound_service_account_names"
echo " Rôle autorise: $BOUND_SA"
fi
# Vérifier les namespaces autorisés
BOUND_NS=$(vault read "auth/kubernetes/role/$VAULT_ROLE" -format=json 2>/dev/null | jq -r '.data.bound_service_account_namespaces[]' 2>/dev/null || echo "")
if echo "$BOUND_NS" | grep -q "$NAMESPACE"; then
echo " ✅ Namespace '$NAMESPACE' est autorisé"
else
echo " ⚠️ Namespace '$NAMESPACE' n'est pas dans bound_service_account_namespaces"
echo " Rôle autorise: $BOUND_NS"
fi
echo ""
else
echo " ❌ Rôle '$VAULT_ROLE' n'existe pas"
echo ""
echo " Créez le rôle avec:"
echo " vault write auth/kubernetes/role/$VAULT_ROLE \\"
echo " bound_service_account_names=$SERVICE_ACCOUNT \\"
echo " bound_service_account_namespaces=$NAMESPACE,cert-manager-ops \\"
echo " policies=$VAULT_POLICY \\"
echo " ttl=1h"
echo ""
fi
# 4. Vérifier le ServiceAccount Kubernetes
echo "4. Vérification du ServiceAccount Kubernetes..."
if kubectl get serviceaccount "$SERVICE_ACCOUNT" -n "$NAMESPACE" &>/dev/null; then
echo " ✅ ServiceAccount existe"
kubectl get serviceaccount "$SERVICE_ACCOUNT" -n "$NAMESPACE" -o wide
echo ""
else
echo " ❌ ServiceAccount '$SERVICE_ACCOUNT' n'existe pas dans '$NAMESPACE'"
echo ""
fi
# 5. Résumé et actions recommandées
echo "=== Résumé ==="
echo ""
echo "Si toutes les vérifications passent mais que l'erreur 403 persiste:"
echo ""
echo "1. Vérifiez que le mount Kubernetes dans Vault est correctement configuré:"
echo " vault read auth/kubernetes/config"
echo ""
echo "2. Testez l'authentification manuellement:"
echo " # Récupérer le token du ServiceAccount"
echo " TOKEN=\$(kubectl get secret -n $NAMESPACE -o jsonpath='{.items[?(@.metadata.annotations.kubernetes\\.io/service-account\\.name==\"$SERVICE_ACCOUNT\")].data.token}' | head -1 | base64 -d)"
echo " # Tester l'authentification"
echo " vault write auth/kubernetes/login role=$VAULT_ROLE jwt=\"\$TOKEN\""
echo ""
echo "3. Vérifiez les logs d'External Secrets Operator:"
echo " kubectl logs -n external-secrets-system -l app.kubernetes.io/name=external-secrets --tail=50 | grep -i vault"
echo ""