InfoGrab Docs

할당 가능한 권한

요약

할당 가능한 권한은 하나 이상의 원시 권한을 사용자 대면 권한 그룹으로 묶습니다. config/authz/permission_groups/assignable_permissions/<category>/<resource>/<action>.yml에 새 YAML 파일을 수동으로 만듭니다:

할당 가능한 권한#

할당 가능한 권한은 하나 이상의 원시 권한을 사용자 대면 권한 그룹으로 묶습니다. 이를 통해 사용자에게 제공되는 세분화 수준을 조정할 수 있어, 제품 그룹이 권한을 세밀하게(예: 이슈 읽기와 스니펫 읽기 권한을 별도로) 또는 더 광범위하게(예: 모든 읽기 작업 항목 권한을 함께) 그룹화할지 결정할 수 있습니다. 이를 통해 코드 수준에서 세밀한 제어를 유지하면서 UI에서 사용자 친화적인 경험을 제공합니다.

할당 가능한 권한 파일 만들기#

config/authz/permission_groups/assignable_permissions/<category>/<resource>/<action>.yml에 새 YAML 파일을 수동으로 만듭니다:

---
name: run_job
description: Grants the ability to run jobs
permissions:
  - play_job
  - retry_job
boundaries:
  - group
  - project

할당 가능한 권한 파일 필드#

필드 설명
name 할당 가능한 권한의 고유 식별자
description 할당 가능한 권한이 부여하는 것에 대한 사람이 읽을 수 있는 설명
permissions 이 할당 가능한 권한에 포함된 원시 권한 배열 (원시 권한 정의 파일로 이미 존재해야 함)
boundaries 할당 가능한 권한이 적용되는 조직 수준 목록
deprecated 선택 사항. true로 설정하면 UI에서 할당 가능한 권한을 숨겨 사용자가 새 토큰 생성 시 더 이상 선택할 수 없게 됩니다. 이미 이 권한을 가진 기존 토큰은 계속 작동합니다. 이름 변경 마이그레이션 중이나 권한을 단계적으로 제거할 때 사용합니다.

디렉터리 구조 이해#

디렉터리 구조는 <category>/<resource>/<action>.yml의 세 수준을 사용합니다.

메타데이터 파일이 필요한 경우#

파일 필요한 경우 목적
카테고리 .metadata.yml 선택 사항 폴더 이름 표시 재정의 (예: ci_cd → "Ci Cd" 대신 "CI/CD")
리소스 .metadata.yml 선택 사항 생성된 리소스 설명 또는 대문자화된 리소스 이름 재정의
Note

<category>/<resource>/<action>.yml에 있는 할당 가능한 권한 YAML 파일은 항상 필수이며 메타데이터 파일이 아닙니다—권한 번들을 정의하는 주요 구성 파일입니다.

카테고리 수준: <category> 하위 폴더는 할당 가능한 권한이 그룹화되는 UI에 표시되는 카테고리 이름을 나타냅니다. 폴더 이름은 표시 시 대문자화됩니다(예: project_management는 "Project Management"가 됨). 이 카테고리 이름은 권한 선택 UI에 표시되어 사용자가 기능 영역별로 권한을 구성하고 찾는 데 도움을 줍니다.

대문자화가 잘못된 표시 이름을 생성하는 경우에만 카테고리 폴더에 .metadata.yml 파일을 만듭니다. 예를 들어 대문자화가 잘 되지 않는 약어나 축약어:

---
name: "CI/CD"

카테고리 수준 메타데이터 예시:

  • 폴더: project_management → 메타데이터 없음: "Project Management"로 표시
  • 폴더: ci_cd → 메타데이터 없음: "Ci Cd"로 표시 (잘못됨)
  • 폴더: ci_cd.metadata.yml 재정의 포함: "CI/CD"로 표시 (올바름)

리소스 수준: config/authz/permission_groups/assignable_permissions/<category>/<resource>/.metadata.yml에 선택적으로 .metadata.yml 파일을 만들어 기본값을 재정의합니다:

---
description: "Grants the ability to <actions> SSH keys."
name: "SSH Key"

기본적으로 리소스 이름은 디렉터리 이름(대문자화)에서 파생되고, 설명은 리소스의 액션에서 생성됩니다(예: "Grants the ability to assign, create, and read runners.").

필드:

  • description (선택 사항) - 생성된 리소스 설명을 재정의합니다. 런타임에 리소스의 YAML 파일에서 알파벳순으로 정렬된 액션 목록으로 교체되는 <actions> 보간을 포함해야 합니다. <actions>를 사용하여 명사를 사용자 정의하면서 액션 목록을 자동으로 동기화 상태로 유지합니다(예: "Grants the ability to <actions> CI variables.").
  • name (선택 사항) - 표시를 위해 대문자화된 리소스 이름을 재정의합니다. 대문자화가 올바르게 작동하지 않는 약어나 특수 형식에 사용합니다(예: 자동 대문자화된 이름 대신 name: "SSH Key").

