본문으로 건너뛰기
← Systems Notebook / Ops
MLOps Notes05 / 15

Keycloak에서 Argo CD 권한까지: OIDC 그룹과 프로젝트별 RBAC

Keycloak의 그룹 클레임을 Argo CD RBAC와 AppProject에 연결하고, 팀별로 조회와 동기화가 허용되는 범위를 확인합니다.

이 글의 배경

HPE 엔지니어의 작업 자료를 바탕으로 정리한 글입니다. 개인 실험 기록이나 HPE 공식 문서와는 구분합니다. 본문의 환경과 버전은 글 작성 당시를 기준으로 합니다.

SSO로 Argo CD에 로그인할 수 있게 되면, 다음으로 사용자가 어떤 작업을 할 수 있어야 하는지 정해야 합니다. 모든 사용자가 모든 애플리케이션을 동기화하고 삭제할 수 있는 상태라면 로그인은 통합되어도 팀별 운영 권한은 구분되지 않습니다.

사용자마다 권한을 직접 지정하면 부서 이동이나 역할 변경 때마다 정책을 수정해야 합니다. 이 실습에서는 조직의 그룹을 애플리케이션 역할로 변환하는 규칙을 사용합니다. Keycloak이 사용자의 소속 그룹을 OIDC의 groups 클레임으로 발급하면, Argo CD가 이 클레임을 Casbin 기반 RBAC 정책의 주체로 읽습니다. 여기에 AppProject를 적용해 허용할 Git 저장소와 배포 대상 클러스터·네임스페이스를 제한합니다.

이 글에서는 다음과 같이 각 계층이 맡는 책임을 구분하고, Keycloak 그룹을 Argo CD의 동작 권한과 배포 범위에 연결하는 실습을 진행합니다.

text
Keycloak: 누가 어느 그룹에 속하는가
Argo CD RBAC: 그 그룹이 어떤 Argo CD 동작을 할 수 있는가
AppProject: 해당 프로젝트가 어느 소스에서 어느 대상으로 배포할 수 있는가
Kubernetes RBAC: Argo CD 컨트롤러가 클러스터에서 실제로 무엇을 할 수 있는가

이 글에서 다루는 것

  • Keycloak 그룹이 OIDC ID Token의 groups 클레임이 되는 과정
  • Argo CD의 인증 설정과 RBAC 설정을 분리하는 이유
  • client secret이 없는 PKCE 방식으로 Argo CD UI와 CLI SSO 구성
  • p 정책과 g 바인딩, <project>/<application> 객체 형식
  • GitOps 운영에 맞춘 조회·동기화 중심 최소 권한
  • AppProject의 sourceRepos, destinations, 리소스 허용 목록
  • 실제 사용자·그룹 클레임·정책 허용 여부를 단계별로 검증하는 방법
  • LDAP 디렉터리를 사용할 때 바뀌는 부분과 바뀌지 않는 부분

실습 환경과 치환값

의미 문서용 값 설명
Keycloak https://sso.lab.example.com 외부에서 접근 가능한 HTTPS issuer
Realm mlops 업무용 Realm
Argo CD https://argocd.lab.example.com Argo CD 외부 URL
OIDC Client ID argocd Keycloak에 등록할 public client
Argo CD Namespace argocd 설치 네임스페이스
Git 저장소 https://gitlab.lab.example.com/platform/web-gitops.git 문서용 GitOps 저장소
실습 사용자 student-01 argocd-web 그룹에 넣을 예제 사용자
LDAP 비밀값 ${LDAP_BIND_PASSWORD} Secret에서만 주입할 bind 자격증명

전제 조건은 다음과 같습니다.

  • Keycloak과 Argo CD가 설치되어 있고 두 URL 모두 유효한 TLS 인증서를 제공합니다.
  • 브라우저와 Argo CD 서버가 sso.lab.example.com을 해석하고 신뢰할 수 있습니다.
  • Argo CD CLI가 설치되어 있으며 실습자는 argocd 네임스페이스의 ConfigMap을 적용할 권한이 있습니다.
  • Gateway API 또는 다른 지원되는 방식으로 Argo CD 외부 URL이 이미 구성되어 있습니다.

