Ssoon

Argo CD in Practice – 4) 접근 제어 : 선언적 사용자 본문

CICD Study [1기]

Argo CD in Practice – 4) 접근 제어 : 선언적 사용자

구구달스 2025. 10. 19. 19:09

 

🔐 Access Control – Argo CD에서 사용자 접근 제어 설정하기

  • Argo CD를 운영 환경에서 사용하려면, 사용자 접근 제어(Access Control) 설정은 반드시 거쳐야 할 핵심 과정
  • 사용자 계정 관리, CLI 및 CI/CD 환경에서의 접근 방법, 그리고 Role-Based Access Control (RBAC) 설정
  • Argo CD가 오픈 소스임에도 기본적으로 Single Sign-On (SSO) 기능을 제공

💡 실습 환경 

  • kind k8s 배포
(⎈|N/A:N/A) ssoon@DESKTOP-72C919S:~$ kind create cluster --name myk8s --image kindest/node:v1.32.8 --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  labels:
    ingress-ready: true
  extraPortMappings:
  - containerPort: 80
    hostPort: 80
    protocol: TCP
  - containerPort: 443
    hostPort: 443
    protocol: TCP
  - containerPort: 30000
    hostPort: 30000
  - containerPort: 30001
    hostPort: 30001
  - containerPort: 30002
    hostPort: 30002
  - containerPort: 30003
    hostPort: 30003
EOF
Creating cluster "myk8s" ...
 ✓ Ensuring node image (kindest/node:v1.32.8) 🖼
 ✓ Preparing nodes 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
Set kubectl context to "kind-myk8s"
You can now use your cluster with:

kubectl cluster-info --context kind-myk8s

Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community 🙂
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ k get node
NAME                  STATUS     ROLES           AGE   VERSION
myk8s-control-plane   NotReady   control-plane   12s   v1.32.8
  • ingress-nginx 배포
    • 노드 라벨 확인
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl get nodes myk8s-control-plane -o jsonpath={.metadata.labels} | jq
{
  "beta.kubernetes.io/arch": "amd64",
  "beta.kubernetes.io/os": "linux",
  "ingress-ready": "true",
  "kubernetes.io/arch": "amd64",
  "kubernetes.io/hostname": "myk8s-control-plane",
  "kubernetes.io/os": "linux",
  "node-role.kubernetes.io/control-plane": ""
}
  • NGINX ingress 배포
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
  • --enable-ssl-passthrough
    → SSL Passthrough 기능 활성화 (클라이언트의 암호화된 트래픽을 백엔드로 그대로 전달).
  • 해당 설정이 안될 경우 보통 ‘argocd.example.com에서 리디렉션한 횟수가 너무 많습니다.’ 발생.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl exec -it -n ingress-nginx deployments/ingress-nginx-controller -- /nginx-ingress-controller --help | grep ssl
      --default-ssl-certificate string          Secret containing a SSL certificate to be used by the default HTTPS server (catch-all).
      --enable-ssl-chain-completion             Autocomplete SSL certificate chains with missing intermediate CA certificates.
      --enable-ssl-passthrough                  Enable SSL Passthrough.
      --ssl-passthrough-proxy-port int          Port to use internally for SSL Passthrough. (default 442)
  
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ KUBE_EDITOR="vi" kubectl edit -n ingress-nginx deployments/ingress-nginx-controller

      containers:
      - args:
        - /nginx-ingress-controller
        - --election-id=ingress-nginx-leader
        - --controller-class=k8s.io/ingress-nginx
        - --ingress-class=nginx
        - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
        - --validating-webhook=:8443
        - --validating-webhook-certificate=/usr/local/certificates/cert
        - --validating-webhook-key=/usr/local/certificates/key
        - --watch-ingress-without-class=true
        - --publish-status-address=localhost
        - --enable-ssl-passthrough
        
deployment.apps/ingress-nginx-controller edited

 

  • Argo CD 설치 + Ingress by Helm
  •  

  두 가지 SSL 처리 방식

  • Termination 모드: 인증서는 Ingress가 사용
  • Passthrough 모드: 인증서는 Argo CD 서버 Pod가 사용
TLS Termination Ingress(NGINX)가 HTTPS 트래픽을 받아서 직접 복호화 Ingress가 tls.secretName 인증서를 직접 사용
TLS Passthrough Ingress가 트래픽을 복호화하지 않고 그대로 전달 Argo CD(백엔드)가 자체 인증서로 복호화

  • 자체 서명(Self-signed) SSL 인증서를 생성 
    argocd.example.com.key 개인키 (Private Key)
    argocd.example.com.crt 공개 인증서 (Certificate)
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout argocd.example.com.key \
  -out argocd.example.com.crt \
  -subj "/CN=argocd.example.com/O=argocd"
