Zenn
🐙

Argo CD で Google アカウントによる SSO する方法

2025/03/11に公開

クラウドエース 北野です。

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 と呼びます)プロバイダを定義します。

cm-argocd.yaml
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 プロバイダを定義します。

cm-argocd.yaml
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 を定義します。

argocd-rbac-cm.yaml
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> は、コネクタごとに異なる設定を定義します。

cm-argocd.yaml
data:
  dex.config: |
    connectors:
      - type: <TYPE>
        id: <ID>
        name: <NAME>
        config: <CONECTION INFO>

既存の OIDC プロバイダにより SSO を実現する場合、 data.oidc.config を以下のように定義します。以下のその他接続設定の部分は、IdP 基盤ごとで必要となる設定値となります。

cm-argocd.yaml
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 アカウント

また、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を作成します。

secret_manager.tf
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 を参照するために使う サービスアカウントの作成と権限の付与をおこないます。

service_account.tf
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 を作ります。

serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: external-secret
  namespace: argocd
  annotations:
    iam.gke.io/gcp-service-account: <SERVICE ACCOUNT EMAIL>
clustersecretstore.yaml
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 にこのラベルを定義します。

es-argocd-oidc-client.yaml
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
es-argocd-serviceaccount-key.yaml
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
kustomization.yaml
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-clientargocd-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 を 無効化するように定義します。

cm-argocd.yaml
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 アカウントに権限を付与します。

cm-argocd-rbac.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
data:
  policy.csv: |
    g, <GOOGLE ACCOUNT EMAIL>, role:admin

kustomaization.yaml に上記の2つのマニフェストを実行するように追記します。

kustomization.yaml
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 のパッチを作成します。

deploy-argocd-dex-server.yaml
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 の値を入力します。

cm-argocd-group.yaml
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 グループに権限を付与します。

cm-argocd-rbac.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
data:
  scopes: '[groups, email]'
  policy.csv: |
    g, <GOOGLE GROUP EMAIL>, role:admin

上記のマニフェストを実行するように kustomization.yaml を以下のように追記します。

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

ログインするとコメントできます