인증서 오류를 우회하기 위해 insecure 또는 TLS 검증 생략을 넣지 않습니다. 사설 CA를 쓴다면 CA 인증서를 Argo CD의 신뢰 저장소에 배포합니다.

권한 모델을 먼저 표로 확정한다

설정에 앞서 “누가 무엇을 할 수 있는가”를 표로 정합니다. 이 표가 있어야 정책을 적용한 뒤 허용할 작업과 거절할 작업이 의도대로 구분되는지 검증할 수 있습니다.

Keycloak 그룹 web 프로젝트 ml 프로젝트 플랫폼 전체
argocd-web 조회, 로그 조회, sync 접근 없음 접근 없음
argocd-ml 접근 없음 조회, 로그 조회, sync 접근 없음
argocd-platform-admin 전체 전체 관리자
어떤 그룹에도 없음 접근 없음 접근 없음 접근 없음

이 실습의 팀 역할에는 create, update, delete, override, exec를 부여하지 않습니다. GitOps에서는 Git의 Merge Request와 승인을 거쳐 변경 사항을 반영하도록 구성하기 때문입니다. 팀 사용자가 Argo CD UI에서 해야 하는 작업은 대개 상태 조회, Pod 로그 조회, 승인된 Git 상태로의 sync이므로 이 범위만 허용합니다.

override를 허용하면 Git에 기록된 원하는 상태를 임시 파라미터로 덮을 수 있고, exec를 허용하면 실행 중인 Pod 안에 셸을 열 수 있습니다. 일반 팀 역할에 기본으로 부여하기에는 변경할 수 있는 범위가 넓으므로, 필요한 경우 별도의 비상 역할과 감사 절차를 마련해 추가합니다.

인증부터 인가까지의 데이터 흐름

구조 살펴보기 / 01Keycloak 그룹에서 Argo CD 권한까지
사용자로그인 요청
선택: LDAP사용자 검증·동기화
Keycloak로그인·MFA
01 / 04
먼저 사용자 인증

Keycloak이 로그인·MFA를 처리합니다. LDAP는 선택적으로 연결하는 사용자 디렉터리입니다.

1

사용자 → Keycloak로그인

2

선택: LDAP → Keycloak선택: 사용자 검증·동기화

구성 관계를 차례로 강조합니다. 단계는 실제 실행 순서가 아닙니다.

전체 단계 한눈에 읽기
  1. 먼저 사용자 인증

    Keycloak이 로그인·MFA를 처리합니다. LDAP는 선택적으로 연결하는 사용자 디렉터리입니다.

    • 사용자 → Keycloak: 로그인
    • 선택: LDAP → Keycloak: 선택: 사용자 검증·동기화
  2. 그룹 정보를 토큰에 담기

    Argo CD가 받는 ID Token에는 groups: argocd-web 같은 그룹 정보가 포함됩니다.

    • Keycloak → Argo CD OIDC: ID Token · groups: argocd-web
  3. 그룹을 역할에 연결

    argocd-rbac-cm의 규칙이 그룹과 역할을 연결하고 AppProject web의 권한을 확인합니다.

    • Argo CD OIDC → argocd-rbac-cm: 그룹을 역할에 연결
    • argocd-rbac-cm → AppProject web: 프로젝트 권한 확인
  4. 허용된 저장소와 대상 확인

    AppProject는 사용할 Git 저장소와 배포할 클러스터·Namespace의 범위를 정합니다. 선은 권한 관계이지 배포 트래픽이 아닙니다.

    • AppProject web → 허용된 Git 저장소: 허용 source
    • AppProject web → 허용된 배포 대상: 허용 destination
도식 원문
flowchart LR
  U["사용자"] --> K["Keycloak<br/>로그인·MFA"]
  D["선택: LDAP 디렉터리"] -.->|"사용자 검증·동기화"| K
  K -->|"ID Token<br/>groups: argocd-web"| A["Argo CD OIDC"]
  A --> R["argocd-rbac-cm<br/>그룹 → 역할"]
  R --> P["AppProject web"]
  P --> S["허용된 Git 저장소"]
  P --> N["허용된 클러스터·Namespace"]

