Stocker des clés de compte de service dans Hashicorp Vault

Stocker des secrets de compte de service dans HashiCorp Vault

Cette fonctionnalité vous permet de stocker les certificats de compte de service Google pour Apigee hybrid dans Hashicorp Vault, un gestionnaire de secrets externe. Les gestionnaires de secrets externes vous permettent de gérer la façon dont les données sont stockées dans Kubernetes, y compris la gestion de la résidence des données et des contrôles d'accès précis.

Si vous n'utilisez pas Workload Identity sur les clusters GKE ni la fédération d'identité de charge de travail sur EKS et AKS, vos composants Apigee hybrid doivent authentifier les comptes de service Google pour pouvoir effectuer leurs tâches. Il existe trois méthodes pour stocker des clés de compte de service Google et y faire référence dans Apigee hybrid:

  • Fichiers de certificat de compte de service (fichiers .json) stockés sur un disque dur. Reportez-vous à ces valeurs dans vos remplacements à l'aide de la propriété de configuration serviceAccountPath. Exemple :
    logger:
      serviceAccountPath: service-accounts/myhybridorg-apigee-logger.json
    
  • Fichiers de certificat de compte de service (fichiers .json) stockés sur un disque dur. Reportez-vous à ces valeurs dans vos remplacements à l'aide de la propriété de configuration serviceAccountPath. Consultez la section À propos des comptes de service.
  • Certificats de compte de service stockés dans un secret Kubernetes. Référencez-les dans vos remplacements avec la propriété de configuration serviceAccountRef. Consultez la section Stocker des données dans un secret Kubernetes.
  • Certificats de compte de service stockés dans Hashicorp Vault, comme expliqué dans ce guide Référencez-les dans vos remplacements avec la propriété de configuration serviceAccountSecretProviderClass.

Configurer le stockage des codes secrets des comptes de service dans Vault

Installer le pilote CSI et le fournisseur Vault

Si vous n'avez pas encore installé le pilote CSI sur votre cluster à l'aide de Helm, suivez les instructions de la section Pilote CSI Secrets Store: installation. Pour en savoir plus, consultez la section Installer le fournisseur CSI Vault dans la documentation Vault.

Consultez Plates-formes et versions compatibles avec Apigee hybrid pour connaître les versions minimales du pilote CSI compatibles avec Apigee hybrid.

Créer des secrets, des règles et des rôles Vault

