RBAC 롤아웃 전략 계획하기

RBAC 롤아웃 전략 계획하기 (Plan your RBAC rollout strategy)

RBAC 롤아웃 전략은 RBAC 역할을 사용자와 팀에 할당하기 전에 구현 방식을 결정하는 데 도움을 줘요. 이 문서는 기본 역할과 고정 역할을 검토하고, 사용자·팀·인증 공급자 관점에서 권한 부여 방식을 설계하는 지침을 제공해요.

출처: Plan your RBAC rollout strategy

본문

Grafana EnterpriseGrafana Cloud에서 사용 가능.

롤아웃 전략은 다음 질문에 답하는 데 도움을 줘야 해요.

  • 사용자에게 기본 역할을 할당해야 할까, 아니면 고정 역할이나 커스텀 역할을 할당해야 할까?
  • 언제 커스텀 역할을 만들어야 할까?
  • 고정/커스텀 역할을 어떤 엔티티에 적용해야 할까? 사용자, 팀? 아니면 기본 역할 권한을 수정해야 할까?
  • 관리하기 쉬운 방식으로 권한을 어떻게 롤아웃할까?
  • 역할을 할당할 때 어떤 방식을 써야 할까? Grafana UI, provisioning, API?

기본 역할과 고정 역할 정의 검토

권한 롤아웃 전략을 결정하는 첫걸음으로 기본 역할과 고정 역할 정의를 숙지하는 걸 권장해요. 고정 역할을 사용자·팀에 할당하는 것 외에도 기본 역할 권한을 수정해 Viewer, Editor, Admin이 할 수 있는 일을 바꿀 수 있어요. 사용자와 팀이 많다면 사용할 고정 역할 목록을 만들어 두는 걸 권장해요. None 기본 역할(권한이 없는 역할)은 수정되거나 갱신될 수 없다는 점을 유의해요.

사용자와 팀 고려 사항

  • 사용자에게 역할 할당: 일회성 시나리오로 소수의 사용자만 특정 리소스 접근이 필요하거나 임시 접근을 부여할 때. 사용자가 많으면 확장 시 관리가 어려울 수 있어요. 예: IT 부서의 한 멤버가 Grafana Enterprise 라이선스를 관리하기 위해 fixed:licensing:readerfixed:licensing:writer 역할이 필요할 수 있어요.
  • 팀에 역할 할당: 팀 멤버 전원이 같은 접근 수준을 가져야 하는 조직 구조에 맞는 사용자 하위 집합이 있을 때. 예: 특정 엔지니어링 팀의 모든 멤버가 리포트를 관리하기 위해 fixed:reports:readerfixed:reports:writer 역할이 필요할 수 있어요.

팀에 추가 사용자를 할당하면 시스템이 자동으로 그 사용자에게 권한을 부여해요.

인증 공급자 고려 사항

현재 인증 공급자를 활용해 Grafana에서 사용자·팀 권한을 관리할 수 있어요. 사용자와 팀을 SAML·LDAP 그룹에 매핑하면 그 할당을 Grafana와 동기화할 수 있어요.

  1. SAML, LDAP, OAuth 역할을 Grafana 기본 역할(viewer, editor, admin)에 매핑해요.
  2. Grafana Enterprise 팀 동기화 기능으로 SAML, LDAP, OAuth 공급자의 팀을 Grafana에 동기화해요. 자세한 내용은 Team sync를 참고해요.
  3. Grafana 내부에서 사용자와 팀에 RBAC 권한을 할당해요.

기본 역할을 수정할지, 커스텀 역할을 만들지

  • 기본 역할 수정: Grafana가 정의한 Viewer/Editor/Admin의 역할이 우리 정의와 맞지 않을 때. 어떤 기본 역할에도 권한을 추가·제거할 수 있어요.

    기본 역할을 변경하면 Grafana 인스턴스의 모든 조직에 영향이 미쳐요. 예: viewer 기본 역할에 fixed:users:writer 권한을 추가하면 인스턴스의 어떤 조직의 모든 viewer가 그 조직에서 사용자를 만들 수 있어요. No Basic Role 권한은 수정할 수 없어요.

  • 커스텀 역할 생성: 고정 역할 정의가 권한 요구사항을 충족하지 못할 때. 예: fixed:dashboards:writer 역할은 대시보드 삭제를 허용해요. 삭제 없이 생성·갱신만 허용하려면 custom:dashboards:creator처럼 dashboards:delete 권한이 없는 커스텀 역할을 만들 수 있어요.

