Kubernetes外部シークレットオペレータ

KeeperシークレットマネージャーのシークレットをKubernetes外部シークレットオペレータと同期

概要

Kubernetes外部シークレットオペレータは、さまざまな外部APIからシークレットを同期することで、Kubernetesにシークレットを挿入します。本ページでは主に外部シークレットのセットアップに焦点を当て、KeeperボルトからKubernetesへのシークレットを同期します。

特徴

  • 外部シークレットを介して、KeeperボルトからKubernetesへシークレットをシームレスに同期します。

  • Keeperボルトからすべてのポッドに渡ってシークレットにリアルタイムでアクセスできます。

要件

この統合を利用するには、以下が必要となります。

セットアップ

Helmで外部シークレットをインストールする

以下のコマンドを実行します。

helm repo add external-secrets https://charts.external-secrets.io

helm install external-secrets \
    external-secrets/external-secrets \
    -n external-secrets \
    --create-namespace

Base64 KSM 構成を保存するためのKubernetesシークレットを作成

ご利用のデバイス用にSecrets Manager構成を作成すると、KeeperシークレットマネージャーAPI からのデータの認証と復号化に使用される接続トークン、暗号化キー、識別子、ドメイン情報を含む Base64 JSON 文字列が作成されます。

Base64 JSON構成文字列は外部シークレットによって設定されKeeper Securityに対して認証し、通常のKubernetesシークレット内で定義されます。

以下のコマンドを呼び出すと、Keeperシークレットマネージャーへの認証に使用される Kubernetesシークレットが作成されます。

kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: ksm-config-secret # name of the k8s Secret where KSM config is stored
type: Opaque
data:
  ksm_config: "[REPLACE WITH YOUR BASE64 JSON string]"
EOF

注: 上記のコード例の2行目から8行目は 、YAMLファイルに保存してkubectl applyコマンドで適用できます。たとえば、2行目から8行目をsecrets.yamlに保存して、以下のコマンドを実行します。

kubectl apply -f secret.yaml

SecretStoreを作成

Base64 JSON文字列に定義したksm_configでKubernetesシークレットを作成すると、SecretStoreを作成できます。

以下のコマンドを呼び出すと、SecretStoreが作成されます。

kubectl apply -f - <<EOF
apiVersion: external-secrets.io/v1beta1   
kind: SecretStore
metadata:
  name: my-external-secrets-secretstore   # name of the SecretStore where retrieved secrets will be stored once fetched from Keeper Secrets Manager (KSM)
spec:
  provider:
    keepersecurity:                       # name of the SecretStore provider, in this case KeeperSecurity
      authRef:
        name: ksm-config-secret           # name of the k8s Secret where KSM config is stored
        key: ksm_config                   # key in the k8s Secret where KSM config is stored
      folderID: "[SHARED FOLDER UID]"     # UID of the shared folder in KeeperSecurity where the records 
                                          #   are stored. Make sure the folder is shared into the KSM Application
EOF

上記の例では、ボルト内のレコードが保存されている共有フォルダのUIDでfolderIDを定義します。

ClusterSecretStoreの場合は、作成したシークレットの名前空間で SecretAccessKeyRefのnamespaceを指定するようにしてください。

注: 上記のコード2行目から13行目は 、YAMLファイルに保存して、kubectl applyコマンドで適用できます。たとえば、2行目から13行目をsecretstore.yamlに保存して、以下のコマンドを実行します。

kubectl apply -f secretstore.yaml

ExternalSecretを作成

次に、ExternalSecretを作成します。

以下のコードでは、外部シークレットを作成し、指定したレコードのログインとパスワードフィールドの値をKubernetesシークレットに保存します。これらのフィールドはtarget.template.dataセクションで定義され、30秒ごとに更新されます。サポートされているフィールドのリストについては、こちらのページをご覧ください。

kubectl apply -f - <<EOF
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
 name: ksm-external-secret
spec:
 refreshInterval: 12h               # rate how often SecretManager pulls KeeperSecurity. 
                                    #   In this case every 12 hours, for the example. 
                                    #   We recommend this value to be 12h or more.
 secretStoreRef:                    # reference to the SecretStore defined above to authenticate against Keeper Security
   kind: SecretStore                # tells External Secrets the type of the secret store, should be same as the one defined above
   name: my-external-secrets-secretstore  

 dataFrom:                          # tells External Secrets which record to use to fetch from Keeper Secrets Manager (KSM)
   - extract:
       key: "[RECORD UID]"          # UID of the record in Keeper where the secrets are going to be fetched from
 target:                            # tells External Secrets the target location where to store the secrets once fetched from Keeper Security
   name: my-external-secrets-values # name of the k8s Secret to be created
   creationPolicy: Owner            # tells External Secrets to create the k8s Secret if it doesn't exist
   template:
     engineVersion: v2          
     data:
       username: "{{ .login }}"     # tells External Secrets to store the value of 
                                    # the login field in Keeper Security into the k8s Secret under the key username
       password: "{{ .password }}"  # tells External Secrets to store the value of 
                                    # the password field in Keeper Security into the k8s Secret under the key password
       name: "{{  (fromJson .name).first }} {{  (fromJson .name).middle }} {{  (fromJson .name).last }}" # decode json string into vars
