こんにちは、研究開発部 Architectグループ ML Platformチームのジャン(a.k.a jc)です。 本記事はSansan Advent Calendar 2024の15日目です。 Argo CDとArgo Workflowsにおける認証・認可の設定について紹介します。
背景
以前の記事でも紹介しましたが、私たちのチームが開発・運用しているEKSクラスタCircuitではArgoCDでGitOpsを行っており、Argo Workflowsでバッチ処理を実行するエンジンとして利用しています。
運用初期は利用者が多くなかったため、Argo CDのSSOはGitHub Team (グループ管理)とArgo CDに付随されているDexを使用していました。
また、認可設定はシンプルに保ち、Basic Built-in Rolesを利用して、クラスタ管理者にrole:admin
、利用者にrole:readonly
権限を付与していました。一方、Argo WorkflowsではSSOを設定せず、デフォルトのAuth Modeであるserver
を使っていたため、認証が通れば誰でもバッチのログを閲覧できる状態でした。
しかし、Circuitの成長に伴い、機密性の高いログが増える見込みとなり、現在の運用は対応が難しくなってきました。
そこで、先日最小権限の原則(Principle of Least Privilege、必要最小限の権限のみを付与する運用方針)に従い、Argo CDとArgo Workflowsの権限設定を見直しました。 本記事では、公式ドキュメントに記載されていない落とし穴や、実践してみて明らかになったArgo CDとArgo Workflows権限のポイントについて解説します。 Argo CDやWorkflows権限設定の権限設定を進める際の参考になれば幸いです。
Argo CD
先述の通り、今回の構成ではGitHub Teamでグループを管理し、OpenID Connect ProviderとしてDexを利用しています。この構成における認証・認可のフローは、GitHub Teams → Dex → Argo CD Applicationとなります。
Argo CDでは、グループごとにnamespaceのアクセス権限を設定することで、必要最小限の権限のみを付与できます。 ただし、Argo CDのドキュメントRBAC Configurationの記載によると、namespaceごとに設定する場合、事前にApplication in Any Namespacesを有効化する必要があります。
デフォルトでは、Argo CDのApplicationはargocd
namespaceに作成されるため、Applicationリソースを各namespaceに分割して配置する必要があります。この設定は比較的簡単な一方で、ApplicationSetのtemplateにおいてnamespaceがサポートされていないため、この方法を採用するのは現実的ではありませんでした。すでにApplicationSetによって複数のnamespaceにアプリケーションをデプロイしているため、ApplicationSetの廃止は容易ではありません。
その解決策として、namespaceごとにAppProjectを作成し、論理的なグループ化を行いました。AppProjectは、Argo CDにおいてアプリケーションをグループ化し、リソースやアクセス制限を設定するためのリソースです。以下は、その例です。
apiVersion: argoproj.io/v1alpha1 kind: AppProject metadata: name: samples namespace: argocd spec: destinations: - namespace: samples server: "https://kubernetes.default.svc" sourceRepos: - "https://github.com/org/repo.git"
このAppProjectに対応する権限は、Dex設定用のConfigMapに定義します。
apiVersion: v1 kind: ConfigMap metadata: name: argocd-rbac-cm data: policy.csv: | g, {YOUR_ORG}/{YOUR_TEAM}, role:user-namespace-samples p, role:user-namespace-samples, applications, get, samples/*, allow p, role:authenticated, projects, get, default, allow policy.default: role:authenticated
この設定により、AppProjectに付与した権限が間接的にnamespaceの権限として機能し、ApplicationSetのtemplateではnamespaceがサポートされていない問題を回避できました。
全namespaceに対してこの設定を適用することで、namespaceのアクセス権限を分離し、それぞれに最小限の権限をargocd-rbac-cm
に設定できるようになります。
Argo Workflows
続いて、Argo WorkflowsのSSO設定について紹介します。 Argo Workflowsの認証認可のフローはGitHub Teams → Dex → ServiceAccount → Workflow/CronWorkflow/WorkflowTemplateになります。
最小限の権限を付与するため、まずはAuth ModeをServerからSSOに変更しておく必要があります。 設定は基本的にドキュメントに従えば問題ありません。ただし、SSO RBAC Namespace Delegationは、ドキュメントでは「オプション」とされていますが、実際には必須と考えるべきです。
理由としては、1人のユーザが複数のグループ (GitHub Teams) を所属する場合、この設定がないままダッシュボードにログインすると、所属しているGitHub Teamsと紐づいている任意のService Accountの権限が付与され、ユーザが本来アクセスするつもりのworkflowにアクセスできない状況が発生します。この挙動を回避するために、SSO RBAC Namespace Delegationの有効化は必須です。 詳細はこちらのissueにご参照ください。
Argo Workflowsの設定
以下は、最終的にArgo Workflowsの設定(Helmのvalues.yaml)です。
server: authModes: - sso sso: enabled: true issuer: https://argocd.example.com/api/dex sessionExpiry: 240h clientId: name: argo-workflows-sso key: client-id clientSecret: name: argo-workflows-sso key: client-secret redirectUrl: https://workflows.example.com/oauth2/callback scopes: - groups rbac: enabled: true extraEnv: - name: SSO_DELEGATE_RBAC_TO_NAMESPACE value: "true"
ポイント
issuer
: DexのエンドポイントredirectUrl
: workflowsのredirect先で、path部分デフォルトで問題ので、domain部分だけを置き換えればいいSSO_DELEGATE_RBAC_TO_NAMESPACE
: RBACをnamespaceに委譲するためにtrue
を指定する
Argo CD側の設定
Argo CD側では、Dexのコンテナにworkflowsのclient secretを追加し、staticClients
を行う必要があります。
apiVersion: apps/v1 kind: Deployment metadata: name: argocd-dex-server spec: template: metadata: spec: containers: - name: dex env: - name: ARGO_WORKFLOWS_SSO_CLIENT_SECRET valueFrom: secretKeyRef: name: argo-workflows-sso key: client-secret --- apiVersion: v1 kind: ConfigMap metadata: name: argocd-cm data: admin.enabled: "false" dex.config: | connectors: - type: github id: github name: GitHub config: clientID: hogehoge clientSecret: $argocd-dex:github-client-secret orgs: - name: your-org teams: - your-tema staticClients: - id: argo-workflows-sso name: Argo Workflow redirectURIs: - https://workflows.example.com/oauth2/callback secretEnv: ARGO_WORKFLOWS_SSO_CLIENT_SECRET url: https://argocd.example.com
ポイント
redirectURIs
: workflowsのredirect先で、Workflows側と一致させる必要があるredirectURIs
はbowser accessibleのリンクでなければならないため、Argo CDとWorkflowsは同じクラスタにある場合でも、クラスタ内通信は難しい
Service Accountの設定
SSOを有効化した後、次のステップとしてService Accountを設定します。特定のnamespaceにあるworkflowなどのArgo Workflows関連のリソースにアクセスするのに、2つのService Accountが必要です。
- デフォルトのService Account: ログイン時に使用する
- namespace側のService Account: 特定のnamespace内リソースのアクセスを管理する
以下はデフォルトのService Accountの設定例です。
apiVersion: v1 kind: ServiceAccount metadata: name: default-user namespace: argo-workflows annotations: workflows.argoproj.io/rbac-rule: "true" workflows.argoproj.io/rbac-rule-precedence: "0" --- apiVersion: v1 kind: Secret metadata: name: default-user.service-account-token namespace: argo-workflows annotations: kubernetes.io/service-account.name: default-user type: kubernetes.io/service-account-token
ポイント
- namespace:
argo-workflows
に設定する - RBACルールの優先順位: デフォルトのため、
workflows.argoproj.io/rbac-rule-precedence
を0
に設定する
以下は、namespace側のService Accountの設定例です。
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: argo-workflows-user namespace: samples rules: - apiGroups: - argoproj.io resources: - cronworkflows verbs: - get - list - watch - patch --- apiVersion: v1 kind: ServiceAccount metadata: name: argo-workflows-user namespace: samples annotations: workflows.argoproj.io/rbac-rule: "'your-org:your-team' in groups" workflows.argoproj.io/rbac-rule-precedence: "1" --- apiVersion: v1 kind: Secret metadata: name: argo-workflows-user.service-account-token namespace: samples annotations: kubernetes.io/service-account.name: argo-workflows-user type: kubernetes.io/service-account-token --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: argo-workflows-user namespace: samples roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: argo-workflows-user subjects: - kind: ServiceAccount name: argo-workflows-user namespace: samples
ポイント
- Role, RoleBinding, ServiceAccountとServiceAccountのtokenをセットで設定する
workflows.argoproj.io/rbac-rule
はdex側のGitHubの情報に基づいて設定する。例:'your-org:your-team' in groups
- RBACルールの優先順位:
workflows.argoproj.io/rbac-rule-precedence
を1
に設定する
これらの設定により、ログイン時にデフォルトのService Accountの権限が付与されます。各namespaceのService Account argo-workflows-user
にRoleをbindingすることで、WorkflowやCronWorkflowなどアクセスできるリソース範囲を制限できます。
まとめ
本記事では、Argo CDとArgo Workflowsにおける認証・認可の具体的な構築手法を解説しました。
- Argo CD: AppProjectとRBACポリシーを組み合わせることで、ApplicationSetの制約を回避しつつ、namespaceごとに柔軟な権限管理を実現
- Argo Workflows: SSOを有効化し、RBAC Namespace Delegationを設定することで、Argo CDと同じくGitHub Teamsベースのリソース管理を強化
- Argo Workflows: デフォルトのService AccountとnamespaceごとのService Accountを設定し、最小限の権限でworkflowリソースを管理可能に
- DexやGitHub Teamを利用しない場合はArgo CD単体の設定を変更するだけで実現可能
皆さんのArgo CDおよびArgo Workflowsの運用に少しでも役立てば幸いです。さらに良い方法や工夫があれば、ぜひ共有してください!
なお、研究開発部ではMLOps/DevOpsエンジニア・プラットフォームエンジニアを募集しています。興味のある方はぜひご連絡ください!