그룹이 만들어져 있어도 아래 연결 중 하나가 빠지면 의도한 권한을 사용할 수 없습니다. 각 단계가 다음 단계에 어떤 값을 넘기는지 확인해야 합니다.

  1. Keycloak에 그룹이 있어도 mapper가 없으면 토큰에 나타나지 않습니다.
  2. 토큰에 그룹이 있어도 Argo CD scopes가 해당 클레임을 읽지 않으면 정책 주체가 되지 않습니다.
  3. RBAC가 sync를 허용해도 애플리케이션이 다른 AppProject에 속해 있으면 객체 패턴이 맞지 않습니다.
  4. RBAC가 관리 작업을 허용해도 AppProject가 저장소 또는 대상을 금지하면 배포할 수 없습니다.

이처럼 그룹 정보가 전달되는 경로와 작업을 허용하는 조건을 나눠 확인하면, 로그인 이후 어느 단계에서 접근이 제한되는지 구분할 수 있습니다.

Keycloak 구성

1. 전용 Realm 사용

Keycloak Admin Console에서 mlops Realm을 선택합니다. 없다면 Create realm으로 만듭니다. 서버 관리 전용 Realm에 업무용 Argo CD Client를 만들지 않습니다.

2. Argo CD public client 생성

Argo CD 공식 문서는 client authentication 방식과 PKCE 방식을 모두 제공합니다. 이 글은 UI와 CLI를 함께 사용하면서 Argo CD에 client secret을 저장하지 않는 PKCE 방식을 선택합니다.

Clients → Create client에서 다음처럼 설정합니다.

설정 값
Client type OpenID Connect
Client ID argocd
Client authentication Off
Standard flow On
Direct access grants Off
PKCE method S256

URI는 정확한 경로만 허용합니다.

URI 종류 값
Root URL https://argocd.lab.example.com
Home URL https://argocd.lab.example.com/applications
Valid redirect URI https://argocd.lab.example.com/auth/callback
Valid redirect URI https://argocd.lab.example.com/pkce/verify
CLI callback http://localhost:8085/auth/callback
Web origin https://argocd.lab.example.com
Valid post logout URI https://argocd.lab.example.com/applications

https://argocd.lab.example.com/* 같은 와일드카드는 사용하지 않습니다. CLI의 포트를 바꾸면 Keycloak의 localhost callback과 argocd login --sso-port도 같은 값으로 바꿔야 합니다.

3. 그룹 생성과 사용자 배정

Groups에서 다음 그룹을 만듭니다.

text
argocd-web
argocd-ml
argocd-platform-admin

Users → student-01 → Groups → Join group에서 argocd-web을 선택합니다. 실제 운영에서는 개인에게 관리자 권한을 직접 부여하지 않고, 승인을 거쳐 관리되는 별도 관리자 그룹을 사용합니다.

4. groups 클레임 mapper 생성

Client scopes → Create client scope에서 이름을 groups로 만들고 OIDC 프로토콜을 선택합니다. 이 scope의 Mappers → Configure a new mapper → Group Membership을 선택합니다.

Mapper 설정 값
Name groups
Token Claim Name groups
Full group path Off
Add to ID token On
Add to access token 필요한 API가 있을 때만 On
Add to userinfo On

그다음 Clients → argocd → Client scopes → Add client scope에서 groups를 Default로 연결합니다. Default로 연결하면 Argo CD가 매번 별도 optional scope를 요청하지 않아도 클레임이 들어갑니다. 이 글의 Argo CD 설정에도 groups를 명시해 의도를 분명히 합니다.

Full group path를 Off로 두면 값이 argocd-web, On으로 두면 /argocd-web이 될 수 있습니다. 선택한 방식에 따라 토큰 값이 달라지므로 policy.csv에서도 정확히 같은 값을 사용해야 합니다. 이 글은 Off를 기준으로 합니다.

Argo CD OIDC 구성

다음 파일을 argocd-oidc.yaml로 저장합니다.

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
  labels:
    app.kubernetes.io/part-of: argocd
data:
  url: https://argocd.lab.example.com
  oidc.config: |
    name: Keycloak
    issuer: https://sso.lab.example.com/realms/mlops
    clientID: argocd
    enablePKCEAuthentication: true
    requestedScopes:
      - openid
      - profile
      - email
      - groups

적용 전에 Discovery의 issuer를 확인합니다.