UI 예시:

다음 스크린샷은 카테고리 및 리소스 메타데이터가 권한 선택 UI에 표시되는 방식을 보여줍니다:

리소스 메타데이터를 보여주는 권한 선택 UI

이 예시에서:

  • CI/CD - 폴더 이름에서 가져온 카테고리 이름으로, 카테고리 .metadata.yml로 재정의할 수 있습니다.
  • CI Config - 폴더 이름에서 가져온 리소스 이름으로, 리소스 .metadata.yml로 재정의할 수 있습니다.
  • 아래 설명은 리소스 설명으로, 리소스 .metadata.yml 파일에서 재정의하거나 리소스의 액션에서 생성됩니다.

리소스 .metadata.yml을 만들어야 하는 경우:

  • 리소스 이름에 올바르게 대문자화되지 않는 약어나 브랜드 이름이 포함된 경우 (예: ssh_key → "Ssh Key" 대신 "SSH Key")
  • 생성된 설명에 사용자 정의 명사가 필요한 경우 (예: "variables" 대신 "CI variables", 또는 "codes" 대신 "code")
  • 리소스에 산문으로 표현하기 어색한 특이한 액션 이름이 있는 경우 (예: renew_secret)
  • 디렉터리 이름의 복수형이 어색한 경우 (예: "code" → "codes", "metadata" → "metadatas")

대부분의 리소스처럼 디렉터리 이름이 올바르게 대문자화되고 복수형이 되는 경우에는 메타데이터 파일이 필요하지 않습니다.

경계 결정#

boundaries 필드는 이 할당 가능한 권한을 지원하는 조직 수준을 지정합니다. 번들된 원시 권한을 적용할 수 있는 위치를 기반으로 선택합니다. 최소 권한 원칙을 사용하여 권한이 실제로 적용되는 경계만 포함합니다.

경계 유형:

  • project - 프로젝트 및 프로젝트 수준 리소스에 적용 가능한 권한 (이슈 관리, 파이프라인 생성, 리포지터리 설정 업데이트)
    • /projects/:id/...와 같은 프로젝트 엔드포인트에서 원시 권한이 작동하는 경우 포함
  • group - 그룹 및 그룹 수준 리소스에 적용 가능한 권한 (그룹 멤버 관리, 그룹 설정, 그룹 소유 프로젝트)
    • /groups/:id/...와 같은 그룹 엔드포인트에서 원시 권한이 작동하는 경우 포함
  • user - 사용자 수준 리소스에 적용 가능한 권한 (개인 프로필, 개인 설정, 사용자 소유 리소스)
    • /users/:id/...와 같은 사용자 엔드포인트나 개인 네임스페이스 작업에서 원시 권한이 작동하는 경우 포함
  • instance - GitLab 인스턴스 수준에서 적용 가능한 권한 (스니펫 읽기, 감사 로그 보기, 시스템 설정 관리와 같은 작업)
    • 드물게 사용 — 일반적으로 관리자 대면 권한에만 사용

경계 선택: API 파일의 엔드포인트 라우트 또는 보호 중인 GraphQL 유형과 뮤테이션을 검토합니다. 엔드포인트가 /projects/:id/...와 같은 패턴을 따르면 project를 포함합니다. 엔드포인트가 /groups/:id/...를 따르면 group을 포함합니다. GraphQL의 경우 지시자에 선언된 boundary_type을 확인합니다. 엔드포인트가 실제로 지원하는 경계만 포함합니다.

중요한 제약 사항#

  • 할당 가능한 권한에 포함된 각 원시 권한은 이미 존재해야 합니다 (원시 권한 정의 파일로 생성됨)
  • 할당 가능한 권한에 할당된 원시 권한만 토큰 인증에 사용할 수 있습니다
  • 관련 할당 가능한 권한 전체에 걸쳐 일관된 이름 지정을 사용합니다

할당 가능한 권한 유효성 검사#

할당 가능한 권한 유효성 검사는 git push 실행 시 Lefthook의 pre-push 훅에 의해 자동으로 실행됩니다. 수동으로도 실행할 수 있습니다:

bundle exec rake gitlab:permissions:validate

유효성 검사 작업은 여러 제약 사항을 적용합니다:

  • 할당 가능한 권한은 정확히 config/authz/permission_groups/assignable_permissions/<category>/<resource>/<action>.yml에 있어야 합니다.
  • 기본 경로와 최종 파일 이름 사이에 추가 디렉터리는 허용되지 않습니다.
  • 각 REST API 라우트의 boundary_type 및 각 GraphQL 지시자의 boundary_type은 할당 가능한 권한의 boundaries 필드에 있는 하나 이상의 경계와 일치해야 합니다(예: 라우트나 지시자가 boundary_type: :project를 선언하는 경우, 할당 가능한 권한의 경계에 project가 포함되어야 함).

