背景
仕事では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
を使っていたため、認証が通れば誰でもバッチのログを閲覧できる状態でした。
しかし、プラットフォームの成長に伴い、機密性の高いログが増える見込みとなり、現在の運用は対応が難しくなってきました。
そこで、先日最小権限の原則(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の運用に少しでも役立てば幸いです。さらに良い方法や工夫があれば、ぜひ共有してください!