bash
curl --fail --silent --show-error \
  https://sso.lab.example.com/realms/mlops/.well-known/openid-configuration \
  | python3 -c 'import json,sys; print(json.load(sys.stdin)["issuer"])'

출력은 다음과 정확히 같아야 합니다.

text
https://sso.lab.example.com/realms/mlops

ConfigMap을 적용합니다.

bash
kubectl apply -f argocd-oidc.yaml
kubectl -n argocd rollout status deployment/argocd-server --timeout=5m

Argo CD는 ConfigMap 변경을 감지하지만, 로그인 버튼이 갱신되지 않거나 기존 Pod가 이전 설정을 유지한다면 다음처럼 안전하게 순차 재시작합니다.

bash
kubectl -n argocd rollout restart deployment/argocd-server
kubectl -n argocd rollout status deployment/argocd-server --timeout=5m

브라우저에서 https://argocd.lab.example.com을 열었을 때 LOG IN VIA KEYCLOAK 버튼이 보여야 합니다.

AppProject로 배포 가능 범위를 제한한다

RBAC는 사용자가 Argo CD API로 어떤 행동을 할 수 있는지 정합니다. AppProject는 애플리케이션이 어떤 소스를 참조하고 어디에 배포할 수 있는지 정합니다. 사용자에게 sync 권한을 주더라도 배포 범위를 제한할 수 있도록 두 설정을 함께 사용해야 합니다.

다음은 web과 ml 프로젝트를 구분하는 argocd-projects.yaml입니다. 실습용 예제도 저장소와 네임스페이스를 *로 열지 않습니다.

yaml
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: web
  namespace: argocd
spec:
  description: Web workloads
  sourceRepos:
    - https://gitlab.lab.example.com/platform/web-gitops.git
  destinations:
    - server: https://kubernetes.default.svc
      namespace: web-*
  namespaceResourceWhitelist:
    - group: ""
      kind: ConfigMap
    - group: ""
      kind: Service
    - group: ""
      kind: ServiceAccount
    - group: apps
      kind: Deployment
    - group: apps
      kind: StatefulSet
    - group: autoscaling
      kind: HorizontalPodAutoscaler
    - group: gateway.networking.k8s.io
      kind: HTTPRoute
  orphanedResources:
    warn: true
---
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: ml
  namespace: argocd
spec:
  description: ML workloads
  sourceRepos:
    - https://gitlab.lab.example.com/platform/ml-gitops.git
  destinations:
    - server: https://kubernetes.default.svc
      namespace: ml-*
  namespaceResourceWhitelist:
    - group: ""
      kind: ConfigMap
    - group: ""
      kind: Service
    - group: ""
      kind: ServiceAccount
    - group: apps
      kind: Deployment
    - group: batch
      kind: Job
    - group: ray.io
      kind: RayJob
    - group: serving.kserve.io
      kind: InferenceService
  orphanedResources:
    warn: true
bash
kubectl apply -f argocd-projects.yaml
kubectl -n argocd get appprojects web ml

이 예제의 허용 목록에는 Secret, RoleBinding, 클러스터 범위 리소스를 넣지 않습니다. 애플리케이션에 필요한 리소스가 더 있다면 사용 목적을 검토한 뒤 추가합니다. External Secrets 같은 별도 비밀 관리 컨트롤러를 사용하는 경우에는 해당 CRD만 허용하고 평문 Secret을 Git에 두지 않습니다.

Argo CD RBAC 정책 작성

Argo CD 정책의 기본 형식은 다음과 같습니다.

text
p, <주체 또는 역할>, <리소스>, <행동>, <객체>, <효과>
g, <사용자 또는 그룹>, <역할>

