Como armazenar chaves de conta de serviço no Hashicorp Vault

Como armazenar secrets de conta de serviço no Hashicorp Vault

Esse recurso permite armazenar certificados de conta de serviço do Google para a Apigee híbrida no Hashicorp Vault, um gerenciador de segredos externo. Com os gerenciadores de secrets externos, você gerencia a forma como os dados são armazenados no Kubernetes, incluindo o gerenciamento da residência de dados e os controles de acesso refinados.

Se você não estiver usando a Identidade da carga de trabalho em clusters do GKE ou a Federação de identidade da carga de trabalho no EKS e no AKS, os componentes híbridos da Apigee vão precisar autenticar as contas de serviço do Google para realizar as tarefas. Há três métodos para armazenar e se referir a chaves de contas de serviço do Google na Apigee híbrida:

  • Arquivos de certificado da conta de serviço (arquivos .json) armazenados em um disco rígido. Consulte esses valores nas substituições com a propriedade de configuração serviceAccountPath. Exemplo:
    logger:
      serviceAccountPath: service-accounts/myhybridorg-apigee-logger.json
    
  • Arquivos de certificado da conta de serviço (arquivos .json) armazenados em um disco rígido. Consulte esses valores nas substituições com a propriedade de configuração serviceAccountPath. Consulte Sobre contas de serviço.
  • Certificados da conta de serviço armazenados em um secret do Kubernetes. Consulte-os nas substituições com a propriedade de configuração serviceAccountRef. Consulte Como armazenar dados em um secret do Kubernetes
  • Certificados da conta de serviço armazenados no Hashicorp Vault, explicados neste guia. Consulte-os nas substituições com a propriedade de configuração serviceAccountSecretProviderClass.

Configurar para armazenar secrets de contas de serviço no Vault

Instalar o driver CSI e o provedor do Vault

Se você ainda não instalou o driver CSI no cluster usando o Helm, siga as instruções em Driver CSI do Secrets Store: instalação (em inglês). Para mais informações, consulte Como instalar o provedor CSI do Vault na documentação do Vault.

Acesse Plataformas e versões compatíveis com a Apigee híbrida para ver as versões mínimas de drivers CSI compatíveis com a Apigee híbrida.

Criar secrets, políticas e papéis do Vault