Utilisez l'UI ou les API Vault pour créer des secrets et accorder des autorisations aux comptes de service Kubernetes utilisés par Apigee hybrid pour lire ces secrets.

  1. Créez les secrets spécifiques à l'organisation et à l'environnement au format suivant :
    Clé secrèteDonnées secrètes
    secret/data/apigee/orgsakeys
    {
      "cassandraBackup": "***",
      "cassandraRestore": "***",
      "connectAgent": "***",
      "logger": "***",
      "mart": "***",
      "metrics": "***",
      "mint": "***",
      "udca": "***",
      "watcher": "***"
    }
    secret/data/apigee/envsakeys-ENV_NAME
    {
      "runtime": "***",
      "synchronizer": "***",
      "udca": "***". 
    }

    Remplacez "***" dans chaque paire par le contenu du fichier .json pour le compte de service Google correspondant au composant Apigee. apigee-cassandra-backup et apigee-cassandra-restore utilisent tous deux le compte de service apigee-cassandra. Exemple :

    {
      "cassandraBackup": "{
        "type": "service_account",
        "project_id": "myhybridorg",
        "private_key_id": "PRIVATE_KEY_ID",
        "private_key": "-----BEGIN PRIVATE KEY-----\nPRIVATE_KEY_TEXT\n-----END PRIVATE KEY-----\n",
        "client_email": "apigee-cassandra@myhybridorg.iam.gserviceaccount.com",
        "client_id": "123456789012345678901",
        "auth_uri": "https://accounts.google.com/o/oauth2/auth",
        "token_uri": "https://oauth2.googleapis.com/token",
        "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
        "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/apigee-cassandra%40myhybridorg.iam.gserviceaccount.com",
        "universe_domain": "googleapis.com"
      }",
      "cassandraRestore":...
    ...
    }
        
  2. Accordez l'accès au secret de l'organisation. Créez un fichier texte nommé orgsakeys-auth-policy.txt avec le contenu suivant :
    path "secret/data/apigee/orgsakeys" {
      capabilities = ["read"]
    }
  3. Dans Vault, créez une règle autorisant l'accès au secret de l'organisation:
    vault policy write apigee-orgsakeys-auth orgsakeys-auth-policy.txt
  4. Pour chaque environnement, créez un fichier texte nommé envsakeys-ENV_NAME-auth-policy.txt avec le contenu suivant :
    path "secret/data/apigee/envsakeys-ENV_NAME" {
      capabilities = ["read"]
    }

    Répétez cette étape pour chaque environnement :

  5. Dans Vault, créez une règle accordant l'accès au secret de l'environnement:
    vault policy write apigee-envsakeys-ENV_NAME-auth envsakeys-ENV_NAME-auth-policy.txt

    Répétez cette étape pour chaque environnement :

  6. Créez un script nommé generate-encoded-sas.sh avec le contenu suivant :
    # generate-encoded-sas.sh
    
    ORG=$APIGEE_ORG            # Apigee organization name
    ENVS=$APIGEE_ENV_LIST      # comma separated env names, for example: dev,prod
    
    ORG_SHORT_NAME=$(echo $ORG | head -c 15)
    ENCODE=$(echo -n $ORG | shasum -a 256 | head -c 7)
    ORG_ENCODE=$(echo "$ORG_SHORT_NAME-$ENCODE")
    NAMES=apigee-manager,apigee-cassandra-default,apigee-cassandra-backup-sa,apigee-cassandra-restore-sa,apigee-cassandra-schema-setup-${ORG_ENCODE},apigee-cassandra-schema-val-${ORG_ENCODE},apigee-cassandra-user-setup-${ORG_ENCODE},apigee-mart-${ORG_ENCODE},apigee-mint-task-scheduler-${ORG_ENCODE},apigee-connect-agent-${ORG_ENCODE},apigee-watcher-${ORG_ENCODE},apigee-udca-${ORG_ENCODE},apigee-metrics-apigee-telemetry,apigee-open-telemetry-collector-apigee-telemetry,apigee-logger-apigee-telemetry
    
    for ENV in ${ENVS//,/ }
    do
      ENV_SHORT_NAME=$(echo $ENV | head -c 15)
      ENCODE=$(echo -n $ORG:$ENV | shasum -a 256 | head -c 7)
      ENV_ENCODE=$(echo "$ORG_SHORT_NAME-$ENV_SHORT_NAME-$ENCODE")
      NAMES+=,apigee-synchronizer-${ENV_ENCODE},apigee-runtime-${ENV_ENCODE}
    done
    
    echo $NAMES
    
  7. Exécutez le script pour générer la liste des noms de comptes de service à laquelle lier la règle:
    ./generate-encoded-sas.sh

    Vous devriez obtenir la liste des noms de comptes de service Kubernetes séparés par une virgule, comme dans l'exemple suivant:

    ./generate-encoded-sas.sh
    apigee-manager,apigee-cassandra-default,apigee-cassandra-backup-sa,
    apigee-cassandra-restore-sa,apigee-cassandra-schema-setup-myhybrido
    rg-5b044c1,apigee-cassandra-schema-val-myhybridorg-5b044c1,apigee-c
    assandra-user-setup-myhybridorg-5b044c1,apigee-mart-myhybridorg-5b0
    44c1,apigee-mint-task-scheduler-myhybridorg-5b044c1,apigee-connect-
    agent-myhybridorg-5b044c1,apigee-watcher-myhybridorg-5b044c1,apigee
    -udca-myhybridorg-5b044c1,apigee-metrics-apigee-telemetry,apigee-op
    en-telemetry-collector-apigee-telemetry,apigee-logger-apigee-teleme
    try,apigee-synchronizer-myhybridorg-dev-ee52aca,apigee-runtime-myhy
    bridorg-dev-ee52aca,apigee-synchronizer-myhybridorg-prod-2d0221c,ap
    igee-runtime-myhybridorg-prod-2d0221c
  8. Copiez le texte de sortie et séparez-le en listes, une liste pour les noms de compte de service org et une liste distincte pour le nom de compte de service env pour chaque environnement. Les comptes de service de type org apparaissent en premier dans la liste de sortie jusqu'à apigee-logger-apigee-telemetry.

    org de l'exemple précédent :

    apigee-manager,apigee-cassandra-default,apigee-cassandra-backup-sa,
    apigee-cassandra-restore-sa,apigee-cassandra-schema-setup-myhybrido
    rg-5b044c1,apigee-cassandra-schema-val-myhybridorg-5b044c1,apigee-c
    assandra-user-setup-myhybridorg-5b044c1,apigee-mart-myhybridorg-5b0
    44c1,apigee-mint-task-scheduler-myhybridorg-5b044c1,apigee-connect-
    agent-myhybridorg-5b044c1,apigee-watcher-myhybridorg-5b044c1,apigee
    -udca-myhybridorg-5b044c1,apigee-metrics-apigee-telemetry,apigee-op
    en-telemetry-collector-apigee-telemetry,apigee-logger-apigee-teleme
    try

    Les noms de compte de service env suivent le format apigee-synchronizer-ORG_NAME-ENV_NAME-HASH_TEXT et apigee-runtime-ORG_NAME-ENV_NAME-HASH_TEXT. Séparez-les en listes distinctes pour chaque environnement. Par exemple, la sortie de l'exemple précédent peut être séparée en deux listes :

    Environnement dev :

    apigee-synchronizer-myhybridorg-dev-ee52aca,apigee-runtime-myhybrid
    org-dev-ee52aca

    Environnement prod :

    apigee-synchronizer-myhybridorg-prod-2d0221c,apigee-runtime-myhybri
    dorg-prod-2d0221c
  9. À l'aide de la règle, créez un rôle Vault qui lie les comptes de service Apigee spécifiques à l'organisation :
    vault write auth/kubernetes/role/apigee-orgsakeys \
        bound_service_account_names=LIST_OF_ORG_SA_NAMES \
        bound_service_account_namespaces=apigee \
        policies=apigee-orgsakeys-auth \
        ttl=1m
    
  10. Pour chaque environnement, créez un rôle Vault pour ses clés de compte de service:
    vault write auth/kubernetes/role/apigee-envsakeys-ENV_NAME \
        bound_service_account_names=LIST_OF_ENV_NAME_SA_NAMES \
        bound_service_account_namespaces=apigee \
        policies=apigee-envsakeys-ENV_NAME-auth \ 
        ttl=1m
    

    Répétez cette étape pour chaque environnement.

Créer des objets SecretProviderClass

La ressource SecretProviderClass indique au pilote CSI avec quel fournisseur il doit communiquer lorsqu'il demande des secrets. Les clés du compte de service doivent être configurées via cet objet. Le tableau suivant présente les noms de fichiers (objectNames) attendus par Apigee hybrid:

Compte de serviceNoms de fichiers de secrets attendus
Sauvegarde Cassandra cassandraBackup
Restauration de Cassandra cassandraRestore
Connexion de l'agent connectAgent
Logger logger
MART mart
Métriques metrics
Monétisation mint
Exécution runtime
Synchronisateur synchronizer
UDCA udca
Watcher watcher
  1. Utilisez le modèle SecretProviderClass suivant pour configurer cette ressource pour les secrets spécifiques à l'organisation :
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: apigee-orgsakeys-spc
    spec:
      provider: vault
      parameters:
        roleName: apigee-orgsakeys
        vaultAddress: VAULT_ADDRESS
        # "objectName" is an alias used within the SecretProviderClass to reference
        # that specific secret. This will also be the filename containing the secret.
        # Apigee Hybrid expects these exact values so they must not be changed.
        # "secretPath" is the path in Vault where the secret should be retrieved.
        # "secretKey" is the key within the Vault secret response to extract a value from.
        objects: |
          - objectName: "cassandraBackup"
            secretPath: ""
            secretKey: ""
          - objectName: "cassandraRestore"
            secretPath: ""
            secretKey: ""
          - objectName: "connectAgent"
            secretPath: ""
            secretKey: ""
          - objectName: "logger"
            secretPath: ""
            secretKey: ""
          - objectName: "mart"
            secretPath: ""
            secretKey: ""
          - objectName: "metrics"
            secretPath: ""
            secretKey: ""
          - objectName: "mint"
            secretPath: ""
            secretKey: ""
          - objectName: "udca"
            secretPath: ""
            secretKey: ""
          - objectName: "watcher"
            secretPath: ""
            secretKey: ""
    

    VAULT_ADDRESS est le point de terminaison sur lequel votre serveur Vault est exécuté. Si Vault s'exécute dans le même cluster qu'Apigee, le format est généralement http://vault.APIGEE_NAMESPACE.svc.cluster.local:VAULT_SERVICE_PORT.

    Enregistrez le modèle dans un fichier nommé spc-org.yaml.

  2. Appliquez la SecretProviderClass spécifique à l'organisation à votre espace de noms apigee :
    kubectl -n APIGEE_NAMESPACE apply -f spc-org.yaml
  3. Pour chaque environnement, utilisez le modèle SecretProviderClass suivant pour configurer cette ressource pour les secrets spécifiques à l'environnement. Répétez cette étape pour chaque environnement:
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: apigee-envsakeys-ENV_NAME-spc
    spec:
      provider: vault
      parameters:
        roleName: apigee-envsakeys-ENV_NAME
        vaultAddress: VAULT_ADDRESS
        # "objectName" is an alias used within the SecretProviderClass to reference
        # that specific secret. This will also be the filename containing the secret.
        # Apigee Hybrid expects these exact values so they must not be changed.
        # "secretPath" is the path in Vault where the secret should be retrieved.
        # "secretKey" is the key within the Vault secret response to extract a value from.
        objects: |
          - objectName: "runtime"
            secretPath: ""
            secretKey: ""
          - objectName: "synchronizer"
            secretPath: ""
            secretKey: ""
          - objectName: "udca"
            secretPath: ""
            secretKey: ""
    

    VAULT_ADDRESS est le point de terminaison sur lequel votre serveur Vault est exécuté. Si Vault s'exécute dans le même cluster et le même espace de noms qu'Apigee, le format est généralement http://vault.APIGEE_NAMESPACE.svc.cluster.local:VAULT_SERVICE_PORT.

    Enregistrez le modèle dans un fichier nommé spc-env-ENV_NAME.yaml.

  4. Pour chaque environnement, appliquez la SecretProviderClass spécifique à l'environnement à votre espace de noms Apigee:
    kubectl -n APIGEE_NAMESPACE apply -f spc-env-ENV_NAME.yaml

    Répétez cette étape pour chaque environnement.

Activer les secrets externes pour les comptes de service Google

  1. Dans votre fichier de remplacement, ajoutez les propriétés de configuration serviceAccountSecretProviderClass et envs[].serviceAccountSecretProviderClass pour activer l'utilisation de secrets externes pour les comptes de service Google. Vous pouvez supprimer ou commenter les propriétés de configuration serviceAccountPath et serviceAccountPaths :
    serviceAccountSecretProviderClass: apigee-orgsakeys-spc
    
    envs:
      - name: ENV_NAME
        serviceAccountSecretProviderClass: apigee-envsakeys-ENV_NAME-spc
  2. Appliquez chaque graphique Helm :
    helm upgrade datastore apigee-datastore/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    
    helm upgrade telemetry apigee-telemetry/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    
    helm upgrade redis apigee-redis/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    
    helm upgrade ORG_NAME apigee-org/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    
  3. Pour chaque environnement, appliquez le graphique apigee-env :
    helm upgrade ENV_NAME apigee-env/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --set env=ENV_NAME \
        --atomic \
        -f overrides.yaml
    

Revenir à l'utilisation de fichiers de certificats de compte de service

Si vous devez effectuer un rollback vers l'utilisation des fichiers de certificat de compte de service Google stockés, procédez comme suit:

  1. Mettez à jour votre fichier de remplacement :
    1. Supprimez ou passez en commentaire les lignes serviceAccountSecretProviderClass et envs:serviceAccountSecretProviderClass.
    2. Ajoutez les propriétés de configuration serviceAccountPath et serviceAccountPaths avec les chemins d'accès aux comptes de service appropriés.

    Exemple :

    # serviceAccountSecretProviderClass: apigee-orgsakeys-spc - (commented out)
    
    cassandra:
      backup:
        serviceAccountPath: service-accounts/myhybridorg-apigee-cassandra.json
      restore:
        serviceAccountPath: service-accounts/myhybridorg-apigee-cassandra.json
    
    connectAgent:
      serviceAccountPath: service-accounts/myhybridorg-apigee-mart.json
    
    envs:
      - name: test
      # serviceAccountSecretProviderClass: apigee-envsakeys-spc - (commented out)
        serviceAccountPaths:
          runtime: service-accounts/myhybridorg-apigee-runtime.json
          synchronizer: service-accounts/myhybridorg-apigee-synchronizer.json
    
    logger:
      serviceAccountPath: service-accounts/myhybridorg-apigee-logger.json
    
    mart:
      serviceAccountPath: service-accounts/myhybridorg-apigee-mart.json
    
    metrics:
      serviceAccountPath: service-accounts/myhybridorg-apigee-metrics.json
    
    udca:
      serviceAccountPath: service-accounts/myhybridorg-apigee-udca.json
    
    watcher:
      serviceAccountPath: service-accounts/myhybridorg-apigee-watcher.json
    
  2. Appliquez chaque graphique Helm :
    helm upgrade datastore apigee-datastore/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    
    helm upgrade telemetry apigee-telemetry/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    
    helm upgrade redis apigee-redis/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    
    helm upgrade ORG_NAME apigee-org/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    
  3. Pour chaque environnement, appliquez le graphique apigee-env :
    helm upgrade ENV_NAME apigee-env/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --set env=ENV_NAME \
        --atomic \
        -f overrides.yaml
    

    Répétez cette étape pour chaque environnement.