....+...+.....+...+...+.......+.........+........+.+..+....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+....+..+............+...+...+.+.........+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...........+.....+.+...+..+...+......+...............+.+......+........+....+...+.....+.......+..+...+.+..+....+...........+..........+...+..+...+......+................+...+..+...+................+...+...+............+..+....+......+...+..+....+..+...+.+......+..+.............+.........+........+............+.+.....+...+......+......+...........................+.+.....+.+........+.+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
..+.......+........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*......+......+..+.+............+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+..+...+.+..+.........+....+.....+....+......+..+.........+...............+...+............+...+............+................+.................+.......+......+...+..+...+....+...+....................+...+....+..+.+..+.......+...+...+...+.....+.......+.....+....+...+........+...+...............+.+...+..+...+.+......+........+......+.........+......+.+...+......+.....+........................+......+.......+..+............+.+........+.+......+..............+.+..+...+...+...............+......+......+....+.....+......+....+......+..+......+......+...+............+.+...+..+...+....+...+..............+.+........+.......+...+......+...............+...........+...+....+..+....+............+...+.....+....+..+.+............+...+.....+...+..........+......+.....+.............+...+..+......+......+...............+...+............+...+.......+...+......+..+...+....+.....+.+..+.............+......+...+.....+...+.......+...+...+......+....................+.+.....+...+.+.....+....+.....+......+....+......+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ ls -l argocd.example.com.*
-rw-r--r-- 1 ssoon ssoon 1184 Nov 12 17:06 argocd.example.com.crt
-rw------- 1 ssoon ssoon 1704 Nov 12 17:06 argocd.example.com.key
  • Argo CD용 TLS 인증서 설정
    • Argo CD를 위한 전용 네임스페이스(argocd)를 생성
    • 앞서 만든 인증서(.crt)와 개인키(.key)를 기반으로 Kubernetes Secret을 생성
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl create ns argocd
namespace/argocd created

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl -n argocd create secret tls argocd-server-tls \
  --cert=argocd.example.com.crt \
  --key=argocd.example.com.key
secret/argocd-server-tls created

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl get secret -n argocd
NAME                TYPE                DATA   AGE
argocd-server-tls   kubernetes.io/tls   2      4s
  • Helm Chart를 사용해 Argo CD를 HTTPS(SSL Passthrough) 로 배포하기 위한 설정
  • 1️⃣ global.domain : Argo CD의 외부 접속 도메인 
  • 2️⃣ server.ingress : Argo CD 서버용 Ingress를 생성
force-ssl-redirect HTTP 요청을 HTTPS로 자동 리다이렉트
ssl-passthrough SSL Passthrough 활성화 — 암호화된 트래픽을 백엔드(Argo CD 서버)로 그대로 전달
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ cat <<EOF > argocd-values.yaml
global:
  domain: argocd.example.com

server:
  ingress:
    enabled: true
    ingressClassName: nginx
    annotations:
      nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
      nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    tls: true
EOF
  • Argo CD Helm 배포
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ helm repo add argo https://argoproj.github.io/argo-helm
"argo" already exists with the same configuration, skipping

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ helm install argocd argo/argo-cd --version 9.0.5 -f argocd-values.yaml --namespace argocd
NAME: argocd
LAST DEPLOYED: Wed Nov 12 17:16:53 2025
NAMESPACE: argocd
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
In order to access the server UI you have the following options:

1. kubectl port-forward service/argocd-server -n argocd 8080:443

    and then open the browser on http://localhost:8080 and accept the certificate

2. enable ingress in the values file `server.ingress.enabled` and either
      - Add the annotation for ssl passthrough: https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/#option-1-ssl-passthrough
      - Set the `configs.params."server.insecure"` in the values file and terminate SSL at your ingress: https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/#option-2-multiple-ingress-objects-and-hosts


After reaching the UI the first time you can login with username: admin and the random password generated during the installation. You can find the password by running:

kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

