Argo CD で Google アカウントによる SSO する方法
クラウドエース 北野です。
Argo CD のユーザー管理に Google アカウントまたは Google グループを使えるようにして、Google アカウントでシングルサインオンを実現する方法を紹介します。
概要
以下のようにして Cloud Identity または Google Workspace を外部 ID プロバイダとして構成して、アカウントに権限を付与してアカウント管理をします。
- API Credentials で OAuth2.0 クライアント ID の作成
-
argocd-cm
の ConfigMap リソースで Dex の設定 -
argocd-rbac-cm
で権限の付与
Google アカウントでユーザー管理するとき、Dex の oidc コネクタを以下のように使い Open ID Connector (以降 OIDC と呼びます)プロバイダを定義します。
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
data:
admin.enabled: "false"
url: https://<ARGO CD DOMAIN>
dex.config: |
connectors:
- name: Google
id: google
type: oidc
config:
issuer: https://accounts.google.com
clientID: $oidc-client:id
clientSecret: $oidc-client:secret
Google グループでユーザー管理するとき、Dex の google コネクタを以下のように使い OIDC プロバイダを定義します。
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
data:
admin.enabled: "false"
url: https://<ARGO CD DOMAIN>
dex.config: |
connectors:
- name: Google
id: google
type: google
config:
redirectURI: https://<ARGO CD DOMAIN>/api/dex/callback
clientID: $oidc-client:id
clientSecret: $oidc-client:secret
serviceAccountFilePath: /tmp/oidc/googleAuth.json
adminEmail: <GOOGLE ACCOUNT EMAIL>
argocd-rbac-cm
で権限の付与は、以下のように ConfigMap を定義します。
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
data:
policy.csv: |
g, <GOOGLE ACCOUNT EMAIL> or <GOOGLE GROUP EMAIL>, role:admin
Google グループでユーザー管理するには、さらに以下の設定が必要です。
- Google Cloud でサービスアカウントの作成
- 作成したサービスアカウントに Admin コンソールのドメイン全体の委任で、
admin.directory.group.readonly
のスコープを付与 - 作成したサービスアカウントの JSON の鍵ファイル情報の Secret リソースへの登録
-
argocd-dex-server
Deployment の dex コンテナに先の Secret リソースのマウント
はじめに
Argo CD はアカウント作成機能があり、ConfigMap の argocd-cm
にアカウントと権限を定義すると、Argo CD 上にアカウントが作成されます。
しかし、このようにサービスごとにアカウントを作成すると、アカウントの管理をサービス個別に行う必要があり運用コストが膨大になります。そこで、一般的にアカウント管理は Keycloak などの認証基盤でアカウント管理を一元的に行い、その認証基盤で認証させるシングルサインオン (以降 SSO と呼びます)が一般的です。Argo CD でも様々な基盤と SSO できるように機能を提供しています。
そこで、この記事では Argo CD のユーザー管理に Google アカウントと Google グループのそれぞれで管理する方法を紹介し、Google アカウントで SSO を実現する方法を紹介します。
SSO の実現方法
Argo CD では、SSO を実現する方法として以下の2つの方法を提供しています。
- Argo CD にインストールされている Dex OIDC プロバイダによる SSO
- 既存の OIDC プロバイダによる SSO
Dex は、OIDC のプロバイダ機能を提供する OSS の認証サービスです。Argo CD を構築すると、初めから argocd-dex-server
が Deployment として構築され、Dex が提供されます。IdP が OIDC をサポートしていない場合や、Dex 機能を利用して SSO を実現したい場合、この機能を使い SSO を実現します。
また、Dex 以外での SSO の実現方法として、IdP 基盤の OIDC 機能により SSO の実現が可能です。
Dex または IdP 基盤の OIDC 接続の設定を、argocd-cm
の ConfigMap に記載します。
Dex で SSO を実現する場合、以下のように data.dex.config を定義します。以下の <CONECTION INFO>
は、コネクタごとに異なる設定を定義します。
data:
dex.config: |
connectors:
- type: <TYPE>
id: <ID>
name: <NAME>
config: <CONECTION INFO>
既存の OIDC プロバイダにより SSO を実現する場合、 data.oidc.config を以下のように定義します。以下のその他接続設定の部分は、IdP 基盤ごとで必要となる設定値となります。
data:
oidc.config: |
type: <TYPE>
id: <ID>
name: <NAME>
issuer: <IDP URL>
# その他接続設定
この記事では、Dex を使って Google アカウント、Google グループでの SSO の実現方法を紹介します。
Argo CD での必要情報の取り扱い
argocd-cm に定義する接続情報には、IdP 側のクライアントシークレットを入力する必要があります。このクライアントシークレットは秘匿情報のため、漏洩しない工夫が必要です。Argo CD には、Secret リソースの値を参照する機能を提供しています。
ConfigMap で $<SECRET NAME>:<KEY IN SECRET>
と参照すると、Secret の値を ConfigMap から参照できます。また、<SECRET NAME>:
部分を省略すると、argocd-secret
に定義した値を参照する様になります。
この記事では、この機能を使い External Secret で Google Cloud の Secret Manager に登録した OICD クライアントの情報を参照させます。
Google アカウントでの SSO の実現方法
Argo CD は Dex OIDC プロバイダを使い、Google Cloud の OIDC クライアントまたは SAML App Auth によって SSO を実現します。ここでは、OIDC クライアントを使い SSO を実現する方法を簡単に紹介します。
Dex コネクタの以下のそれぞれのコネクタを使うと、それぞれのアカウントの管理が可能になります。
コネクタの種類 | 管理できるアカウントの種類 |
---|---|
OIDC | Google アカウント |
Google グループと Google アカウント |
また、Google グループで SSO の実現には、Google グループの情報を取得させる必要があります。ドメイン全体の委任設定で Google Cloud のサービスアカウントにグループ情報を取得するスコープを付与します。そして、このサービスアカウントを Dex が使って、Google グループの情報を取得します。
この記事では、OIDC コネクタ、Google コネクタをそれぞれ使って、Google アカウントで SSO を実現する方法を紹介します。
環境構築
この記事では、以下のようなシステム構成で、Google アカウント、Google グループで SSO を実現させます。
Google Kubernetes Engine (以降 GKE と呼びます。)を使い Kubernetes 基盤を Google Cloud 上で構築し、GKE 上に Argo CD を作成します。インターネットから Argo CD への接続には、Gateway を使い、通信の暗号化には、Certificate Manager のマネージドサーバー証明書を使います。
OIDC クライアントの クライアント ID やクライアントシークレット、サービスアカウントの鍵情報は Google Cloud の Secret Manager で管理し、External Secret を使い GKE 上の Secret と連携させます。
以降の環境の構築では、Google Cloud のリソースの作成に Terraform を使い、Kubernetes リソースの作成に マニフェストと Kustomize を使います。以下で説明するコード内の <>
で囲まれた値は、環境に合わせて書き替えてください。
事前準備
SSO の設定の前に Google Cloud および Kubernetes 側に設定する方法を説明します。
Google Cloud の設定
Google Cloud 側では、秘匿情報を管理するための設定として以下を実施します。
- Secret Manager の作成
- サービスアカウントの作成
OIDC クライアントの ID とシークレット情報およびサービスアカウントの鍵ファイルの情報を格納する Secret Managerを作成します。
locals {
secret_managers = [
"argocd-oidc-client-id",
"argocd-oidc-client-secret",
"argocd-serviceaccount-key"
]
}
resource "google_secret_manager_secret" "main" {
for_each = toset(local.secret_managers)
secret_id = each.value
project = var.project
replication {
user_managed {
replicas {
location = "asia-northeast1"
}
}
}
}
External Secret Operator が Secret Manager を参照するために使う サービスアカウントの作成と権限の付与をおこないます。
resource "google_service_account" "main" {
depends_on = [
google_container_cluster.primary
]
account_id = <GOOGLE CLOUD SERVICEACCOUNT ID>
project = var.project
}
resource "google_service_account_iam_member" "workload_identity_argocd-server" {
service_account_id = google_service_account.main.id
role = "roles/iam.workloadIdentityUser"
member = format("serviceAccount:%s.svc.id.goog[%s/%s]", var.project, "argocd", "external-secret")
}
resource "google_project_iam_member" "k8s-argocd_roles_gkehub_viewer" {
member = google_service_account.main.member
project = var.project
role = "roles/secretmanager.secretAccessor"
}
resource "google_project_iam_member" "k8s-argocd_roles_gkehub_gatewayEditor" {
member = google_service_account.main.member
project = var.project
role = "roles/secretmanager.viewer"
}
Kubernetes
Kubernetes 側の設定は Argo CD の構築、External Secret Operator の接続と Cluster Secret Storeの作成をします。
- Argo CD の構築
- External Secret Operator のインストール
- External Secret を使った Secret の作成
Argo CD の構築は GKE での Argo CD の構築の記事と全く同じ方法なので、そちらを参照してください。
External Secret Operator のインストールは Helm を使い以下のコマンドで実行します。
helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets -n external-secrets --create-namespace
暫くして External Secret Operator が起動し終った後、以下のように External Secret を作ります。
apiVersion: v1
kind: ServiceAccount
metadata:
name: external-secret
namespace: argocd
annotations:
iam.gke.io/gcp-service-account: <SERVICE ACCOUNT EMAIL>
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: argocd-css
namespace: argocd
spec:
provider:
gcpsm:
projectID: <PROJECT ID>
auth:
workloadIdentity:
clusterLocation: asia-northeast1
clusterName: platform
serviceAccountRef:
name: external-secret
namespace: argocd
Secret の情報を ConfigMap で参照させるためには、app.kubernetes.io/part-of: argocd
のラベルを作成する必要があるため、External Secret の metadata にこのラベルを定義します。
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: es-argocd-secret
namespace: argocd
labels:
app.kubernetes.io/part-of: argocd
spec:
refreshInterval: 1h
secretStoreRef:
name: argocd-css
kind: ClusterSecretStore
target:
name: oidc-client
creationPolicy: Owner
data:
- secretKey: id
remoteRef:
key: argocd-oidc-client-id
version: latest
- secretKey: secret
remoteRef:
key: argocd-oidc-client-secret
version: latest
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: es-argocd-google-groups-json
namespace: argocd
spec:
refreshInterval: 1h
secretStoreRef:
name: argocd-css
kind: ClusterSecretStore
target:
name: argocd-google-groups-json
creationPolicy: Owner
data:
- secretKey: googleAuth.json
remoteRef:
key: argocd-serviceaccount-key
version: latest
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./clustersecretstore.yaml
- ./es-argocd-oidc-client.yaml
- ./es-argocd-serviceaccount-key.yaml
- ./serviceaccount.yaml
暫くすると、以下のように Kubernetes 上に oidc-client
と argocd-google-groups-json
Secret が以下のように作成されます。
Google アカウントでの SSO
Dex の OIDC コネクタを使い Google アカウントでユーザー管理する方法を紹介します。
Google Cloud の設定
OAuth 2.0 クライアントを Google Cloud の API Credentials で作成して、クライアント情報を Secret Manager に格納します。
項目 | 設定値 |
---|---|
アプリケーションの種類 | ウェブアプリケーション |
名前 | 任意の値 |
承認済みの JavaScript 生成元 | https://<ARGO CD DOMAIN> |
承認済みのリダイレクトURI | https://<ARGO CD DOMAIN>/api/dex/callback |
生成した OAuth2 クライアント ID のそれぞれの情報を Secret Manager に保存します。
Secret Manager 名 | 格納する値 |
---|---|
argocd-oidc-client-id | クライアント ID |
argocd-oidc-client-secret | クライアント シークレット |
Kubernetes の設定
Kubernetes は以下の設定をします。
- Dex への設定
- RBAC で Google アカウントへの設定
argocd-cm
の ConfigMap に以下のように設定し、OIDC クライアントの情報を Dex に入力します。またこのとき、admin ユーザーのログインを無効化するように data.admin.enabled を 無効化するように定義します。
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
data:
admin.enabled: "false"
url: https://<ARGOCD DOMAIN>
dex.config: |
connectors:
- name: Google
id: google
type: oidc
config:
issuer: https://accounts.google.com
clientID: $oidc-client:id
clientSecret: $oidc-client:secret
argocd-rbac-cm の ConfigMap にアクセスを許可する Google アカウントに権限を付与します。
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
data:
policy.csv: |
g, <GOOGLE ACCOUNT EMAIL>, role:admin
kustomaization.yaml に上記の2つのマニフェストを実行するように追記します。
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: argocd
resources:
- gateway.yaml
- health-check-policy.yaml
- httproute.yaml
- https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
patches:
- path: cm-argocd-cmd-params.yaml
- path: cm-argocd-rbac.yaml
- path: cm-argocd.yaml
再びログインすると、以下のように LOG IN VIA GOOGLE
というボタンが表示されます。
LOG IN VIA GOOGLE
ボタンをクリックすると、Google アカウントのログイン画面に遷移します。
ログインすると、Application の一覧ページにアクセスできるようになります。
ログインしたユーザー情報を User Info
で確認すると、以下のように Google アカウントの情報が表示されます。
Google グループでの SSO
Dex の Google コネクタを使い Google グループでのユーザー管理する方法を紹介します。
Google Cloud の設定
- OIDC クライアントの作成
- サービスアカウントの鍵情報の作成
- Admin SDK API の有効化
OIDC クライアントの作成とクライアント情報の Secret Manager への格納は、Google アカウントでの SSO の手順と同じなので、そちらを参照してください。
サービスアカウントの鍵情報の作成は、サービスアカウントを作成した後、Cloud コンソールの作成したサービスアカウントの詳細ページの鍵からキーを追加をクリックし、JSON タイプの鍵を作成します。作成した JSON ファイルを Secret Manager の argocd-serviceaccount-key
にアップロードします。
resource "google_service_account" "argocd_sso" {
account_id = <GOOGLE CLOUD SERVICEACCOUNT ID FOR ARGO CD SSO>
project = var.project
}
次に Admin SDK の API は admin.googleapis.com
を有効にします。
resource "google_project_service" "main" {
for_each = toset(local.enabled_services)
project = var.project
service = "admin.googleapis.com"
disable_dependent_services = false
disable_on_destroy = false
}
Google Admin の設定
Google Admin のドメイン全体の委任から Google Cloud の設定で作成したサービスアカウントに Google グループの閲覧権限のスコープを設定します。
設定項目 | 設定値 |
---|---|
クライアント ID | サービスアカウントのクライアント ID※ |
OAuth スコープ | https://www.googleapis.com/auth/admin.directory.group.readonly |
※サービスアカウントのクライアント ID は以下のコマンドから確認ができます。
gcloud iam service-accounts describe <SERVICE ACCOUNT EMAIL> --format value'(oauth2ClientId)'
Kubernetes の設定
Kubernetes 側では以下の設定をします。
- argocd-dex-server Deployment へのサービスアカウント情報を有する Secret のマウント
- Dex の設定
- Google グループへの権限の設定
argocd-dex-server Deployment の dex コンテナが、サービスアカウントの鍵情報の JSON ファイルを有する Secret を /tmp/oidc
にマウントするように、volumeMounts と volumes を以下のような Kustomize のパッチを作成します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: argocd-dex-server
spec:
template:
spec:
containers:
- name: dex
volumeMounts:
- mountPath: /shared
name: static-files
- mountPath: /tmp
name: dexconfig
- mountPath: /tls
name: argocd-dex-server-tls
- mountPath: /tmp/oidc
name: google-json
readOnly: true
volumes:
- emptyDir: {}
name: static-files
- emptyDir: {}
name: dexconfig
- name: argocd-dex-server-tls
secret:
defaultMode: 420
items:
- key: tls.crt
path: tls.crt
- key: tls.key
path: tls.key
- key: ca.crt
path: ca.crt
optional: true
secretName: argocd-dex-server-tls
- name: google-json
secret:
defaultMode: 420
secretName: argocd-google-groups-json
argocd-cm
の data.dex.config に以下の値を定義し、Dex に OIDC クライアントの設定を入力します。また、以下の adminEmail の <GOOGLE ACCOUNT EMAIL>
は、Google Workspace の管理者の Google アカウントの email の値を入力します。
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
data:
admin.enabled: "false"
url: https://<ARGOCD DOMAIN>
dex.config: |
connectors:
- name: Google
id: google
type: google
config:
redirectURI: https://<ARGOCD DOMAIN>/api/dex/callback
clientID: $oidc-client:id
clientSecret: $oidc-client:secret
serviceAccountFilePath: /tmp/oidc/googleAuth.json
adminEmail: <GOOGLE ACCOUNT EMAIL>
argocd-rbac-cm
を以下のように定義し、Google グループに権限を付与します。
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
data:
scopes: '[groups, email]'
policy.csv: |
g, <GOOGLE GROUP EMAIL>, role:admin
上記のマニフェストを実行するように kustomization.yaml を以下のように追記します。
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: argocdresources:
- gateway.yaml
- health-check-policy.yaml
- httproute.yaml
- https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
patches:
- path: cm-argocd-cmd-params.yaml
- path: cm-argocd-rbac.yaml
- path: cm-argocd-group.yaml
patchesStrategicMerge:
- deploy-argocd-dex-server.yaml
再びログインすると、以下のように LOG IN VIA GOOGLE
というボタンが表示されます。
LOG IN VIA GOOGLE
ボタンをクリックすると、Google アカウントのログイン画面に遷移します。
許可していないドメインのアカウントでログインするとアクセス拒否されます。
許可したドメインでログインすると、Application の一覧ページにアクセスできるようになります。
ログインしたユーザー情報を User Info
で確認すると、以下のように Google アカウントの情報と Google グループの情報が表示されます。
さいごに
Argo CD で Google アカウント、Google グループで Argo CD のアカウントを管理する方法を紹介しました。
Google グループでアカウントを管理し、グループにユーザーを追加、削除することで権限を付与するのが、権限管理のプラクティスとなっているので Google コネクタを使って、Google グループを管理するよう構成することをお勧めします。もし、Google アカウントで SSO を実現しようとされる方は、この記事の方法を参考にしてみてください。
Discussion