Application 계열 객체는 기본적으로 <AppProject>/<Application> 형식을 사용합니다. 따라서 web/*은 web AppProject 안의 모든 Application을 뜻합니다.

다음 파일을 argocd-rbac.yaml로 저장합니다.

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
  labels:
    app.kubernetes.io/part-of: argocd
data:
  scopes: "[groups]"
  policy.matchMode: glob
  policy.default: role:authenticated
  policy.csv: |
    # 기본 인증 역할에는 의도적으로 권한을 추가하지 않는다.

    # web 프로젝트 운영 역할
    p, role:web-operator, projects, get, web, allow
    p, role:web-operator, applications, get, web/*, allow
    p, role:web-operator, applications, sync, web/*, allow
    p, role:web-operator, logs, get, web/*, allow

    # ml 프로젝트 운영 역할
    p, role:ml-operator, projects, get, ml, allow
    p, role:ml-operator, applications, get, ml/*, allow
    p, role:ml-operator, applications, sync, ml/*, allow
    p, role:ml-operator, logs, get, ml/*, allow

    # Keycloak 그룹을 Argo CD 내부 역할에 연결
    g, argocd-web, role:web-operator
    g, argocd-ml, role:ml-operator
    g, argocd-platform-admin, role:admin
bash
kubectl apply -f argocd-rbac.yaml
kubectl -n argocd get configmap argocd-rbac-cm -o yaml

policy.default를 기본 제공 role:readonly로 두면 로그인한 모든 사용자가 전체 애플리케이션을 읽을 수 있습니다. 이 글에서는 권한 없는 role:authenticated를 기본값으로 두고 그룹별 정책만 허용합니다. Argo CD 공식 문서가 설명하듯 default role에 부여된 권한은 개별 deny 규칙으로 회수할 수 없으므로 기본 역할을 최소화하는 것이 중요합니다.

왜 deny 규칙보다 좁은 allow가 중요한가

Argo CD RBAC에서는 필요한 행동을 명시적인 allow 목록으로 작성하면 허용 범위를 검토하기 쉽습니다. 넓은 allow 뒤에 일부 deny를 붙이는 방식은 glob 패턴과 리소스별 행동을 놓칠 수 있습니다. 다음 권한은 사용자가 실제로 할 수 있게 되는 작업을 확인하고 필요성을 별도로 검토합니다.

  • applications, override: Git 상태를 임시로 덮을 수 있습니다.
  • applications, delete: Application 또는 관리 리소스를 삭제할 수 있으므로 허용되는 삭제 범위를 확인합니다.
  • applicationsets, create: 여러 Application을 생성할 수 있습니다.
  • exec, create: Pod 내부에서 명령을 실행할 수 있습니다.
  • extensions, invoke: 프록시 확장을 호출할 수 있습니다.
  • repositories, clusters: 자격증명과 배포 대상을 관리하는 데 관여하므로 팀 역할에 필요한 범위를 별도로 검토합니다.

검증: 로그인과 권한

1. 브라우저 SSO 확인

브라우저의 시크릿 창을 사용하면 기존 Keycloak 세션으로 인해 다른 사용자가 자동 로그인되는 혼동을 줄일 수 있습니다.

  1. Argo CD 로그인 화면에서 LOG IN VIA KEYCLOAK을 선택합니다.
  2. student-01로 로그인합니다.
  3. 우측 상단 User Info에서 groups에 argocd-web이 보이는지 확인합니다.
  4. web 프로젝트는 보이고 ml 프로젝트는 보이지 않는지 확인합니다.
  5. web Application의 sync와 로그 조회가 가능하고 삭제·override·exec는 불가능한지 확인합니다.

2. CLI PKCE 로그인

bash
argocd login argocd.lab.example.com \
  --sso \
  --sso-port 8085 \
  --grpc-web

argocd account get-user-info

예상 결과의 핵심은 사용자 이름과 다음 그룹입니다.

text
Groups: argocd-web

인증서 검증을 우회하는 --insecure는 넣지 않습니다. CLI가 사설 CA를 신뢰하지 못한다면 운영체제 신뢰 저장소에 CA를 설치합니다.

3. 정책 파일 정적 검증

ConfigMap의 policy.csv 부분을 별도 policy.csv로 저장한 뒤 Argo CD CLI의 RBAC 검사 기능을 사용합니다.

bash
argocd admin settings rbac validate --policy-file policy.csv

argocd admin settings rbac can \
  argocd-web sync application 'web/sample-app' \
  --policy-file policy.csv

argocd admin settings rbac can \
  argocd-web sync application 'ml/training-app' \
  --policy-file policy.csv

argocd admin settings rbac can \
  argocd-web delete application 'web/sample-app' \
  --policy-file policy.csv

예상 결과는 순서대로 정책 유효, yes, no, no입니다. 배포 전에 CI에서 이 검사를 실행하면 오타와 과도한 권한을 Merge Request 단계에서 차단할 수 있습니다.

4. 실제 Application이 올바른 Project에 속하는지 확인

bash
kubectl -n argocd get applications.argoproj.io \
  -o custom-columns='NAME:.metadata.name,PROJECT:.spec.project,DEST:.spec.destination.namespace'

정책 객체가 web/*이어도 Application의 spec.project가 default라면 일치하지 않습니다. 권한 문제처럼 보이지만 실제로는 Application 분류 문제일 수 있습니다.

LDAP 디렉터리를 사용하는 경우

이 실습은 기존 디렉터리 없이도 재현할 수 있도록 Keycloak 로컬 사용자를 기준으로 합니다. LDAP 또는 Active Directory를 연결하는 환경에서도 Argo CD 이후의 구조는 그대로 사용할 수 있습니다.

text
LDAP 사용자/그룹
  → Keycloak User Federation과 LDAP mapper
  → Keycloak의 사용자·그룹 모델
  → OIDC groups 클레임
  → Argo CD RBAC

Keycloak User Federation → Add LDAP provider에서 연결할 때는 다음 원칙을 적용합니다.

  • 가능하면 ldaps://ldap.lab.example.com:636 또는 StartTLS를 사용합니다.
  • Bind DN은 읽기 전용 최소 권한 서비스 계정으로 만듭니다.
  • bind 비밀번호는 ${LDAP_BIND_PASSWORD} 같은 Secret으로 관리합니다.
  • 사용자 DN, 로그인 속성(uid 또는 sAMAccountName), 고유 ID 속성을 디렉터리 스키마에 맞춥니다.
  • LDAP 그룹을 쓸 경우 group LDAP mapper의 DN과 동기화 방향을 명시합니다.
  • 가져온 전체 조직 그룹을 토큰에 싣지 말고 Argo CD에 필요한 그룹만 scope로 제한합니다.

LDAP 사용자 동기화가 성공해도 그룹이 토큰과 Argo CD까지 전달되었는지는 별도로 확인해야 합니다. Keycloak 사용자 화면, OIDC Token, Argo CD User Info의 세 위치를 비교해 그룹이 동일한지 확인합니다.

문제 해결

로그인 버튼이 보이지 않는다

bash
kubectl -n argocd get configmap argocd-cm -o jsonpath='{.data.oidc\.config}'
kubectl -n argocd logs deployment/argocd-server --since=10m

oidc.config 들여쓰기, issuer, url을 확인합니다. ConfigMap 이름과 app.kubernetes.io/part-of: argocd 라벨도 확인합니다.

Keycloak 로그인 후 redirect 오류가 난다

Argo CD가 실제로 보내는 callback과 Keycloak의 Valid Redirect URIs를 비교합니다. 외부 프록시가 Argo CD에 잘못된 scheme이나 host를 전달하면 http callback을 만들 수 있습니다. Gateway와 Argo CD의 외부 URL 설정을 함께 확인합니다.

로그인은 되지만 아무것도 보이지 않는다

이 글의 기본 정책에서는 그룹이 없으면 아무것도 보이지 않는 것이 정상입니다.

bash
argocd account get-user-info

groups가 없다면 Keycloak mapper와 client scope를 확인합니다. 값이 /argocd-web인데 정책은 argocd-web이면 Full group path 설정 또는 정책을 일치시킵니다.

모든 프로젝트가 보인다

policy.default: role:readonly 또는 넓은 기존 정책이 남아 있을 가능성이 큽니다.

bash
kubectl -n argocd get configmap argocd-rbac-cm -o yaml

policy.csv뿐 아니라 policy.*.csv 키도 확인합니다. Argo CD는 이 추가 정책 파일을 합쳐 평가할 수 있습니다.

web/* 정책이 일치하지 않는다

Application의 spec.project를 확인합니다. Application in any namespace 기능을 사용한다면 객체 형식이 <project>/<app-namespace>/<app-name>으로 달라질 수 있으므로 현재 Argo CD 설정과 공식 RBAC 문서를 기준으로 패턴을 조정합니다.

OIDC 서버 TLS 검증이 실패한다

Keycloak 인증서의 SAN, 중간 인증서 체인, Argo CD Pod의 CA 신뢰를 확인합니다. 검증 생략 설정은 장애 원인을 숨기고 중간자 공격 가능성을 만듭니다. Argo CD가 제공하는 custom root CA 구성 경로를 사용합니다.

RBAC 변경이 예상대로 적용되지 않는다

CLI로 정책을 먼저 validate하고, argocd-server 로그에서 policy parse 오류를 찾습니다. 브라우저의 기존 토큰에는 이전 그룹이 남아 있을 수 있으므로 완전히 로그아웃하고 새 시크릿 창에서 다시 로그인합니다.

운영과 보안 설계

로컬 admin은 초기 구성 후 비상 계정으로 전환한다

SSO와 관리자 그룹을 검증한 뒤에는 내장 admin을 비상 접근용으로 관리하고 일상 업무에 사용하지 않습니다. SSO 장애가 발생했을 때 복구에 사용할 수 있도록 접근 절차, 자격증명 보관, 사용 감사, 정기 점검을 별도로 마련합니다. 복구 경로를 확보하더라도 공유 계정을 상시 사용하는 방식으로 운영하지 않습니다.

관리자 그룹을 토큰에 싣는 범위를 제한한다

argocd-platform-admin에 속한 사용자는 Argo CD 전체 관리자 권한을 갖습니다. 그룹에 사용자를 추가하는 것만으로 권한을 높일 수 있으므로, Keycloak 관리자 권한과 감사 로그를 엄격히 관리해야 합니다. 자동 동기화된 외부 그룹 이름이 다른 애플리케이션의 로컬 사용자 이름과 충돌하지 않도록 명명 규칙도 정합니다.

RBAC와 AppProject를 Git으로 관리한다

argocd-cm, argocd-rbac-cm, AppProject를 수동 편집하면 변경 이력과 리뷰가 사라집니다. 부트스트랩 이후에는 별도 플랫폼 GitOps 저장소에서 관리하고, 정책 검증 명령을 CI에 넣습니다. 단, 자신을 관리하는 Argo CD 설정을 잘못 배포했을 때 복구할 break-glass 절차를 문서화합니다.

저장소와 클러스터 자격증명을 팀 역할과 분리한다

팀이 Application을 sync할 수 있다고 저장소 자격증명과 클러스터 등록까지 관리할 필요는 없습니다. repositories, clusters, certificates, accounts 권한은 플랫폼 운영 역할로 분리합니다.

권한 변경의 효력 시간을 이해한다

그룹에서 사용자를 제거해도 이미 발급된 토큰과 애플리케이션 세션이 만료될 때까지 이전 클레임이 남을 수 있습니다. 고위험 역할은 토큰 수명을 짧게 하고, 긴급 회수 시 Keycloak 세션 종료와 Argo CD 세션 무효화가 실제로 동작하는지 훈련합니다.

요약

  • Keycloak은 사용자와 그룹을 관리하고 groups 클레임을 발급하며, Argo CD는 이 값을 자체 RBAC 주체로 사용합니다.
  • Argo CD의 PKCE 연동은 UI와 CLI SSO를 지원하면서 client secret 저장을 없앨 수 있습니다.
  • g는 Keycloak 그룹을 Argo CD 역할에 연결하고, p는 그 역할이 리소스에 수행할 행동을 정의합니다.
  • GitOps 팀의 기본 역할은 조회·로그·sync로 좁히고, delete·override·exec·저장소 관리는 별도 고위험 권한으로 분리합니다.
  • AppProject로 소스 저장소, 대상 Namespace, 허용 리소스를 제한해야 사용자 RBAC 밖의 배포 경계까지 완성됩니다.
  • 검증은 Keycloak 그룹 → 토큰 클레임 → Argo CD User Info → 정적 정책 검사 → 실제 Application Project 순서로 수행합니다.

다음 글에서는 권한이 있는 사용자가 운영할 Kubernetes 플랫폼을 어떻게 관측할지, 메트릭·로그·트레이스의 역할부터 정리합니다.

← 이전 글: Keycloak으로 이해하는 SSO: Realm, Client, OIDC와 SAML
→ 다음 글: Kubernetes 관측성 지도: 메트릭·로그·트레이스를 함께 읽는 법

공식 참고자료