본문 바로가기
DevOps

Argo CD에서 “읽기 전용(READ-ONLY)” 사용자 만들기 (Helm/Terraform 예시)

by Rainbound-IT 2025. 8. 29.
반응형

 

 

  1. 로컬 계정 하나 만들고
  2. role:readonly 를 정의해 조회만 허용
  3. policy.default 를 role:readonly 로 두되, admin은 명시적으로 전권 매핑
  4. Helm values 로 관리하고, 적용 후 argocd-server 재시작 → 비밀번호/토큰 발급 → 권한 확인

1) 개념 한 줄 요약

  • Argo CD 권한은 Casbin 정책(policy.csv) 으로 정의합니다.
    • p, <주체/역할>, <리소스>, <액션>, <오브젝트>, allow|deny
    • g, <사용자>, role:<역할> (사용자→역할 매핑)
  • policy.default 는 매핑되지 않은 사용자의 기본 역할입니다.
  • deny가 allow를 이깁니다. 읽기 전용 역할에 굳이 deny 줄을 많이 넣기보다, “허용만 명시”하는 편이 안전합니다.
  • admin은 반드시 명시 매핑하세요. 기본 역할이 readonly이면 admin도 읽기 전용처럼 보일 수 있습니다.

2) Helm/Terraform 값 예시 (권장)

Terraform의 helm_release.argocd.values 에 아래를 넣습니다.
읽기 전용 계정 이름은 예시로 barun-user 를 사용했습니다.

 
configs:
  # 서버를 HTTP로 노출하는 예 (내부망)
  params:
    server.insecure: "true"

  cm:
    # 로컬 계정: UI 로그인 + API 토큰 발급 허용
    accounts.barun-user: "apiKey, login"
    # (선택) RBAC 디버그 로그
    server.rbac.log.enforce.enable: "true"
    # (중요) 서버가 스스로 인식하는 공식 URL (ALB/Ingress와 일치)
    url: "http://<ALB_DNS>:8080"

  rbac:
    policy.csv: |
      # --- admin: 전권 허용(역할 + 사용자 직접 허용) ---
      p, role:admin, *, *, */*, allow
      p, admin,     *, *, */*, allow
      g, admin, role:admin

      # --- readonly: 조회만 허용 (허용만 명시, 불필요한 deny는 제거) ---
      p, role:readonly, applications, get, */*, allow
      p, role:readonly, projects,     get, */*, allow
      p, role:readonly, repositories, get, */*, allow
      p, role:readonly, clusters,     get, */*, allow
      p, role:readonly, logs,         get, */*, allow

      # --- 사용자 매핑 ---
      g, barun-user, role:readonly

    # 기본값: 매핑 없는 사용자는 읽기 전용
    policy.default: role:readonly
 
 

✅ 포인트

  • admin 전권 라인 2개: p, role:admin, … allow + p, admin, … allow (보험용)
  • readonly는 허용만 적어도 충분합니다. (허용 외 액션은 자동 거부)
  • CM/ConfigMap을 Helm values로만 관리하세요. 수동 kubectl edit 는 드리프트를 유발합니다.

3) 적용과 재시작

 
 
terraform apply -auto-approve

# 정책 재적용을 위해 서버 재시작
kubectl -n argocd rollout restart deploy/argocd-server
kubectl -n argocd rollout status  deploy/argocd-server
 

반영 확인:

 
kubectl -n argocd get cm argocd-rbac-cm -o jsonpath='{.data.policy\.csv}'
kubectl -n argocd get cm argocd-cm      -o jsonpath='{.data.url}'
 

4) 비밀번호/토큰 발급

관리자(admin)로 로그인된 상태에서:

 
# (UI/CLI 어느 쪽이든 admin으로 로그인)

# 읽기 전용 사용자 비밀번호 설정
argocd account update-password --account barun-user

# API 토큰(만료 기본 없음) 발급
argocd account generate-token --account barun-user
 
 

참고: API 토큰은 기본 만료가 없습니다. 필요 시 토큰 회수/재발급으로 관리하세요.
(세션 토큰은 만료가 있지만 account generate-token 으로 받는 API 토큰은 기본 무기한)


5) 로그인 및 동작 확인

UI 로그인

  • ID: barun-user
  • 비밀번호: 위에서 설정한 값
  • Application, Project, Repo 목록 조회가 되고, Sync/Update/Delete 버튼은 허용되지 않아야 정상입니다.

CLI (HTTP라면)

# HTTP + gRPC-Web 환경
argocd login <ALB_DNS>:8080 --username barun-user --password '<PW>' --grpc-web --plaintext
# (특정 환경에서 TLS 사전 테스트가 타임아웃나면 --skip-test-tls 를 추가해도 됩니다)
 
 
 

권한 확인

# 현재 로그인 계정과 매핑된 Role 확인
argocd account get-user-info
# 기대값: username=barun-user, groups=[role:readonly] 혹은 비어있어도 실제 정책이 적용되면 OK

# 읽기만 허용 → Sync 같은 변경 작업은 거부되어야 정상
argocd app sync <APP_NAME>     # => permission denied
argocd app get  <APP_NAME>     # => OK (조회)
 
 
 

6) 흔한 함정 & 해결

  • admin이 읽기 전용처럼 보일 때
    • 원인: policy.default: role:readonly + admin 매핑 누락/정책 미반영
    • 해결: g, admin, role:admin 과 p, role:admin, … allow + p, admin, … allow 를 반드시 넣고 서버 재시작
  • readonly에 deny를 잔뜩 넣었더니 admin도 막힘
    • Casbin은 deny가 allow를 이깁니다.
    • 해결: readonly는 “허용만 명시”, 또는 admin 전권을 명시하고 deny는 최소화
  • Helm이 CM을 관리 중인데 kubectl로 수정
    • 다음 apply 때 되돌아갑니다. 반드시 Helm values로 관리하세요.
  • 로그인 타임아웃(context deadline exceeded)
    • HTTP/ALB 환경이면 Ingress에 /grpc, /api, / 를 Prefix로 분리하고
      alb.ingress.kubernetes.io/backend-protocol-version: "HTTP1" + 헬스체크 /api/version 권장
    • CLI는 --grpc-web --plaintext (필요 시 --skip-test-tls)
    • configs.cm.url 이 실제 노출 URL과 일치해야 합니다.

7) Helm 없이 순정 매니페스트로 하는 방법(참고용)

argocd-rbac-cm:

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
data:
  policy.csv: |
    p, role:admin, *, *, */*, allow
    p, admin,     *, *, */*, allow
    g, admin, role:admin

    p, role:readonly, applications, get, */*, allow
    p, role:readonly, projects,     get, */*, allow
    p, role:readonly, repositories, get, */*, allow
    p, role:readonly, clusters,     get, */*, allow
    p, role:readonly, logs,         get, */*, allow

    g, barun-user, role:readonly
  policy.default: role:readonly
 
 
 

argocd-cm (계정과 URL):

 
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  accounts.barun-user: "apiKey, login"
  url: "http://<ALB_DNS>:8080"
 
 

적용 후 argocd-server 를 재시작하세요.


마무리

  • 핵심은 세 줄입니다:
    1. accounts.<name>: "apiKey, login" (계정 생성)
    2. p, role:readonly, … get … allow (읽기만 허용)
    3. g, <name>, role:readonly (사용자→역할 매핑)
  • 운영에서는 admin 전권을 명시해 기본 역할 정책에 휘둘리지 않도록 하고,
    readonly 정책은 허용만 적는 방식으로 깔끔하게 유지하는 걸 추천합니다.
반응형

댓글