할당 가능한 권한 유지 관리#

할당 가능한 권한은 시간이 지남에 따라 변경이 필요할 수 있습니다. 이 섹션에서는 일반적인 변경 시나리오와 그 영향을 다룹니다.

토큰이 권한을 해석하는 방법#

변경하기 전에 토큰이 권한을 저장하고 해석하는 방법을 이해하는 것이 중요합니다.

토큰은 데이터베이스에 할당 가능한 권한 이름(원시 권한이 아님)을 저장합니다. 요청 시 시스템은 현재 YAML 정의를 사용하여 이 이름을 동적으로 원시 권한으로 해석합니다. 이는 YAML 파일의 변경 사항이 마이그레이션 없이 모든 기존 토큰에 즉시 적용됨을 의미합니다.

이는 app/models/authz/granular_scope.rb에서 구현됩니다:

scope
  .pluck(Arel.sql('DISTINCT jsonb_array_elements_text(permissions)'))
  .flat_map { |p| ::Authz::PermissionGroups::Assignable.get(p)&.permissions }
  .compact.map(&:to_sym)

Assignable.get(p)가 현재 YAML 정의에서 저장된 이름을 찾을 수 없으면 nil을 반환하고 권한이 조용히 무시됩니다. 이것이 할당 가능한 권한이 이름 변경되거나 제거될 때 오류가 발생하는 근본 원인입니다.

할당 가능한 권한 추가#

새 할당 가능한 권한 추가는 안전합니다. 새 YAML 파일은 자동으로 검색되어 세분화된 스코프를 만들 때 UI에서 표시됩니다. 기존 토큰은 영향을 받지 않습니다.

Note

할당 가능한 권한에 포함된 원시 권한 중 어느 것도 API 인증에 사용되지 않으면, 토큰을 만드는 사용자는 해당 권한을 추가해도 효과를 볼 수 없습니다. 할당 가능한 권한이 API 인증 외부에서도 사용될 수 있으므로(예: Repository > Code > Download/Push 권한은 Git 작업에 사용됨) 이에 대한 정적 유효성 검사는 없습니다.

할당 가능한 권한 제거#

할당 가능한 권한 제거는 중단 변경입니다. 해당 할당 가능한 권한으로 만든 토큰은 Assignable.get(p)가 제거된 이름에 대해 nil을 반환하므로 포함된 원시 권한이 부여한 모든 API 접근을 잃습니다.

기본 API 기능도 제거되는 경우에만 할당 가능한 권한을 제거합니다.

할당 가능한 권한 이름 변경#

할당 가능한 권한 이름 변경은 중단 변경입니다. 이전 이름으로 만든 토큰은 저장된 이름이 더 이상 YAML 정의와 일치하지 않으므로 접근을 잃습니다.

이를 위해 3단계 프로세스가 필요합니다:

  1. 다음을 수행하는 머지 리퀘스트를 만듭니다:
    • 새 할당 가능한 권한 YAML 파일 추가.
    • 데이터베이스의 저장된 이름을 업데이트하는 rename_granular_scope_permission 배포 후 배치 백그라운드 마이그레이션 추가 (아래 참조).
    • 이전 할당 가능한 권한을 더 이상 사용되지 않음으로 표시.
  2. 이후 마일스톤에서 배치 백그라운드 마이그레이션 최종화하여 업그레이드 중 남은 행을 동기적으로 마이그레이션합니다.
  3. 마이그레이션이 최종화된 후 더 이상 사용되지 않는 권한을 제거하는 후속 머지 리퀘스트를 만듭니다.
이름 변경 마이그레이션 만들기

설명적인 이름으로 마이그레이션 스캐폴드를 생성합니다:

bundle exec rails g batched_background_migration rename_granular_scope_permission_<description> \
  --table-name=granular_scopes --feature-category=permissions

생성된 배포 후 마이그레이션 내용을 다음으로 교체합니다:

# frozen_string_literal: true

class QueueRenameGranularScopePermissionDescription < Gitlab::Database::Migration[2.3]
  milestone '<milestone>'
  restrict_gitlab_migration gitlab_schema: :gitlab_main_org

  MIGRATION = 'RenameGranularScopePermissionDescription'

  def up
    queue_batched_background_migration(
      MIGRATION,
      :granular_scopes,
      :id
    )
  end

  def down
    delete_batched_background_migration(MIGRATION, :granular_scopes, :id, [])
  end
end

생성된 백그라운드 마이그레이션 내용을 다음으로 교체합니다:

# frozen_string_literal: true