(You should delete the initial secret afterwards as suggested by the Getting Started Guide: https://argo-cd.readthedocs.io/en/stable/getting_started/#4-login-using-the-cli)
  • Ingress가 정상적으로 생성

 

CLASS nginx — NGINX Ingress Controller가 라우팅 담당
HOSTS argocd.example.com — 브라우저 접근용 도메인
ADDRESS localhost — 현재 Ingress Controller의 엔드포인트(IP)
PORTS 80, 443 — HTTP/HTTPS 둘 다 열림
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl get ingress -n argocd argocd-server
NAME            CLASS   HOSTS                ADDRESS     PORTS     AGE
argocd-server   nginx   argocd.example.com   localhost   80, 443   15m
  •  Ingress 설정
Host argocd.example.com 브라우저 접속 도메인
IngressClassName nginx NGINX Ingress Controller 사용
annotations force-ssl-redirect: "true", ssl-passthrough: "true" HTTPS 리다이렉트 및 SSL Passthrough 활성화
Service backend argocd-server:443 Argo CD 서버 서비스의 HTTPS 포트로 직접 연결
tls.secretName argocd-server-tls Argo CD에서 사용할 인증서 Secret
loadBalancer.ingress.hostname localhost kind / minikube 환경으로 추정, 로컬 IP(127.0.0.1) 사용 가능
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl get ingress -n argocd argocd-server -o yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    meta.helm.sh/release-name: argocd
    meta.helm.sh/release-namespace: argocd
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
  creationTimestamp: "2025-11-12T08:17:23Z"
  generation: 1
  labels:
    app.kubernetes.io/component: server
    app.kubernetes.io/instance: argocd
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: argocd-server
    app.kubernetes.io/part-of: argocd
    app.kubernetes.io/version: v3.1.9
    helm.sh/chart: argo-cd-9.0.5
  name: argocd-server
  namespace: argocd
  resourceVersion: "4582"
  uid: d5aa6339-b666-4062-a176-331066650355
spec:
  ingressClassName: nginx
  rules:
  - host: argocd.example.com
    http:
      paths:
      - backend:
          service:
            name: argocd-server
            port:
              number: 443
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - argocd.example.com
    secretName: argocd-server-tls
status:
  loadBalancer:
    ingress:
    - hostname: localhost
  • 동작 구조 (SSL Passthrough 모드)
    • NGINX는 트래픽을 단순 전달만 하고 실제 SSL 처리는 Argo CD Pod 내부에서 수행
[브라우저]
   ↓ HTTPS (암호화된 채로)
[NGINX Ingress Controller]
   ↓ 암호 해독 없이 그대로 전달 (SSL Passthrough)
[argocd-server Pod :443]
   ↓
[내부 argocd-server-tls Secret 사용해 복호화]

 

  Helm Chart가 문제!

    • Argo CD의 Helm Chart는 내부적으로 “Ingress 설정을 생성할 때, TLS 관련 항목(tls.secretName)이 있어야 한다” 라고 강제로 기대하는 부분이 있습니다.
    • 즉, Passthrough 모드에서는 Ingress가 인증서를 사용하지 않는데도, Helm Chart는 tls.secretName 값이 없으면 에러나 잘못된 YAML을 생성할 수도 있습니다. 그래서 "형식상" 그 값을 넣어줘야 하는 겁니다.

 Passthrough 모드일 때 실제 흐름

      • 브라우저 → NGINX(그냥 통과) → Argo CD 서버(복호화)
      • Ingress의 tls.secretName은 실제로 사용되지 않음
      • 하지만 Helm Chart가 tls.secretName을 요구할 수 있음
      • 그래서 "안전하게" 그 Secret(argocd-server-tls)을 만들어 두는 것!
      TLS Passthrough Argo CD Pod Helm Chart가 형식상 요구함
      TLS Termination Ingress Controller Ingress가 직접 사용함 (필수)
  • C:\Windows\System32\drivers\etc\hosts 관리자모드에서 메모장에 내용 추가 
127.0.0.1 argocd.example.com
  • 최초 접속 암호 확인
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d ;echo
6aT34CdOgpWoAm1t
  • Argo CD 웹 접속 주소 확인 : 초기 암호 입력 (admin 계정)
    • 인증서 정보 확인 : 발급 기관에 O, CN 정보
⚠️  SSL Passthrough을 사용하고 있으므로, 인증서는 Argo CD Pod이 직접 제공하게 됩니다.
(브라우저에서 “보안 인증서가 신뢰되지 않음” 경고가 뜨는 것은 정상입니다 — 자체 서명 인증서이기 때문)

  • argocd 서버 cli 로그인
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ argocd login argocd.example.com --insecure
Username: admin
Password:
'admin:login' logged in successfully
Context 'argocd.example.com' updated

👥 Declarative Users

  • Argo CD의 접근 제어를 이해하기 전에, OWASP Top Ten을 살펴보면 “Broken Access Control”이 2021년판 기준 가장 큰 보안 리스크 1위로 선정되었습니다.
  • 이는 그만큼 잘못된 접근 권한 설정이 심각한 보안 위협이 될 수 있음을 보여줍니다.

“올바른 접근 제어 설정은 시스템 보안을 지키는 첫 번째 방어선이다.”


🔑 Admin 및 Local User

  • Argo CD 설치 직후에는 admin 사용자만 존재합니다.
    이때 기본 비밀번호는 과거에는 argocd-server-xxxxx 형식의 Pod 이름이었지만, 보안 취약점(CVE-2020-8828)으로 인해 현재는 랜덤 비밀번호가 자동 생성되어 argocd-initial-admin-secret Secret에 저장됩니다.
  • 비밀번호 확인 명령어:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
6aT34CdOgpWoAm1t

 

  • 비밀번호의 % 기호는 shell의 줄바꿈 문자이므로 제거해야 합니다.
  • 이 비밀번호로 UI 또는 CLI를 통해 로그인할 수 있습니다. 비밀번호 변경은 UI의 User Info 메뉴나 아래 CLI 명령으로 가능합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ argocd account update-password
*** Enter password of currently logged in user (admin):
*** Enter new password for user admin:
*** Confirm new password for user admin:
Password updated
Context 'argocd.example.com' updated
  • 비밀번호를 잊었다면 argocd-secret 리소스에서 bcrypt 해시를 직접 수정하여 재설정할 수 있습니다. 

“admin 계정은 너무 강력하므로, 실운영 환경에서는 반드시 비활성화하고 별도의 사용자 계정을 생성해야 합니다.”


👩‍💻 새 사용자 (Local User) 생성

  • 운영 환경에서는 개별 사용자 계정을 선언적으로 관리해야 합니다.
  • 공용 계정을 사용하면 추적이 어렵고, 사용자별 권한 제어가 불가능하기 때문입니다.
  • 아래는 alice라는 로컬 사용자를 추가
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ KUBE_EDITOR="vi"  kubectl edit cm -n argocd argocd-cm
apiVersion: v1
data:
  accounts.alice: apiKey, login


configmap/argocd-cm edited

  • CLI에서 사용자 생성 확인:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ argocd account list
NAME   ENABLED  CAPABILITIES
admin  true     login
alice  true     apiKey, login

 


🔐 사용자 비밀번호 설정

  • 다음 명령으로 alce 계정의 비밀번호를 설정할 수 있습니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ argocd account update-password \
  --account alice \
  --current-password qwe12345 \
  --new-password alice12345
Password updated
  • 비밀번호를 명령줄에서 직접 입력하지 않으면, CLI가 대화형 입력 모드로 전환되어 기록에 남지 않도록 입력할 수 있습니다.

“비밀번호는 CLI 이력(history)에 남지 않도록 대화형으로 입력하는 것이 안전합니다.”


🧩 사용자 정보 확인

  • 사용자 계정 정보는 argocd-secret Secret 리소스에 저장됩니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl get secret -n argocd argocd-secret -o jsonpath='{.data}' | jq
{
  "accounts.alice.password": "JDJhJDEwJFZCWnNMM1pkR2pBUnB6NXY4TmZpTE9vMHRBSWlnU3FYa1RKM0xPSlljYmg3ZXd5b3BmZldP",
  "accounts.alice.passwordMtime": "MjAyNS0xMS0xMlQwOToyMDowNFo=",
  "accounts.alice.tokens": "bnVsbA==",
  "admin.password": "JDJhJDEwJE5SZ3RFeGNOYVMuV2oyQk9zcGcyMk9mMmhHREZLMDE2UnU0d2N1RVlhRVZkLzhKTDUzNXBX",
  "admin.passwordMtime": "MjAyNS0xMS0xMlQwOTowNjo1MVo=",
  "server.secretkey": "L1V2V0pPTGJKY2N4d3FQaElGanZ5MWhGM3JqWEhRS25hQXRDeXd0dExRST0="
}

 

  • accounts.alina.tokens 값이 null이면 아직 토큰이 발급되지 않았음을 의미합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl get secret -n argocd argocd-secret -o jsonpath='{.data.accounts\.alice\.tokens}' | base64 -d ; echo
null

“토큰이 null이면 해당 계정은 아직 인증 토큰을 발급받지 않은 상태입니다.”


  • 샘플 애플리케이션 배포
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ cat <<EOF | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    helm:
      valueFiles:
      - values.yaml
    path: helm-guestbook
    repoURL: https://github.com/argoproj/argocd-example-apps
    targetRevision: HEAD
  syncPolicy:
    automated:
      enabled: true
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=true
  destination:
    namespace: guestbook
    server: https://kubernetes.default.svc
EOF
Warning: metadata.finalizers: "resources-finalizer.argocd.argoproj.io": prefer a domain-qualified finalizer name including a path (/) to avoid accidental conflicts with other finalizer writers
application.argoproj.io/guestbook created
  • argo ui admin logout 후 → alice 로그인 후 확인 : 권한이 없으므로, application 이나 cluster 정보 안보임

 

 

 

🧱 Role-Based Access Control (RBAC) 기본 설정

  • 새로운 사용자(alina)는 기본적으로 아무 권한도 없습니다.
    이때 기본 정책(default policy) 을 설정하면, 특정 권한이 지정되지 않은 사용자에게 공통 권한을 부여할 수 있습니다.
  • RBAC 구성을 정의할 수 있는 두 가지 주요 구성 요소
  • 기본 내장 역할 : Argo CD에는 두 가지 사전 정의된 역할이 있지만 RBAC 구성을 사용하면 역할과 그룹을 정의할 수 있습니다(아래 참조).
    • role:readonly : 모든 리소스에 대한 읽기 전용 액세스
    • role:admin : 모든 리소스에 대한 무제한 액세스
  • 사용자가 Argo CD에서 인증되면 policy.default 에 지정된 역할이 부여됩니다
  • argocd-rbac-cm.yaml 파일을 생성하여 다음과 같이 작성합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl get cm -n argocd argocd-rbac-cm -o jsonpath='{.data}' | jq
{
  "policy.csv": "",
  "policy.default": "",
  "policy.matchMode": "glob",
  "scopes": "[groups]"
}

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ KUBE_EDITOR="vi" kubectl edit cm -n argocd argocd-rbac-cm
apiVersion: v1
data:
  policy.csv: ""
  policy.default: role:readonly
  policy.matchMode: glob
  scopes: '[groups]'
  
configmap/argocd-rbac-cm edited
  • alice 로그인 상태에서 새로고침하여 app, cluster 정보 확인

 

 

“policy.default 설정은 모든 사용자에게 적용되는 기본 권한을 정의합니다.”


🧭 CLI에서 사용자 로그인 테스트

  • 이제 alice 사용자로 CLI 로그인 테스트를 진행합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ argocd login argocd.example.com --insecure --username alice
Password:
'alice:login' logged in successfully
Context 'argocd.example.com' updated
  • 로그인 후, 읽기 권한이 정상 동작하는지 애플리케이션 목록을 조회합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ argocd app list
NAME              CLUSTER                         NAMESPACE  PROJECT  STATUS  HEALTH   SYNCPOLICY  CONDITIONS  REPO                                             PATH            TARGET
argocd/guestbook  https://kubernetes.default.svc  guestbook  default  Synced  Healthy  Auto-Prune  <none>      https://github.com/argoproj/argocd-example-apps  helm-guestbook  HEAD

 

“RBAC 설정 후 read-only 권한으로 애플리케이션 목록이 정상적으로 표시된다면 성공입니다.”


🚫 Admin 사용자 비활성화

  • 마지막으로 admin 계정 비활성화를 통해 보안을 강화합니다.
    argocd-cm ConfigMap을 수정하여 아래 항목을 추가합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ KUBE_EDITOR="vi"  kubectl edit cm -n argocd argocd-cm
configmap/argocd-cm edited

apiVersion: v1
data:
  accounts.alice: apiKey,login
  admin.enabled: "false"
  
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ argocd account list
NAME   ENABLED  CAPABILITIES
admin  false    login
alice  true     apiKey, login

 

“admin.enabled: false 설정으로 기본 admin 계정을 완전히 비활성화합니다.”


📌 핵심 요약

  • Argo CD 설치 시 admin 계정만 존재하며, 초기 비밀번호는 argocd-initial-admin-secret에 저장된다.
  • 보안 강화를 위해 개별 로컬 사용자 계정을 생성하고 admin 계정은 비활성화해야 한다.
  • 사용자 계정은 argocd-cm ConfigMap에 선언적으로 정의한다.
  • 기본 접근 정책(policy.default)은 argocd-rbac-cm ConfigMap에서 설정한다.
  • CLI 로그인 및 권한 테스트를 통해 사용자 접근 제어를 검증할 수 있다.
  • 모든 설정은 GitOps 방식으로 관리하여 Argo CD가 자동 반영하도록 구성한다.

“Argo CD의 접근 제어는 단순한 사용자 관리가 아닌, 시스템 전체의 보안 체계를 강화하는 핵심 구성요소다.”


Comments