TECHSTEP

ITインフラ関連の記事を公開してます。

ArgoCD Projectから一部のDestinationをDenyする

今回はArgoCD ver 2.5で追加された、Projectレベルでのセキュリティ機能を試してみます。

以前のArgoCD Projectの記事にも記載をしているのですが、ArgoCDのProjectは Application を論理的にグルーピングする機能で、source/destinationやroleなどを設定できます。

今回のアップデートでは、destinationdeny の設定を追加できるようになりました。これを利用するケースとしては、一部のnamespace( kube-system など)やclusterが機密情報を扱っており、管理者以外が該当のnamespaceへアクセスできないようにしたい場合などが挙げられます。

※参考:

ではProject-level securityを試していきます。今回は以下のマニフェストファイルを使ってテスト用のProjectを作成しています。

Denyの設定をするには、宛先の名称の先頭に ! を付ければ実現できます。なお、同じDestinationにAllow/Deny両方設定するとDenyのほうが優先されます。そのため、今回のテスト用ファイルのように記載すると、kube-system 以外のNamespaceはすべて許可する、といった設定ができます。

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: test-project
  namespace: argocd
spec:
  sourceRepos:
  - '*'
  destinations:
  - namespace: '*'
    server: '*'
  - namespace: '!kube-system' # Denyの設定
    server: '*'

上記マニフェストファイルをデプロイします。

$ kubectl apply -f proj-test.yaml
appproject.argoproj.io/test-project created

$ kubectl describe appproject test-project -n argocd
Name:         test-project
Namespace:    argocd

(割愛)

Spec:
  Destinations:
    Namespace:  *
    Server:     *
    Namespace:  !kube-system
    Server:     *
  Source Repos:
    *
Events:  <none>

上記Projectを指定して Application の作成を行います。今回はDestinationのNamespaceを変えた2つの Application を作成してみます。片方は default 、もう片方は以下にあるように kube-systemDestinationに指定します。

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook-kube-system
  namespace: argocd
spec:
  project: test-project
  source:
    repoURL: https://github.com/argoproj/argocd-example-apps.git
    targetRevision: HEAD
    path: guestbook
  destination:
    server: https://kubernetes.default.svc
    namespace: kube-system # ProjectでDenyしたkube-systemを指定
  syncPolicy:
    automated:
      prune: false
      selfHeal: false

default を指定したほうはSyncも正常に実行し、Statusも Healthy となることが確認できます。

# namespace: defaultを指定したリソース
$ kubectl apply -f app-default.yaml
application.argoproj.io/guestbook-default created

$ kubectl get app -n argocd
NAME                SYNC STATUS   HEALTH STATUS
guestbook-default   Synced        Progressing

$ kubectl get app -n argocd
NAME                SYNC STATUS   HEALTH STATUS
guestbook-default   Synced        Healthy

kube-system を指定したほうは、 Application を作成してもStatusが Unknown の状態でキープされます。 Application の状態を確認すると、指定したDestinationが許可されていない旨を表すメッセージが表示されました。

# namespace: kube-systemを指定したリソース
$ kubectl apply -f app-kube-system.yaml
application.argoproj.io/guestbook-kube-system created

$ kubectl get app -n argocd
NAME                    SYNC STATUS   HEALTH STATUS
guestbook-default       Synced        Healthy
guestbook-kube-system   Unknown       Unknown

$ kubectl describe app guestbook-kube-system -n argocd
Name:         guestbook-kube-system
Namespace:    argocd

(割愛)

Status:
  Conditions:
    Last Transition Time:  2022-11-05T06:35:37Z
    Message:               application destination {https://kubernetes.default.svc kube-system} is not permitted in project 'test-project'
    Type:                  InvalidSpecError
  Health:
    Status:  Unknown
  Sync:
    Status:  Unknown
Events:
  Type    Reason           Age   From                           Message
  ----    ------           ----  ----                           -------
  Normal  ResourceUpdated  22s   argocd-application-controller  Updated sync status:  -> Unknown
  Normal  ResourceUpdated  22s   argocd-application-controller  Updated health status:  -> Unknown

上記の通り、kube-systemdestinationに利用できないことが確認できました。 ちなみにArgoCD UIのほうからも、同様のメッセージを確認できます。