module Gitlab
  module BackgroundMigration
    class RenameGranularScopePermissionDescription < BatchedMigrationJob
      include Gitlab::Database::MigrationHelpers::GranularScopePermissions

      RENAMES = {
        'old_name_one' => 'new_name_one',
        'old_name_two' => %w[new_name_two_a new_name_two_b]
      }.freeze

      feature_category :permissions
    end
  end
end

RENAMES 해시, 클래스 이름, milestone을 이름 변경 및 대상 릴리스에 맞게 업데이트합니다. RENAMES의 값은 문자열(단순 이름 변경) 또는 배열(하나의 권한을 여러 개로 분할)이 될 수 있습니다. 단일 이름 변경에는 하나의 항목을 사용하거나, 동일한 배치 처리에서 여러 이름 변경을 처리하려면 여러 항목을 사용합니다.

할당 가능한 권한에 원시 권한 추가#

기존 할당 가능한 권한에 원시 권한을 추가하면 해당 할당 가능한 권한으로 이전에 만든 토큰이 증가된 접근 권한을 얻게 됩니다.

해석이 동적이므로 새 원시 권한이 즉시 적용됩니다. 이것이 최소 권한 원칙을 위반하는 것처럼 보일 수 있지만, 각 원시 권한이 하나의 할당 가능한 권한에만 속할 수 있다는 유효성 검사로 인해 새 기능은 다른 권한을 통해 접근할 수 없었을 것입니다. 사용자는 할당 가능한 권한이 동일한 리소스에 대한 새 기능을 포함할 것으로 기대할 것입니다.

새 API 엔드포인트에 대한 지원을 추가할 때만 원시 권한을 추가합니다. 할당 가능한 권한의 YAML 파일에서 permissions 배열에 원시 권한을 추가합니다.

할당 가능한 권한에서 원시 권한 제거#

할당 가능한 권한에서 원시 권한 제거는 중단 변경입니다. 해당 할당 가능한 권한을 가진 토큰은 제거된 원시 권한이 부여한 접근을 즉시 잃습니다.

이를 rename_granular_scope_permission 마이그레이션을 사용하여 이전 할당 가능한 권한을 이전 권한(제거된 원시 권한 제외)과 이동된 원시 권한을 포함하는 새 할당 가능한 권한의 조합으로 교체함으로써 완화할 수 있습니다.

Note

이 접근 방식은 새 할당 가능한 권한이 이동 중인 권한 외에 추가 원시 권한을 포함하는 경우 접근 증가로 이어질 수 있습니다.

엔드포인트 또는 지시자의 경계 유형 변경#

REST API route_setting 또는 GraphQL authorize_granular_token 지시자의 boundary_type 변경은 기존 토큰에 대한 중단 변경이 될 수 있습니다.

할당 가능한 권한의 boundaries 필드는 원시 권한의 엔드포인트와 지시자가 선언한 모든 boundary_type 값의 합집합을 포함해야 합니다. 할당 가능한 권한 경계를 직접 변경하지 않습니다—엔드포인트가 boundary_type을 추가하거나 변경하거나, 원시 권한이 할당 가능한 권한에 추가되거나 제거됨에 따라 변경됩니다. Lefthook pre-push 유효성 검사가 불일치를 잡아냅니다.

토큰은 세분화된 스코프를 경계(네임스페이스)와 할당 가능한 권한의 조합으로 저장합니다. 엔드포인트의 boundary_type이 변경되면 인증 검사는 새 경계에 대해 토큰의 스코프를 평가합니다. 토큰이 이전 경계에 대한 스코프로 만들어진 경우 더 이상 일치하지 않을 수 있습니다.

projectgroup 간 변경은 안전합니다. 프로젝트는 그룹에 속하므로 그룹 경계 세분화된 스코프를 가진 토큰은 해당 그룹 내의 프로젝트도 포함하고, 프로젝트 경계 스코프는 그룹 엔드포인트의 영향을 받지 않습니다.

user 또는 instance로 또는 이들 사이의 변경(예: project에서 instance로)은 중단 변경입니다. 해당 권한에 대한 프로젝트 경계 세분화된 스코프로 만들어진 토큰은 더 이상 접근 권한이 없습니다. 토큰 보유자는 새 경계에서 새 스코프를 만들어야 합니다.

API 인증에 사용되는 원시 권한 이름 변경#

원시 권한 이름 변경은 UI나 기존 토큰에 영향을 미치지 않습니다. 토큰은 할당 가능한 권한 이름(원시 권한 이름이 아님)을 저장하므로 원시 권한 이름 변경 시 YAML 파일만 업데이트하면 됩니다:

  • 원시 권한 정의 파일 (config/authz/permissions/<resource>/<action>.yml)
  • 이를 참조하는 모든 할당 가능한 권한 YAML 파일

데이터베이스 마이그레이션이 필요하지 않습니다.