Use a interface ou as APIs do Vault para criar segredos e conceder permissões às contas de serviço do Kubernetes usadas pela Apigee híbrida para ler esses segredos.

  1. Crie os secrets específicos da organização e do ambiente no seguinte formato:
    Chave secretaDados de secret
    secret/data/apigee/orgsakeys
    {
      "cassandraBackup": "***",
      "cassandraRestore": "***",
      "connectAgent": "***",
      "logger": "***",
      "mart": "***",
      "metrics": "***",
      "mint": "***",
      "udca": "***",
      "watcher": "***"
    }
    secret/data/apigee/envsakeys-ENV_NAME
    {
      "runtime": "***",
      "synchronizer": "***",
      "udca": "***". 
    }

    Substitua o "***" em cada par pelo conteúdo do arquivo .json da conta de serviço do Google correspondente ao componente da Apigee. apigee-cassandra-backup e apigee-cassandra-restore usam a conta de serviço apigee-cassandra. Exemplo:

    {
      "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. Conceda acesso ao secret da organização. Crie um arquivo de texto chamado orgsakeys-auth-policy.txt com o seguinte conteúdo:
    path "secret/data/apigee/orgsakeys" {
      capabilities = ["read"]
    }
  3. No Vault, crie uma política que conceda acesso ao secret da organização:
    vault policy write apigee-orgsakeys-auth orgsakeys-auth-policy.txt
  4. Para cada ambiente, crie um arquivo de texto chamado envsakeys-ENV_NAME-auth-policy.txt com o seguinte conteúdo:
    path "secret/data/apigee/envsakeys-ENV_NAME" {
      capabilities = ["read"]
    }

    Repita esta etapa para cada ambiente:

  5. No Vault, crie uma política que conceda acesso ao secret do ambiente:
    vault policy write apigee-envsakeys-ENV_NAME-auth envsakeys-ENV_NAME-auth-policy.txt

    Repita esta etapa para cada ambiente:

  6. Crie um script chamado generate-encoded-sas.sh com o seguinte conteúdo:
    # 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. Execute o script para gerar a lista de nomes da conta de serviço e vincular a política a:
    ./generate-encoded-sas.sh

    A saída será uma lista de nomes de contas de serviço do Kubernetes separados por vírgulas, semelhante ao exemplo a seguir:

    ./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. Copie o texto de saída e o separe em listas, uma para os nomes das contas de serviço org e outra para os nomes das contas de serviço env de cada ambiente. As contas de serviço da organização são as primeiras na lista de saída até apigee-logger-apigee-telemetry.

    A lista de nomes de serviço da org do exemplo anterior:

    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

    Os nomes das contas de serviço env têm o padrão apigee-synchronizer-ORG_NAME-ENV_NAME-HASH_TEXT e apigee-runtime-ORG_NAME-ENV_NAME-HASH_TEXT. Separe-as em listas separadas para cada ambiente. Por exemplo, a saída do exemplo anterior pode ser separada nas duas listas a seguir:

    ambiente dev.

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

    ambiente prod:

    apigee-synchronizer-myhybridorg-prod-2d0221c,apigee-runtime-myhybri
    dorg-prod-2d0221c
  9. Usando a política, crie um papel do Vault que vincule as contas de serviço do Apigee específicas da organização:
    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. Crie um papel do Vault para as chaves das contas de serviço de cada ambiente:
    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
    

    Repita essa etapa para cada ambiente.

Criar objetos SecretProviderClass

O recurso SecretProviderClass informa ao driver CSI com qual provedor se comunicar ao solicitar secrets. As chaves da conta de serviço precisam ser configuradas por meio desse objeto. A tabela a seguir mostra os nomes de arquivo (objectNames) esperados pela Apigee híbrida:

Conta de serviçoNomes de arquivos de secrets esperados
Backup do Cassandra cassandraBackup
Restauração do Cassandra cassandraRestore
Agente do Connect connectAgent
Logger logger
MART mart
Métricas metrics
Monetização mint
Ambiente de execução runtime
Sincronizador synchronizer
UDCA udca
Watcher watcher
  1. Use o seguinte modelo de SecretProviderClass para configurar este recurso para os segredos específicos da organização:
    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 é o endpoint em que o servidor do Vault está em execução. Se o Vault estiver sendo executado no mesmo cluster que a Apigee, o formato geralmente será http://vault.APIGEE_NAMESPACE.svc.cluster.local:VAULT_SERVICE_PORT.

    Salve o modelo em um arquivo chamado spc-org.yaml.

  2. Aplique o SecretProviderClass específico da organização ao seu namespace da Apigee:
    kubectl -n APIGEE_NAMESPACE apply -f spc-org.yaml
  3. Para cada ambiente, use o seguinte modelo de SecretProviderClass para configurar esse recurso para os segredos específicos do ambiente. Repita essa etapa para cada ambiente:
    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 é o endpoint em que o servidor do Vault está em execução. Se o Vault estiver sendo executado no mesmo cluster e namespace que a Apigee, o formato geralmente será http://vault.APIGEE_NAMESPACE.svc.cluster.local:VAULT_SERVICE_PORT.

    Salve o modelo em um arquivo chamado spc-env-ENV_NAME.yaml.

  4. Para cada ambiente, aplique o SecretProviderClass específico ao ambiente ao seu namespace do Apigee:
    kubectl -n APIGEE_NAMESPACE apply -f spc-env-ENV_NAME.yaml

    Repita essa etapa para cada ambiente.

Ativar segredos externos para contas de serviço do Google

  1. No arquivo de substituições, adicione as propriedades de configuração serviceAccountSecretProviderClass e envs[].serviceAccountSecretProviderClass para ativar o uso de segredos externos para contas de serviço do Google. É possível remover ou comentar as propriedades de configuração serviceAccountPath e serviceAccountPaths:
    serviceAccountSecretProviderClass: apigee-orgsakeys-spc
    
    envs:
      - name: ENV_NAME
        serviceAccountSecretProviderClass: apigee-envsakeys-ENV_NAME-spc
  2. Aplique cada gráfico do 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. Para cada ambiente, aplique o gráfico apigee-env:
    helm upgrade ENV_NAME apigee-env/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --set env=ENV_NAME \
        --atomic \
        -f overrides.yaml
    

Como reverter para o uso de arquivos de certificado da conta de serviço

Se você precisar reverter para usar arquivos de certificado de conta de serviço do Google armazenados, use o seguinte procedimento:

  1. Atualize seu arquivo de modificação:
    1. Remova ou comente as linhas serviceAccountSecretProviderClass e envs:serviceAccountSecretProviderClass.
    2. Adicione as propriedades de configuração serviceAccountPath e serviceAccountPaths com os caminhos para as contas de serviço adequadas.

    Exemplo:

    # 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. Aplique cada gráfico do 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. Para cada ambiente, aplique o gráfico apigee-env:
    helm upgrade ENV_NAME apigee-env/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --set env=ENV_NAME \
        --atomic \
        -f overrides.yaml
    

    Repita essa etapa para cada ambiente.