EOF

上記のコード例で、[RECORD UID]を目的のレコードUIDに置き換えます。

namephonebankAccountなどの複雑なタイプは単一の文字列値と一致しないため、外部シークレットは完全なJSON文字列を返します。JSONテンプレート関数を使用してデコードします。

注: 上記のコード例の2行目から27行目は 、YAMLファイルに保存して、kubectl applyコマンドで適用できます。たとえば、2行目から27行目をexternalsecret.yamlに保存して、以下のコマンドを実行します。

kubectl apply -f externalsecret.yaml

動作

  • RecordがExternalSecretがマッピングされる方法

    • remoteRef.keyがレコードIDに一致

    • remoteRef.propertyが以下のいずれかに一致

      • フィールド: レコードのフィールドのタイプ

      • CustomFields: レコードのフィールドのラベル

      • ファイル: レコードのファイル名

      • 空白の場合、レコード全体がJSON形式で返されます。

    • remoteRef.versionは現在サポートされていません。

  • dataFrom:

    • find.pathは現在サポートされていません。

    • find.name.regexpが以下のいずれかに一致

      • フィールド: レコードのフィールドのタイプ

      • CustomFields: レコードのフィールドのラベル

      • ファイル: レコードのファイル名

    • find.tagsは現時点ではサポートされていません。

制限事項

このプロバイダの使用にはいくつかの制限があります。

  • Keeperシークレットマネージャーは、レガシーのタイプなしのレコードでは動作しません。

  • Keeperシークレットマネージャーではfind.tagsタグの使用はサポートされていません。

  • find.pathは現在サポートされていません。

シークレットをプッシュ

プッシュシークレットは、カスタムKeeperSecurityレコードタイプのExternalSecretsでのみ機能します。

動作

  • selector:

  • secret.name: プッシュするKubernetes シークレットの名前

  • data.match:

  • secretKey: プッシュする選択済みシークレットのキー

  • remoteRef.remoteKey: リモートプロバイダで作成されるシークレットとキー

    • 形式: SecretName/SecretKey

PushSecretを作成

KubernetesからKeeper Securityレコードを作成するには、Kind=PushSecretが必要となります。

kubectl apply -f - <<EOF
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
  name: example
spec:
  secretStoreRefs:
    - name: keeper
      kind: SecretStore
  refreshInterval: "1h"
  deletionPolicy: Delete
  selector:
    secret:
      name: secret-name # k8s secret to be pushed
  data:
    - match:
        secretKey: secret-key # k8s key within the secret to be pushed
        remoteRef:
          remoteKey: remote-secret-name/remote-secret-key # This will create a record called "remote-secret-name" with a key "remote-secret-key"
EOF

注: 上記のコード例の2行目から19行目は 、YAMLファイルに保存して、kubectl applyコマンドで適用できます。たとえば、 2行目から19行目をpushsecret.yamlに保存して、以下のコマンドを実行します。

kubectl apply -f pushsecret.yaml

KSMアプリケーションで、使用中のremote-secret-nameというタイトルの付いた記録は1つだけであるようにします。

制限事項

  • 現時点では、シークレットごとに 1 つのキーのみプッシュできます。

  • 選択した名前のレコードは存在するが、キーが存在しない場合は、レコードを更新できません。

セットアップの確認

KubernetesシークレットSecretStoreExternalSecretを設定後、kubectl get secretsコマンドでシークレットを抽出できます。

上記のコード例では、シークレットの名前はmy-external-secrets-valuesであり、以下のレコード値が保存されます。

data:
       username: "{{ .login }}"                                      
       password: "{{ .password }}"

ログインとパスワードの値を取得するには、以下のコマンドを呼び出します。

$ kubectl get secret my-external-secrets-values -o jsonpath="{.data}"
{"password":"a2lsbCB5b3U=","username":"SSB3aWxs"}

上記の応答はエンコードいるので、デコードするには以下を呼び出します。

$ kubectl get secret my-external-secrets-values -o jsonpath="{.data.password}" | base64 --decode
pAs$w0rd

結論

本ページでは、Kubernetes外部シークレットオペレータを介して KeeperシークレットマネージャーをKubernetesに統合するための手順を詳しく説明しました。上記の手順で、Keeperボルトに保存されているシークレットをKubernetes環境にシームレスに同期できるようになります。これにより、シークレットを安全に管理できるだけでなく、すべてのポッド間でリアルタイムのアクセスも容易になります。

概説したプロセス (外部シークレットオペレータの設定、Kubernetesシークレット、SecretStore、ExternalSecret の作成など) は、この統合の鍵となります。設定が成功すると、コマンドを使用して統合を確認し、保存されているシークレットを簡単に取得できるようになります。

KeeperシークレットマネージャーとKubernetesの統合により、Kubernetes環境で実行されるアプリケーションのセキュリティインフラストラクチャが強化されます。シークレットを管理するための強固な基盤となり、全体的な運用効率とセキュリティ体制が向上します。

コマンド例のすべてのプレースホルダ部分を実際の情報に置き換えるようにしましょう。Kubernetesで外部シークレットを設定または管理する必要があるときはいつでも、本ページをご参照ください。

最終更新