할당 가능한 권한

원문 보기
요약

할당 가능한 권한은 하나 이상의 원시 권한을 사용자 대면 권한 그룹으로 묶습니다. config/authz/permission_groups/assignable_permissions/&#x3C;category>/&#x3C;resource>/&#x3C;action>.yml에 새 YAML 파일을 수동으로 만듭니다:

할당 가능한 권한#

할당 가능한 권한은 하나 이상의 원시 권한을 사용자 대면 권한 그룹으로 묶습니다. 이를 통해 사용자에게 제공되는 세분화 수준을 조정할 수 있어, 제품 그룹이 권한을 세밀하게(예: 이슈 읽기와 스니펫 읽기 권한을 별도로) 또는 더 광범위하게(예: 모든 읽기 작업 항목 권한을 함께) 그룹화할지 결정할 수 있습니다. 이를 통해 코드 수준에서 세밀한 제어를 유지하면서 UI에서 사용자 친화적인 경험을 제공합니다.

할당 가능한 권한 파일 만들기#

config/authz/permission_groups/assignable_permissions/<category>/<resource>/<action>.yml에 새 YAML 파일을 수동으로 만듭니다:

---
name: run_job
description: Grants the ability to run jobs
permissions:
  - play_job
  - retry_job
boundaries:
  - group
  - project

할당 가능한 권한 파일 필드#

필드 설명
name 할당 가능한 권한의 고유 식별자
description 할당 가능한 권한이 부여하는 것에 대한 사람이 읽을 수 있는 설명
permissions 이 할당 가능한 권한에 포함된 원시 권한 배열 (원시 권한 정의 파일로 이미 존재해야 함)
boundaries 할당 가능한 권한이 적용되는 조직 수준 목록
deprecated 선택 사항. true로 설정하면 UI에서 할당 가능한 권한을 숨겨 사용자가 새 토큰 생성 시 더 이상 선택할 수 없게 됩니다. 이미 이 권한을 가진 기존 토큰은 계속 작동합니다. 이름 변경 마이그레이션 중이나 권한을 단계적으로 제거할 때 사용합니다.

디렉터리 구조 이해#

디렉터리 구조는 <category>/<resource>/<action>.yml의 세 수준을 사용합니다.

메타데이터 파일이 필요한 경우#

파일 필요한 경우 목적
카테고리 .metadata.yml 선택 사항 폴더 이름 표시 재정의 (예: ci_cd → "Ci Cd" 대신 "CI/CD")
리소스 .metadata.yml 선택 사항 생성된 리소스 설명 또는 대문자화된 리소스 이름 재정의
Note

<category>/<resource>/<action>.yml에 있는 할당 가능한 권한 YAML 파일은 항상 필수이며 메타데이터 파일이 아닙니다—권한 번들을 정의하는 주요 구성 파일입니다.

카테고리 수준: <category> 하위 폴더는 할당 가능한 권한이 그룹화되는 UI에 표시되는 카테고리 이름을 나타냅니다. 폴더 이름은 표시 시 대문자화됩니다(예: project_management는 "Project Management"가 됨). 이 카테고리 이름은 권한 선택 UI에 표시되어 사용자가 기능 영역별로 권한을 구성하고 찾는 데 도움을 줍니다.

대문자화가 잘못된 표시 이름을 생성하는 경우에만 카테고리 폴더에 .metadata.yml 파일을 만듭니다. 예를 들어 대문자화가 잘 되지 않는 약어나 축약어:

---
name: "CI/CD"

카테고리 수준 메타데이터 예시:

  • 폴더: project_management → 메타데이터 없음: "Project Management"로 표시
  • 폴더: ci_cd → 메타데이터 없음: "Ci Cd"로 표시 (잘못됨)
  • 폴더: ci_cd.metadata.yml 재정의 포함: "CI/CD"로 표시 (올바름)

리소스 수준: config/authz/permission_groups/assignable_permissions/<category>/<resource>/.metadata.yml에 선택적으로 .metadata.yml 파일을 만들어 기본값을 재정의합니다:

---
description: "Grants the ability to <actions> SSH keys."
name: "SSH Key"

기본적으로 리소스 이름은 디렉터리 이름(대문자화)에서 파생되고, 설명은 리소스의 액션에서 생성됩니다(예: "Grants the ability to assign, create, and read runners.").

필드:

  • description (선택 사항) - 생성된 리소스 설명을 재정의합니다. 런타임에 리소스의 YAML 파일에서 알파벳순으로 정렬된 액션 목록으로 교체되는 <actions> 보간을 포함해야 합니다. <actions>를 사용하여 명사를 사용자 정의하면서 액션 목록을 자동으로 동기화 상태로 유지합니다(예: "Grants the ability to <actions> CI variables.").
  • name (선택 사항) - 표시를 위해 대문자화된 리소스 이름을 재정의합니다. 대문자화가 올바르게 작동하지 않는 약어나 특수 형식에 사용합니다(예: 자동 대문자화된 이름 대신 name: "SSH Key").