RBAC 역할 할당 방법

  • Grafana UI: 제한된 수의 RBAC 역할을 할당할 때. 역할 선택기(role picker)가 포함돼요.
  • Grafana HTTP API: 역할 할당을 자동화할 때.
  • Terraform: provisioning에 Terraform을 사용할 때.
  • Grafana provisioning: 역할 할당·제거·삭제에 견고한 접근 방식. 단일 YAML 파일에 여러 역할 할당·제거 항목을 넣을 수 있어요.

권한 시나리오

내부 viewer 직원은 Explore를 쓰게, 외부 계약직 viewer는 Explore 사용 금지

  1. Internal employees 이름의 팀을 만들어요.
  2. Internal employees 팀에 fixed:datasources:explorer 역할을 할당해요.
  3. 내부 직원을 팀에 추가하거나 Team Sync로 SAML, LDAP, OAuth 팀에서 매핑해요.
  4. 내부 직원과 계약직 모두에게 viewer 역할을 할당해요.

viewer, editor, admin 권한 제한

  1. 기본 역할과 연관된 권한 목록을 검토해요.
  2. 기본 역할 권한 변경.

한 팀의 멤버만 Alert 관리 허용

  1. Alert Managers 팀을 만들고 그 팀에 모든 관련 Alerting 고정 역할을 할당해요.
  2. 사용자를 팀에 추가해요.
  3. Viewer, Editor, Admin 기본 역할에서 alert. 접두사가 있는 모든 권한을 제거해요.

두 개 이상 지역의 사용자에게 대시보드 제공

  1. 지역마다 폴더를 만들어요(예: US 폴더, EU 폴더).
  2. 각 폴더에 대시보드를 추가해요.
  3. 폴더 권한으로 US 기반 사용자는 US 폴더의 Editor로, EU 기반 사용자는 EU 폴더의 Editor로 추가해요.

사용자에게 구체적인 역할 집합 할당

  1. 조직 역할에서 No Basic Role이 선택된 사용자를 만들어요.
  2. 요구사항에 맞는 고정 역할 집합을 사용자에게 할당해요.

특정 폴더의 알림에 접근하는 커스텀 역할 만들기

Grafana에서 알림 규칙을 보려면 사용자가 알림 규칙을 저장하는 폴더에 대한 읽기 권한, 폴더의 알림 읽기 권한, 규칙이 사용하는 모든 데이터 소스에 대한 쿼리 권한이 있어야 해요. 이 예제의 API 명령은 다음을 기준으로 해요.

  • ID가 92Test-Folder
  • UID _oAfGYUnkDS1, UID YYcBGYUnkDS2
  • Test-Folder에 저장되고 두 데이터 소스를 쿼리하는 알림 규칙

다음 요청은 알림 규칙 접근 권한을 포함한 커스텀 역할을 만들어요.

curl --location --request POST '<grafana_url>/api/access-control/roles/' \
--header 'Authorization: Bearer glsa_i...2697' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": 1,
    "name": "custom:alerts.reader.in.folder.123",
    "displayName": "Read-only access to alerts in folder Test-Folder",
    "description": "Let user query DS1 and DS2, and read alerts in folder Test-Folders",
    "group":"Custom",
    "global": false,
    "permissions": [
        {
            "action": "folders:read",
            "scope": "folders:uid:YEcBGYU22"
        },
        {
            "action": "alert.rules:read",
            "scope": "folders:uid:YEcBGYU22"
        },
        {
            "action": "datasources:query",
            "scope": "datasources:uid:_oAfGYUnk"
        },
        {
            "action": "datasources:query",
            "scope": "datasources:uid:YYcBGYUnk"
        }
    ]
}'

Editor가 커스텀 역할을 만들 수 있게 하기

기본적으로 Grafana Server Admin만 커스텀 역할을 만들고 관리할 수 있어요. Editor도 하게 하려면 Editor 기본 역할 권한을 갱신해야 해요. 두 가지 방법이 있어요.

  • provisioning 또는 RBAC HTTP API를 사용해 basic:editor 역할에 다음 권한을 추가:
action scope
roles:read roles:*
roles:write permissions:type:delegate
roles:delete permissions:type:delegate

예를 들어 역할을 가져와 jq로 수정하고 갱신하는 작은 bash 스크립트:

# 역할을 가져와 원하는 권한을 추가하고 version 증가
curl -H 'Authorization: Bearer glsa_i...2697' \
  -X GET '<grafana_url>/api/access-control/roles/basic_editor' | \
  jq 'del(.created)| del(.updated) | del(.permissions[].created) | del(.permissions[].updated) | .version += 1' | \
  jq '.permissions += [{"action": "roles:read", "scope": "roles:*"}, {"action": "roles:write", "scope": "permissions:type:delegate"}, {"action": "roles:delete", "scope": "permissions:type:delegate"}]' > /tmp/basic_editor.json

# 역할 갱신
curl -H 'Authorization: Bearer glsa_i...2697' -H 'Content-Type: application/json' \
  -X PUT-d @/tmp/basic_editor.json '<grafana_url>/api/access-control/roles/basic_editor'
  • 또는 provisioning 파일의 role > from 목록을 사용해 basic:editor 역할에 fixed:roles:writer 권한 추가:
apiVersion: 2

roles:
  - name: 'basic:editor'
    global: true
    version: 3
    from:
      - name: 'basic:editor'
        global: true
      - name: 'fixed:roles:writer'
        global: true

참고: 역할을 수정할 수 있는 사용자나 서비스 계정은 부여받은 권한으로만 역할을 생성·갱신·삭제할 수 있어요. 예: Editor 역할의 사용자는 자신이 가진 권한(또는 그 부분집합)으로만 역할을 만들고 관리할 수 있어요.

Viewer가 리포트를 만들 수 있게 하기

Viewer가 리포트를 만들게 하려면 Viewer 기본 역할 권한을 갱신해야 해요. 두 가지 방법:

  • provisioning 또는 RBAC HTTP APIbasic:viewer 역할에 다음 권한을 추가:
Action Scope
reports:create n/a
reports:write reports:*
reports:id:*
reports:read reports:*
reports:send reports:*
# 역할을 가져와 원하는 권한을 추가하고 version 증가
curl -H 'Authorization: Bearer glsa_i...2697' \
  -X GET '<grafana_url>/api/access-control/roles/basic_viewer' | \
  jq 'del(.created)| del(.updated) | del(.permissions[].created) | del(.permissions[].updated) | .version += 1' | \
  jq '.permissions += [{"action": "reports:create"}, {"action": "reports:read", "scope": "reports:*"}, {"action": "reports:write", "scope": "reports:*"}, {"action": "reports:send", "scope": "reports:*"}]' > /tmp/basic_viewer.json

# 역할 갱신
curl -H 'Authorization: Bearer glsa_i...2697' -H 'Content-Type: application/json' \
  -X PUT-d @/tmp/basic_viewer.json '<grafana_url>/api/access-control/roles/basic_viewer'
  • 또는 provisioning 파일의 role > from 목록을 사용해 basic:viewer 역할에 fixed:reports:writer 권한 추가:
apiVersion: 2

roles:
  - name: 'basic:viewer'
    global: true
    version: 3
    from:
      - name: 'basic:viewer'
        global: true
      - name: 'fixed:reports:writer'
        global: true

참고: fixed:reports:writer 역할은 리포트 생성보다 더 많은 권한을 할당해요. 자세한 내용은 Fixed role definitions를 참고해요.

Grafana Admin이 사용자를 생성·초대하지 못하게 하기

Grafana Admin이 사용자를 만들고 조직에 초대하지 못하게 하려면 기본 역할 권한을 갱신해야 해요. 제거할 권한:

Action Scope
users:create
org.users:add users:*
# 역할을 가져와 원치 않는 권한 제거 및 version 증가
curl -H 'Authorization: Bearer glsa_i...2697' \
  -X GET '<grafana_url>/api/access-control/roles/basic_grafana_admin' | \
  jq 'del(.created)| del(.updated) | del(.permissions[].created) | del(.permissions[].updated) | .version += 1' | \
  jq 'del(.permissions[] | select (.action == "users:create")) | del(.permissions[] | select (.action == "org.users:add" and .scope == "users:*"))' > /tmp/basic_grafana_admin.json

# 역할 갱신
curl -H 'Authorization: Bearer glsa_i...2697' -H 'Content-Type: application/json' \
  -X PUT-d @/tmp/basic_grafana_admin.json '<grafana_url>/api/access-control/roles/basic_grafana_admin'
  • 또는 provisioning 파일의 role > from 목록과 permission > state 옵션을 사용:
apiVersion: 2

roles:
  - name: 'basic:grafana_admin'
    global: true
    version: 3
    from:
      - name: 'basic:grafana_admin'
        global: true
    permissions:
      - action: 'users:create'
        state: 'absent'
      - action: 'org.users:add'
        scope: 'users:*'
        state: 'absent'

Viewer가 App Plugin에 접근하지 못하게 하기

기본적으로 Viewer, Editor, Admin은 조직 역할이 허용하는 모든 App Plugin에 접근할 수 있어요. Viewer가 특정 App plugin에 접근하지 못하게 하려면 기본 역할 권한을 갱신해야 해요. 예제에서 세 개의 App plugin이 설치·활성화돼 있어요.

Name ID Required Org role
On Call grafana-oncall-app Viewer
Kentik Connect Pro kentik-connect-app Viewer
Enterprise logs grafana-enterprise-logs-app Admin

기본적으로 Viewer는 On Call와 Kentik Connect Pro App plugin을 모두 볼 수 있어요. On Call App plugin에 대한 접근을 철회하려면:

  1. 모든 애플리케이션 플러그인에 대한 접근 권한 제거:
Action Scope
plugins.app:access plugins:*
  1. Kentik Connect Pro App plugin에만 접근 권한 부여:
Action Scope
plugins.app:access plugins:id:kentik-connect-app
# 역할을 가져와 원치 않는 권한 제거, 새 권한 추가 및 version 증가
curl -H 'Authorization: Bearer glsa_i...2697' \
  -X GET '<grafana_url>/api/access-control/roles/basic_viewer' | \
  jq 'del(.created)| del(.updated) | del(.permissions[].created) | del(.permissions[].updated) | .version += 1' | \
  jq 'del(.permissions[] | select (.action == "plugins.app:access" and .scope == "plugins:*"))' | \
  jq '.permissions += [{"action": "plugins.app:access", "scope": "plugins:id:kentik-connect-app"}]' > /tmp/basic_viewer.json

# 역할 갱신
curl -H 'Authorization: Bearer glsa_i...2697' -H 'Content-Type: application/json' \
  -X PUT -d @/tmp/basic_viewer.json '<grafana_url>/api/access-control/roles/basic_viewer'

이 요청에 사용되는 토큰은 service account token이에요.

  • 또는 provisioning 파일 사용:
---
apiVersion: 2

roles:
  - name: 'basic:viewer'
    version: 8
    global: true
    from:
      - name: 'basic:viewer'
        global: true
    permissions:
      - action: 'plugins.app:access'
        scope: 'plugins:*'
        state: 'absent'
      - action: 'plugins.app:access'
        scope: 'plugins:id:kentik-connect-app'
        state: 'present'

팀을 통한 사용자 권한 관리

사용자가 속한 팀으로 접근 권한을 부여하고 싶다면 사용자 역할을 No Basic Role로 설정하고 팀 할당이 대신 역할을 부여하도록 하는 걸 권장해요.

  1. 다음 구성 설정이 활성화되어 있는지 확인해요.
[users]
# 새 사용자를 기본 조직(id 1)에 자동 할당하려면 true로 설정
auto_assign_org = true

# 위 auto_assign_org가 true일 때 새 사용자를 제공된 조직에 자동 추가하는 값
auto_assign_org_id = <org_id>

# 새 사용자에게 자동 할당될 기본 역할 (auto_assign_org가 true일 때)
auto_assign_org_role = None
  1. Grafana 인스턴스를 재시작해요.
  2. 원하는 이름의 팀을 만들어요.
  3. 팀에 고정 역할을 할당해요.
  4. 사용자를 팀에 추가해요.

사용자는 기본 조직에 자동으로 추가되지만 팀에 할당되기 전까지는 권한이 없어요.

서비스 계정 범위 축소

Service Account는 M2M 통신을 촉진하는 효율적인 방법이에요. 다만 적절히 범위(scope)를 지정하지 않으면 보안 위협이 될 수 있어요. None 기본 역할로 Service Account를 만들고 필요한 권한을 할당하는 것으로 시작할 수 있어요.

  1. Service Accounts를 참고해 새 Service Account를 추가해요.
  2. 기본 역할을 None으로 설정해요.
  3. Service Account에 필요한 고정 역할을 설정해요.

이렇게 하면 Service Account의 필요 권한이 줄어들어 침해 위험을 최소화해요.

더 알아보기 (Learn more)