🔑

External Secret OperatorでAkeylessを使用した時の構成とトラブル

2024/07/28に公開

はじめに

みなさん、おうちクラスタのシークレット管理はどのようにされていますか?

個人利用だとあまりお金をかけたくないため、GCPやAWSのシークレットマネージャーを使うのもどうかな...と思っていた矢先にExternal Secret OperatorのProviderで面白そうなサービスを見つけたので試してみました。

今回取り上げるAkeylessは無料枠が大きいため、HashiCorp Vaultなどと比較しても個人開発でも気兼ねなく使用することができます。

5 Clients
2,000 Static Secrets

External Secret Operator

External Secret Operatorとは、外部のシークレットマネージャーからSecretを作成してくれる便利なツールです。これにより、マニフェストにクレデンシャル情報を残す必要がなく、また一元管理できるなどのメリットがあります。
このツールではクラスタ単位とネームスペース単位で使用するシークレットマネージャーの情報を設定できるため、マルチテナント・シングルテナントなど柔軟に切り分けることができます。

Akeyless

Akeylessはイスラエルの会社が提供しているシークレットマネージャーSaaSです。DFCと呼ばれる秘密鍵を管理する特許技術を持っており、異なるクラウドやリージョンで鍵のフラグメントを管理することにより、高い安全性を提供しています。
キーローテーションなどの基本機能はもちろん、、Kubernetesとのインテグレーションが充実していることも特徴かなと思います。

構築


Akeyless + External Secret Operator(https://docs.akeyless.io/docs/external-secret-operator)
https://docs.akeyless.io/docs/external-secret-operator
AkeylessのドキュメントではExternal Secret Operatorの導入から記載があるため、上から順に実行する形で設定を行うことができます。今回自分はAPIキーを用いた連携を行ったため、ダッシュボード上のUsers & Auth MethodsからAPIキーを発行し下記のように設定を行いました。

accessId: "p-XXXX" # AccessID
accessType:  api_key
accessTypeParam: "<api_key>"

続いて、Akeylessでは発行した認証情報に対しロールをアタッチすることでシークレット情報にアクセスができるようになるため、ロール追加と紐付けも行います。

余談ですが、Akeylessでは個人用のクレデンシャル情報を保管するためのPersonalディレクトリがあるため、用途によって情報を入れる場所が異なるので注意が必要です。今回の場合は、ユーザに関わらずアクセスを行いたいため、Items直下にディレクトリを作成し管理を行いました。

ハマった部分

クレデンシャル情報を扱うため、APIキーに対しIP制限をかけたところアクセスできなくなってしまいました。監査ログを調べたところ、見覚えのないIPアドレスからのアクセスがあり、恐らくリクエストがどこかでプロキシされているのか、クライアントのIPが正しく伝わっていない様子でした。
そこで、Akeyless Gatewayを通してExternal Secret OperatorからAkeylessにアクセスを行うことで、上記の問題を解決することにしました。

Akeyless Gatewayの導入

こちらもhelmをもとに導入を行います。ドキュメントやダッシュボード上のGatewayでも同様に手順を確認することができるので、そちらに沿って進めていきます。

https://docs.akeyless.io/docs/gateway-k8s

また、本来であればvalues.yamlに認証情報を記入し構築を行いますが、今回はあくまでもGatewayを経由しリクエストを送るのみのため、一度helm templateで出力し、下記のようにSecretを書き換え認証情報を含まない形で構築します。

apiVersion: v1
kind: Secret
metadata:
  name: akeyless-gw-conf-secret
type: Opaque
data:
  admin-access-id: ""
  admin-access-key: ""
---
...

最後に、SecretStoreのURLをGatewayに設定することで疎通することができます。accessID, accessTypeなどの認証情報についてはそのまま設定しておきます。

apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
  name: akeyless-cluster-secret-store
spec:
  provider:
    akeyless:
      # URL of your akeyless API
      akeylessGWApiURL: "http://akeyless-gw-akeyless-api-gateway.akeyless-gateway.svc.cluster.local:8080/v2"
      authSecretRef:
...

まとめ

今回はAkeyless Gatewayを用いてIP制限をかけつつシークレット情報を外部で管理する方法を紹介いたしまいた。本来であればこのGatewayはキーレスで運用するために用いられるもののような気がするため、現在まだSecretとして残ってしまっているAPIキーを使用しない方法を模索していきたいと思います。

参考文献

External Secret Operator+Akeyless

https://docs.akeyless.io/docs/external-secret-operator
https://faun.pub/akeyless-secret-management-with-external-secrets-operator-in-local-kubernetes-b30ae309d5f9

Gateway

https://docs.akeyless.io/docs/api-gw
https://docs.akeyless.io/docs/gateway-k8s

Discussion