UI 예시:

다음 스크린샷은 카테고리 및 리소스 메타데이터가 권한 선택 UI에 표시되는 방식을 보여줍니다:

리소스 메타데이터를 보여주는 권한 선택 UI

이 예시에서:

  • CI/CD - 폴더 이름에서 가져온 카테고리 이름으로, 카테고리 .metadata.yml로 재정의할 수 있습니다.
  • CI Config - 폴더 이름에서 가져온 리소스 이름으로, 리소스 .metadata.yml로 재정의할 수 있습니다.
  • 아래 설명은 리소스 설명으로, 리소스 .metadata.yml 파일에서 재정의하거나 리소스의 액션에서 생성됩니다.

리소스 .metadata.yml을 만들어야 하는 경우:

  • 리소스 이름에 올바르게 대문자화되지 않는 약어나 브랜드 이름이 포함된 경우 (예: ssh_key → "Ssh Key" 대신 "SSH Key")
  • 생성된 설명에 사용자 정의 명사가 필요한 경우 (예: "variables" 대신 "CI variables", 또는 "codes" 대신 "code")
  • 리소스에 산문으로 표현하기 어색한 특이한 액션 이름이 있는 경우 (예: renew_secret)
  • 디렉터리 이름의 복수형이 어색한 경우 (예: "code" → "codes", "metadata" → "metadatas")

대부분의 리소스처럼 디렉터리 이름이 올바르게 대문자화되고 복수형이 되는 경우에는 메타데이터 파일이 필요하지 않습니다.

경계 결정#

boundaries 필드는 이 할당 가능한 권한을 지원하는 조직 수준을 지정합니다. 번들된 원시 권한을 적용할 수 있는 위치를 기반으로 선택합니다. 최소 권한 원칙을 사용하여 권한이 실제로 적용되는 경계만 포함합니다.

경계 유형:

  • project - 프로젝트 및 프로젝트 수준 리소스에 적용 가능한 권한 (이슈 관리, 파이프라인 생성, 리포지터리 설정 업데이트)
    • /projects/:id/...와 같은 프로젝트 엔드포인트에서 원시 권한이 작동하는 경우 포함
  • group - 그룹 및 그룹 수준 리소스에 적용 가능한 권한 (그룹 멤버 관리, 그룹 설정, 그룹 소유 프로젝트)
    • /groups/:id/...와 같은 그룹 엔드포인트에서 원시 권한이 작동하는 경우 포함
  • user - 사용자 수준 리소스에 적용 가능한 권한 (개인 프로필, 개인 설정, 사용자 소유 리소스)
    • /users/:id/...와 같은 사용자 엔드포인트나 개인 네임스페이스 작업에서 원시 권한이 작동하는 경우 포함
  • instance - GitLab 인스턴스 수준에서 적용 가능한 권한 (스니펫 읽기, 감사 로그 보기, 시스템 설정 관리와 같은 작업)
    • 드물게 사용 — 일반적으로 관리자 대면 권한에만 사용

경계 선택: API 파일의 엔드포인트 라우트 또는 보호 중인 GraphQL 유형과 뮤테이션을 검토합니다. 엔드포인트가 /projects/:id/...와 같은 패턴을 따르면 project를 포함합니다. 엔드포인트가 /groups/:id/...를 따르면 group을 포함합니다. GraphQL의 경우 지시자에 선언된 boundary_type을 확인합니다. 엔드포인트가 실제로 지원하는 경계만 포함합니다.

중요한 제약 사항#

  • 할당 가능한 권한에 포함된 각 원시 권한은 이미 존재해야 합니다 (원시 권한 정의 파일로 생성됨)
  • 할당 가능한 권한에 할당된 원시 권한만 토큰 인증에 사용할 수 있습니다
  • 관련 할당 가능한 권한 전체에 걸쳐 일관된 이름 지정을 사용합니다

할당 가능한 권한 유효성 검사#

할당 가능한 권한 유효성 검사는 git push 실행 시 Lefthook의 pre-push 훅에 의해 자동으로 실행됩니다. 수동으로도 실행할 수 있습니다:

bundle exec rake gitlab:permissions:validate

유효성 검사 작업은 여러 제약 사항을 적용합니다:

  • 할당 가능한 권한은 정확히 config/authz/permission_groups/assignable_permissions/<category>/<resource>/<action>.yml에 있어야 합니다.
  • 기본 경로와 최종 파일 이름 사이에 추가 디렉터리는 허용되지 않습니다.
  • 각 REST API 라우트의 boundary_type 및 각 GraphQL 지시자의 boundary_type은 할당 가능한 권한의 boundaries 필드에 있는 하나 이상의 경계와 일치해야 합니다(예: 라우트나 지시자가 boundary_type: :project를 선언하는 경우, 할당 가능한 권한의 경계에 project가 포함되어야 함).

