tech.guitarrapc.cóm

Technical updates

ArgoCDのOIDC認証とリフレッシュトークンチェック不具合

ArgoCDはOIDC認証をサポートしていますがリフレッシュトークンのチェックが機能していないため注意が必要です。 2025年4月の暫定対応メモです。

2025年5月7日追記

半年ぶりにPR進捗が出たのでマージが近いといいですね。

ArgoCDのJWT認証

ArgoCDへのログインには、ローカルユーザー認証、OIDC認証の2つがあります。ArgoCDのローカルユーザー作成はオンザフライにユーザー、追加、削除がしにくいためユーザー個別の認証を提供するならJWT認証を使うのが良いでしょう。公式も、管理者ユーザーを1名用意して、OIDCを利用するSSO統合を推奨しています。

さてArgoCDのSSO統合には、ArgoCDにバンドルされたDexと、ArgoCD自身のOIDCの2つがあります。 Dexは以前からあった方法で、OIDCをサポートしていなかったりDexコネクター機能1で利用が推奨されています。OIDCプロバイダーなら、ArgoCD自身のOIDCを利用するのが推奨されています。

とはいえ、ArgoCDのOIDCプロバイダーを使うとリフレッシュトークンによる延長が行われないため、注意が必要です。

CognitoをOIDCプロバイダーとして利用してArgoCDのSSOを実現する

Cognitoを使ったOIDC認証を通して状況を説明しましょう。

ArgoCDのOIDCプロバイダーを使うと、CognitoやGoogle Workspace、Auth0、OkataなどのSSOを簡単なコンフィグ利用できます。 例えばCognitoを利用するArgoCDの設定は次の通りです。

# argocd-cm.yaml
data:
  oidc.config: |
    name: Cognito
    issuer: https://cognito-idp.<region>.amazonaws.com/<cognito-user-pool-id>
    redirectUrl: https://<argocd-server-url>
    clientID: <cognito-client-id>
    clientSecret: <cognito-client-secret>
    requestedScopes: ["openid", "profile", "email"]
    requestedIDTokenClaims: {"groups": {"essential": true}}
    logoutURL: https://<argocd-server-url>/logout?client_id=<cognito-client-id>&logout_uri=https://<argo-cd-server-url>/logout
  # Cognitoにapp-readonlyグループを、ArgoCDのapp-readonly-role権限にマッピングする例
  policy.csv: |
    p, role:app-readonly-role, applications, get, *, allow
    p, role:app-readonly-role, logs, get, *, allow
    p, role:app-readonly-role, projects, get, *, allow
    g, app-readonly, role:app-readonly-role

# argocd-rbac-cm.yaml
data:
  scopes: '[cognito:groups]'

ArgoCD向けのCognitoクライアントは次のように登録して、Cognitoユーザー/グループにCognitoのグループをマッピングしておけばOKです。

resource "aws_cognito_user_pool_client" "main" {
  name = "cognito"

  # OAuth 2.0を使用するための設定
  allowed_oauth_flows_user_pool_client = true
  allowed_oauth_flows                  = ["code"]
  allowed_oauth_scopes                 = ["email", "openid", "profile"]

  # 認証後のリダイレクトURL
  callback_urls        = "https://<argocd-server-url>/auth/callback"
  logout_urls          = "https://<argocd-server-url>/logout"

  # 認証に使用するプロバイダ
  supported_identity_providers = ["COGNITO"]
  user_pool_id                 = aws_cognito_user_pool.main.id

  # トークンの有効期限(単位は時間)
  id_token_validity     = 1 # 1h。ユーザーが認証されたままになる期間を表します。この期間が過ぎると、再度ログインするか、セッションを更新する必要があります。
  access_token_validity = 1 # 1h。ユーザーが再度サインインするかセッションを更新するまで認証された状態が続く期間。この期間が過ぎると、再度ログインするか、セッションを更新する必要があります。

  # ArgoCDにはシークレット生成が必要
  generate_secret = true
}

これでArgoCDのトップページにアクセスすると、Cognitoログインボタンが表示、Cognito認証を経て、Cognitoユーザーログインします。 ArgoCDの権限は、policy.csvでマッピングしたCognitoグループとArgoCDロール通りです。

cognitoログインページ

リフレッシュトークンが使われない

さて、一見するとこの設定は完璧に見えますが、実はリフレッシュトークンが使われません。 Cognitoのリフレッシュトークンは、OIDCの認証フローで取得したアクセストークンとIDトークンを更新するために使用されますが、ArgoCDのOIDCプロバイダーはリフレッシュトークンのチェックを正しく行いません。 このため、Issueの通り、IDトークン/アクセストークンが更新されず、ユーザーはトークン期限切れに伴う再ログイン2が必要です。

リフレッシュトークンの修正PRは上がっているものの、2023年に作られてからレビューが進まず、2025年4月に入ってもマージされていません。

暫定対応

あまりやりたくないものの、修正されるまではArgoCDのアクセストークンとIDトークンの有効期限をある程度長くすることで、ユーザーに頻繁なログインを強いることを避けることができます。 例えば毎日ログイン程度なら8hに延ばすのも良いでしょう。

resource "aws_cognito_user_pool_client" "main" {
  name = "cognito"

  # 省略....

  # 暫定対応
  id_token_validity     = 8 # 8h。リフレッシュトークンが効かないので暫定で延ばして設定
  access_token_validity = 8 # 8h。リフレッシュトークンが効かないので暫定で延ばして設定
}

まとめ

ArgoCDのOIDCプロバイダーは、現在の実装ではリフレッシュトークンチェックが機能していないため、ユーザーはトークン期限切れに伴う再ログインが必要です。 暫定でアクセストークンとIDトークンの有効期限を長くするか、あるいはDexを利用するのが良いでしょう。

参考


  1. GitHubの組織やチームをOIDCグループのクレームにマッピングする機能など
  2. 上のIDトークン、アクセストークン設定なら1時間ごとに再ログインが必要