할당 가능한 권한 유지 관리#

할당 가능한 권한은 시간이 지남에 따라 변경이 필요할 수 있습니다. 이 섹션에서는 일반적인 변경 시나리오와 그 영향을 다룹니다.

토큰이 권한을 해석하는 방법#

변경하기 전에 토큰이 권한을 저장하고 해석하는 방법을 이해하는 것이 중요합니다.

토큰은 데이터베이스에 할당 가능한 권한 이름(원시 권한이 아님)을 저장합니다. 요청 시 시스템은 현재 YAML 정의를 사용하여 이 이름을 동적으로 원시 권한으로 해석합니다. 이는 YAML 파일의 변경 사항이 마이그레이션 없이 모든 기존 토큰에 즉시 적용됨을 의미합니다.

이는 app/models/authz/granular_scope.rb에서 구현됩니다:

scope
  .pluck(Arel.sql('DISTINCT jsonb_array_elements_text(permissions)'))
  .flat_map { |p| ::Authz::PermissionGroups::Assignable.get(p)&.permissions }
  .compact.map(&:to_sym)

Assignable.get(p)가 현재 YAML 정의에서 저장된 이름을 찾을 수 없으면 nil을 반환하고 권한이 조용히 무시됩니다. 이것이 할당 가능한 권한이 이름 변경되거나 제거될 때 오류가 발생하는 근본 원인입니다.

할당 가능한 권한 추가#

새 할당 가능한 권한 추가는 안전합니다. 새 YAML 파일은 자동으로 검색되어 세분화된 스코프를 만들 때 UI에서 표시됩니다. 기존 토큰은 영향을 받지 않습니다.

Note

할당 가능한 권한에 포함된 원시 권한 중 어느 것도 API 인증에 사용되지 않으면, 토큰을 만드는 사용자는 해당 권한을 추가해도 효과를 볼 수 없습니다. 할당 가능한 권한이 API 인증 외부에서도 사용될 수 있으므로(예: Repository > Code > Download/Push 권한은 Git 작업에 사용됨) 이에 대한 정적 유효성 검사는 없습니다.

할당 가능한 권한 제거#

할당 가능한 권한 제거는 중단 변경입니다. 해당 할당 가능한 권한으로 만든 토큰은 Assignable.get(p)가 제거된 이름에 대해 nil을 반환하므로 포함된 원시 권한이 부여한 모든 API 접근을 잃습니다.

기본 API 기능도 제거되는 경우에만 할당 가능한 권한을 제거합니다.

할당 가능한 권한 이름 변경#

할당 가능한 권한 이름 변경은 중단 변경입니다. 이전 이름으로 만든 토큰은 저장된 이름이 더 이상 YAML 정의와 일치하지 않으므로 접근을 잃습니다.

이를 위해 3단계 프로세스가 필요합니다:

  1. 다음을 수행하는 머지 리퀘스트를 만듭니다:
    • 새 할당 가능한 권한 YAML 파일 추가.
    • 데이터베이스의 저장된 이름을 업데이트하는 rename_granular_scope_permission 배포 후 배치 백그라운드 마이그레이션 추가 (아래 참조).
    • 이전 할당 가능한 권한을 더 이상 사용되지 않음으로 표시.
  2. 이후 마일스톤에서 배치 백그라운드 마이그레이션 최종화하여 업그레이드 중 남은 행을 동기적으로 마이그레이션합니다.
  3. 마이그레이션이 최종화된 후 더 이상 사용되지 않는 권한을 제거하는 후속 머지 리퀘스트를 만듭니다.
이름 변경 마이그레이션 만들기

설명적인 이름으로 마이그레이션 스캐폴드를 생성합니다:

bundle exec rails g batched_background_migration rename_granular_scope_permission_<description> \
  --table-name=granular_scopes --feature-category=permissions

생성된 배포 후 마이그레이션 내용을 다음으로 교체합니다:

# frozen_string_literal: true

class QueueRenameGranularScopePermissionDescription < Gitlab::Database::Migration[2.3]
  milestone '<milestone>'
  restrict_gitlab_migration gitlab_schema: :gitlab_main_org

  MIGRATION = 'RenameGranularScopePermissionDescription'

  def up
    queue_batched_background_migration(
      MIGRATION,
      :granular_scopes,
      :id
    )
  end

  def down
    delete_batched_background_migration(MIGRATION, :granular_scopes, :id, [])
  end
end

생성된 백그라운드 마이그레이션 내용을 다음으로 교체합니다:

# frozen_string_literal: true

module Gitlab
  module BackgroundMigration
    class RenameGranularScopePermissionDescription < BatchedMigrationJob
      include Gitlab::Database::MigrationHelpers::GranularScopePermissions

      RENAMES = {
        'old_name_one' => 'new_name_one',
        'old_name_two' => %w[new_name_two_a new_name_two_b]
      }.freeze

      feature_category :permissions
    end
  end
end

RENAMES 해시, 클래스 이름, milestone을 이름 변경 및 대상 릴리스에 맞게 업데이트합니다. RENAMES의 값은 문자열(단순 이름 변경) 또는 배열(하나의 권한을 여러 개로 분할)이 될 수 있습니다. 단일 이름 변경에는 하나의 항목을 사용하거나, 동일한 배치 처리에서 여러 이름 변경을 처리하려면 여러 항목을 사용합니다.

할당 가능한 권한에 원시 권한 추가#

기존 할당 가능한 권한에 원시 권한을 추가하면 해당 할당 가능한 권한으로 이전에 만든 토큰이 증가된 접근 권한을 얻게 됩니다.

해석이 동적이므로 새 원시 권한이 즉시 적용됩니다. 이것이 최소 권한 원칙을 위반하는 것처럼 보일 수 있지만, 각 원시 권한이 하나의 할당 가능한 권한에만 속할 수 있다는 유효성 검사로 인해 새 기능은 다른 권한을 통해 접근할 수 없었을 것입니다. 사용자는 할당 가능한 권한이 동일한 리소스에 대한 새 기능을 포함할 것으로 기대할 것입니다.

새 API 엔드포인트에 대한 지원을 추가할 때만 원시 권한을 추가합니다. 할당 가능한 권한의 YAML 파일에서 permissions 배열에 원시 권한을 추가합니다.

할당 가능한 권한에서 원시 권한 제거#

할당 가능한 권한에서 원시 권한 제거는 중단 변경입니다. 해당 할당 가능한 권한을 가진 토큰은 제거된 원시 권한이 부여한 접근을 즉시 잃습니다.

이를 rename_granular_scope_permission 마이그레이션을 사용하여 이전 할당 가능한 권한을 이전 권한(제거된 원시 권한 제외)과 이동된 원시 권한을 포함하는 새 할당 가능한 권한의 조합으로 교체함으로써 완화할 수 있습니다.

Note

이 접근 방식은 새 할당 가능한 권한이 이동 중인 권한 외에 추가 원시 권한을 포함하는 경우 접근 증가로 이어질 수 있습니다.

엔드포인트 또는 지시자의 경계 유형 변경#

REST API route_setting 또는 GraphQL authorize_granular_token 지시자의 boundary_type 변경은 기존 토큰에 대한 중단 변경이 될 수 있습니다.

할당 가능한 권한의 boundaries 필드는 원시 권한의 엔드포인트와 지시자가 선언한 모든 boundary_type 값의 합집합을 포함해야 합니다. 할당 가능한 권한 경계를 직접 변경하지 않습니다—엔드포인트가 boundary_type을 추가하거나 변경하거나, 원시 권한이 할당 가능한 권한에 추가되거나 제거됨에 따라 변경됩니다. Lefthook pre-push 유효성 검사가 불일치를 잡아냅니다.

토큰은 세분화된 스코프를 경계(네임스페이스)와 할당 가능한 권한의 조합으로 저장합니다. 엔드포인트의 boundary_type이 변경되면 인증 검사는 새 경계에 대해 토큰의 스코프를 평가합니다. 토큰이 이전 경계에 대한 스코프로 만들어진 경우 더 이상 일치하지 않을 수 있습니다.

projectgroup 간 변경은 안전합니다. 프로젝트는 그룹에 속하므로 그룹 경계 세분화된 스코프를 가진 토큰은 해당 그룹 내의 프로젝트도 포함하고, 프로젝트 경계 스코프는 그룹 엔드포인트의 영향을 받지 않습니다.

user 또는 instance로 또는 이들 사이의 변경(예: project에서 instance로)은 중단 변경입니다. 해당 권한에 대한 프로젝트 경계 세분화된 스코프로 만들어진 토큰은 더 이상 접근 권한이 없습니다. 토큰 보유자는 새 경계에서 새 스코프를 만들어야 합니다.

API 인증에 사용되는 원시 권한 이름 변경#

원시 권한 이름 변경은 UI나 기존 토큰에 영향을 미치지 않습니다. 토큰은 할당 가능한 권한 이름(원시 권한 이름이 아님)을 저장하므로 원시 권한 이름 변경 시 YAML 파일만 업데이트하면 됩니다:

  • 원시 권한 정의 파일 (config/authz/permissions/<resource>/<action>.yml)
  • 이를 참조하는 모든 할당 가능한 권한 YAML 파일

데이터베이스 마이그레이션이 필요하지 않습니다.