InfoGrab DocsInfoGrab Docs

권한 규칙

요약

새로운 권한은 절대적으로 필요한 경우에만 도입합니다. 새로운 권한을 도입해야 하는 예시는 admin_project처럼 권한 범위가 매우 광범위한 경우입니다. 새로운 권한은 최소 권한 원칙을 지원해야 합니다. 권한은 역할 정의 YAML 파일(기본 역할의 경우), 커스텀 ability YAML 파일(커스텀 역할의 경우), 그리고 할당 가능한 권한 그룹(세분화된 PAT 범위 지정의 경우)에서 참조됩니다.

새로운 권한 도입#

새로운 권한은 절대적으로 필요한 경우에만 도입합니다. 항상 기존 권한을 먼저 사용하려고 시도하세요. 예를 들어, 이미 read_issue가 있고 두 권한 모두 동일한 수준의 접근을 요구한다면 read_issue_description 권한을 새로 만들 필요가 없습니다. 일반 지침으로, 주체(subject)와 행위(action)가 동일한 경우 권한을 재사용할 수 있습니다. 앞의 예시에서 주체는 issue이고 행위는 read입니다. 사용자가 읽을 수 있는 이슈의 각 속성마다 새로운 권한을 만들 필요는 없습니다.

새로운 권한을 도입해야 하는 예시는 admin_project처럼 권한 범위가 매우 광범위한 경우입니다. 이 경우 권한이 모호하며 프로젝트 Maintainer에게 부여됩니다. 이론적으로 이 권한은 Maintainer에게 해당 기능이 부여되므로 프로젝트의 CI/CD 변수 관리 접근을 제어하는 데 사용될 수 있습니다. 그러나 광범위한 권한을 사용할 때 권한 검사를 보면 무엇을 인가(authorize)하는지 명확하지 않습니다. 또한 admin_cicd_variable이나 manage_cicd_variable과 같은 권한은 인가되는 서로 다른 행위를 암시하므로 사용을 피해야 합니다. 대신 create_cicd_variable이나 read_cicd_variable처럼 행위가 구체적이어야 합니다. 세분화된 권한을 구현하면 커스텀 역할에 대한 최소 권한 원칙을 준수할 수 있고, 표준 역할에 대해 훨씬 더 세밀한 옵션을 제공합니다.

새로운 권한은 최소 권한 원칙을 지원해야 합니다. 단일 리소스에 대해 단일하고 명확하게 정의된 행위에 필요한 접근만 부여해야 하며, 그 이상은 안 됩니다. 제안된 권한이 두 개 이상의 행위에 접근을 부여하거나 관련 없는 기능을 묶는 경우, 별도의 권한으로 분리하세요. 이렇게 좁은 범위로 권한을 지정할 수 없다면, 도입 전에 설계를 재검토하세요.

권한은 역할 정의 YAML 파일(기본 역할의 경우), 커스텀 ability YAML 파일(커스텀 역할의 경우), 그리고 할당 가능한 권한 그룹(세분화된 PAT 범위 지정의 경우)에서 참조됩니다.

권한 명명#

모든 권한이 일관된 패턴인 action_resource(_subresource) 를 따르는 것이 목표입니다. 이 지침은 할당 가능한 권한(Assignable Permissions)과 원시 권한(Raw Permissions) 모두에 적용되지만, 공개 facing인 할당 가능한 권한에서 가장 엄격하게 준수되어야 합니다.

선호 행위(Actions)#

새로운 권한을 도입할 때는 다음 행위 중 하나를 사용하는 것을 선호합니다:

행위 기능 예시
create 새 객체를 생성함 create_issue
read 객체를 조회하거나 검색함 read_project
update 기존 객체를 수정함 update_merge_request
delete 객체를 제거함 delete_issue

이 행위 집합이 제한적이며 모든 기능에 적용 가능하지 않다는 것을 인식하고 있습니다. 행위는 이 집합 외부에서 상황에 따라 허용되지만, Authorization 팀의 승인이 필요합니다.

허용되지 않는 행위(Actions)#

다음 행위 패턴들은 권한 카탈로그에 도입하지 않아야 하는 예시입니다:

행위 허용되지 않는 이유
admin 범위가 불명확한 광범위하고 정의되지 않은 권한을 암시함
change update와 중복됨
configure update와 중복됨
destroy 도메인 행위가 아닌 구현 시맨틱을 반영함; delete를 선호함
edit update와 중복됨
list 모호한 read 시맨틱; read를 사용할 것
manage 여러 CRUD 작업을 하나의 모호한 권한으로 묶음
modify update와 중복됨
set update와 중복됨
view 모호한 read 시맨틱; read를 사용할 것
write create, update, delete 작업을 모두 포함하여, 사용자가 create나 update만 필요할 때 실수로 delete 접근을 받는 보안 사고를 일으키는 의도치 않은 권한 상승을 야기함. create, update, delete와 같은 구체적인 행위를 사용할 것

이러한 행위를 가진 권한이 있더라도, 이러한 규칙이 수립되기 전에 도입된 것이며 결국 현재 지침에 맞게 리팩토링될 것입니다.

새로운 행위를 도입해야 하는 경우#

선호 행위 집합 외부의 행위 중 사용자에게 안전하고 직관적인 권한 모델을 제공하기 위해 필요한 것들이 있습니다.

다음과 같은 경우 새로운 행위를 도입할 수 있습니다:

  • 행위가 GitLab 도메인 언어에 이미 존재하는 별개의 라이프사이클 또는 상태 전환을 나타내는 경우. 예를 들어, archive_projectprotect_branch는 GitLab 도메인 언어 내에 이미 확립되어 있기 때문에 사용자가 이해하고 기대하는 구체적인 행위를 나타냅니다.

  • 행위가 GitLab 도메인 언어의 일부인 리소스 간의 관계를 변경하는 경우. 예를 들어, transfer_projectmove_issue는 리소스와 그 상위 네임스페이스 간의 관계를 변경하는 구체적인 행위를 나타냅니다.

  • 행위가 높은 영향력을 가지거나 되돌릴 수 없으며 별개의 도메인 의미를 갖는 경우. 예를 들어, purge_maven_virtual_registry_cachepurge 행위를 사용하는데, 이는 되돌릴 수 없으며 더 넓은 소프트웨어 산업에서 캐싱을 논의할 때 확립된 의미를 가집니다.

리소스 명명 규칙#

권한 이름에서 리소스(및 선택적 하위 리소스)는 항상 다음을 따라야 합니다:

  • 단수 형태를 사용합니다 (예: read_projects 대신 read_project)

  • 행위를 적용하는 도메인 객체와 일치해야 합니다. (예: Issue에 대해 행위를 평가한다면 권한 이름은 {action}_issue 형식이어야 합니다.)

  • 구현 세부 사항을 노출하는 대신 사용자 facing 도메인 용어를 사용합니다. (예: 고객이 해당 리소스를 알 방법이 없다면, 권한 이름에 포함하지 않는 것이 좋습니다)

권한 이름에서 리소스 경계 방지#

권한은 권한 이름에 리소스 경계(예: project, group, user)를 직접 인코딩해서는 안 됩니다.

예를 들어, read_project_insights_dashboardread_group_insights_dashboard와 같이 별도의 권한을 도입하는 것을 피하세요. 대신 read_insights_dashboard처럼 기능 자체를 설명하는 단일 시맨틱 권한을 정의하세요.

권한 이름에 projectgroup과 같은 경계를 포함하는 것은 중복입니다. 왜냐하면 can? 검사에서 subject를 전달하면 이미 범위가 결정되기 때문입니다. 예를 들어:

can?(:read_insights_dashboard, project)
can?(:read_insights_dashboard, group)

예외#

이러한 규칙을 따르지 않는 새로운 권한이 필요하다고 생각되면, Govern:Authorization 팀에 문의하세요. 항상 토론에 열려 있으며, 이 지침은 Engineer의 작업을 어렵게 하는 것이 아니라 더 쉽게 만들기 위한 것입니다.

비공개 권한#

비공개 권한(private permissions)은 조건부 또는 미묘한 기능을 나타내는 좁은 범위의 권한입니다. 이 권한들은 정책 로직에서만 비공개임을 나타내기 위해 밑줄(_)을 접두사로 붙이며, 강제 지점(컨트롤러, 서비스, finder, GraphQL)에서 직접 검사해서는 안 됩니다.

비공개 권한이 존재하는 이유#

GitLab RBAC 모델에서 동일한 행위는 역할에 따라 다르게 동작할 수 있습니다. 예를 들어:

  • Guest자신이 작성했거나 할당된 기밀 이슈를 읽을 수 있습니다.

  • Planner+모든 기밀 이슈를 읽을 수 있습니다.

비공개 권한 없이는 두 경우 모두 단일 read_issue 권한에 매핑되고, 미묘한 차이가 절차적 정책 로직에 묻혀버립니다. 이는 다음과 같은 문제를 야기합니다:

  • 권한 상승 위험: 사용자가 다른 사용자를 초대할 때, 시스템은 초대된 역할의 권한이 초대하는 사용자 자신의 권한을 초과하지 않는지 검증해야 합니다. read_issue와 같은 단순한 권한으로는 작성한 이슈만 읽을 수 있는 Guest와 모든 이슈를 읽을 수 있는 Owner가 동일하게 보입니다.

  • 커스텀 역할 모호성: 단순한 권한으로 구성된 커스텀 역할은 "작성한 이슈만 읽기"를 표현할 수 없습니다. 커스텀 역할은 전체 read_issue(너무 광범위함)를 받거나 아무것도 받지 못하게 됩니다(너무 제한적임).

비공개 권한은 이러한 문제를 해결합니다. 미묘한 차이를 명시적이고 기계가 읽을 수 있도록 만듭니다.

명명 규칙#

비공개 권한은 _<action>_<qualifier>_<resource> 패턴을 따르며, qualifier는 권한이 적용되는 조건을 설명합니다:

권한 설명 일반적인 역할
_read_authored_issue 기밀 여부에 관계없이 자신이 작성한 이슈를 읽음 Guest+, Internal
_read_assigned_issue 기밀 여부에 관계없이 자신에게 할당된 이슈를 읽음 Guest+, Internal
_read_confidential_issue 모든 기밀 이슈를 읽음 Planner, Reporter+

밑줄 접두사는 여러 목적을 제공합니다:

  • 코드 및 YAML 정의에서 비공개 권한을 공개 권한과 시각적으로 구분합니다.

  • 개발자와 툴링에 이 권한이 정책 파일 외부의 can? 검사에 나타나서는 안 된다는 신호를 줍니다.

  • linter가 부적절한 사용을 플래그 처리하기 쉽게 만듭니다.

  • 구성보다 규칙(Convention over configuration). 밑줄 구문은 권한 정의에 메타데이터를 저장하는 것보다 선호됩니다.

Qualifier 명명 규칙#

qualifier는 일반적으로 리소스의 속성이어야 합니다. 리소스 자체에 존재하는 속성을 기반으로, 권한이 적용되는 리소스의 하위 집합을 설명합니다.

qualifier에 대한 지침:

  • qualifier는 리소스의 실제 속성 또는 관계에 대응해야 합니다. 행위자(actor)를 설명하는 qualifier는 사용하지 마세요 (예: admin_read_issue 피하기).

  • 리소스의 설명으로 자연스럽게 읽히는 과거 분사 또는 형용사 형태를 선호합니다 (예: confidential, authored, assigned).

  • qualifier는 동일한 리소스에 대한 동일한 행위가 리소스의 상태에 따라 다른 접근 수준을 필요로 할 때만 도입해야 합니다. 리소스의 모든 인스턴스가 동일한 접근 수준을 요구한다면 qualifier는 필요하지 않습니다.

정책에서 비공개 권한을 사용하는 방법#

비공개 권한은 게이트 역할을 합니다. 역할 YAML 정의를 통해 역할이 비공개 권한을 활성화합니다. 그런 다음 정책은 비공개 권한과 subject 수준 조건을 결합하여 더 넓은 공개 권한을 활성화합니다:

# In the role YAML (e.g., config/authz/roles/guest.yml):
#   raw_permissions:
#     - _read_authored_issue
#     - _read_assigned_issue
#     - read_issue
#
# In the role YAML (e.g., config/authz/roles/reporter.yml):
#   raw_permissions:
#     - _read_authored_issue
#     - _read_assigned_issue
#     - _read_confidential_issue
#     - read_issue

# In the issue policy (e.g., app/policies/issue_policy.rb):
condition(:is_author) { @subject.author == @user }
condition(:is_assignee) { @subject.assignees.include?(@user) }
condition(:is_confidential) { @subject.confidential? }

rule { is_author & can?(:_read_authored_issue) }.policy do
  enable :read_issue
  enable :_read_confidential_issue
end

rule { is_assignee & can?(:_read_assigned_issue) }.policy do
  enable :read_issue
  enable :_read_confidential_issue
end

rule { is_confidential & ~can?(:_read_confidential_issue) }.prevent :read_issue

강제 지점(컨트롤러, 서비스, GraphQL)은 공개 권한만 검사합니다:

# Correct - check the public permission
authorize :read_issue

# Wrong - never check a private permission at an enforcement point
authorize :_read_authored_issue

비공개 권한을 사용해야 하는 경우#

다음과 같은 경우 비공개 권한을 사용합니다:

  • 역할이 subject 수준 조건이 충족될 때만 행위를 수행할 수 있는 경우 (사용자가 작성함, 사용자에게 할당됨, 사용자가 생성함).

  • 다른 역할이 동일한 행위에 대해 서로 다른 수준의 접근을 갖는 경우 (일부는 무조건적, 일부는 조건부).

  • 구분이 권한 상승 검사 또는 커스텀 역할 구성에 중요한 경우.

다음과 같은 경우 비공개 권한을 사용하지 않습니다:

  • 기능 플래그 또는 라이선스 검사. 대신 prevent 규칙을 사용하세요.

  • 설정 기반 제한. 대신 prevent 규칙을 사용하세요.

  • 모든 역할에 동등하게 적용되는 조건. 단일 prevent 규칙을 사용하세요.

권한 정의 파일#

비공개 권한도 다른 권한과 마찬가지로 정의 파일이 필요합니다. 파일 이름은 권한 이름과 일치하도록 밑줄 접두사를 사용합니다:

config/authz/permissions/<resource>/_<action>_<qualifier>.yml

예를 들어:

# config/authz/permissions/issue/_read_authored.yml
---
name: _read_authored_issue
description: Allows users to read issues they authored when they would not otherwise have access

권한 규칙

GitLab v19.1
원문 보기
요약

새로운 권한은 절대적으로 필요한 경우에만 도입합니다. 새로운 권한을 도입해야 하는 예시는 admin_project처럼 권한 범위가 매우 광범위한 경우입니다. 새로운 권한은 최소 권한 원칙을 지원해야 합니다. 권한은 역할 정의 YAML 파일(기본 역할의 경우), 커스텀 ability YAML 파일(커스텀 역할의 경우), 그리고 할당 가능한 권한 그룹(세분화된 PAT 범위 지정의 경우)에서 참조됩니다.

새로운 권한 도입#

새로운 권한은 절대적으로 필요한 경우에만 도입합니다. 항상 기존 권한을 먼저 사용하려고 시도하세요. 예를 들어, 이미 read_issue가 있고 두 권한 모두 동일한 수준의 접근을 요구한다면 read_issue_description 권한을 새로 만들 필요가 없습니다. 일반 지침으로, 주체(subject)와 행위(action)가 동일한 경우 권한을 재사용할 수 있습니다. 앞의 예시에서 주체는 issue이고 행위는 read입니다. 사용자가 읽을 수 있는 이슈의 각 속성마다 새로운 권한을 만들 필요는 없습니다.

새로운 권한을 도입해야 하는 예시는 admin_project처럼 권한 범위가 매우 광범위한 경우입니다. 이 경우 권한이 모호하며 프로젝트 Maintainer에게 부여됩니다. 이론적으로 이 권한은 Maintainer에게 해당 기능이 부여되므로 프로젝트의 CI/CD 변수 관리 접근을 제어하는 데 사용될 수 있습니다. 그러나 광범위한 권한을 사용할 때 권한 검사를 보면 무엇을 인가(authorize)하는지 명확하지 않습니다. 또한 admin_cicd_variable이나 manage_cicd_variable과 같은 권한은 인가되는 서로 다른 행위를 암시하므로 사용을 피해야 합니다. 대신 create_cicd_variable이나 read_cicd_variable처럼 행위가 구체적이어야 합니다. 세분화된 권한을 구현하면 커스텀 역할에 대한 최소 권한 원칙을 준수할 수 있고, 표준 역할에 대해 훨씬 더 세밀한 옵션을 제공합니다.

새로운 권한은 최소 권한 원칙을 지원해야 합니다. 단일 리소스에 대해 단일하고 명확하게 정의된 행위에 필요한 접근만 부여해야 하며, 그 이상은 안 됩니다. 제안된 권한이 두 개 이상의 행위에 접근을 부여하거나 관련 없는 기능을 묶는 경우, 별도의 권한으로 분리하세요. 이렇게 좁은 범위로 권한을 지정할 수 없다면, 도입 전에 설계를 재검토하세요.

권한은 역할 정의 YAML 파일(기본 역할의 경우), 커스텀 ability YAML 파일(커스텀 역할의 경우), 그리고 할당 가능한 권한 그룹(세분화된 PAT 범위 지정의 경우)에서 참조됩니다.

권한 명명#

모든 권한이 일관된 패턴인 action_resource(_subresource) 를 따르는 것이 목표입니다. 이 지침은 할당 가능한 권한(Assignable Permissions)과 원시 권한(Raw Permissions) 모두에 적용되지만, 공개 facing인 할당 가능한 권한에서 가장 엄격하게 준수되어야 합니다.

선호 행위(Actions)#

새로운 권한을 도입할 때는 다음 행위 중 하나를 사용하는 것을 선호합니다:

행위 기능 예시
create 새 객체를 생성함 create_issue
read 객체를 조회하거나 검색함 read_project
update 기존 객체를 수정함 update_merge_request
delete 객체를 제거함 delete_issue

이 행위 집합이 제한적이며 모든 기능에 적용 가능하지 않다는 것을 인식하고 있습니다. 행위는 이 집합 외부에서 상황에 따라 허용되지만, Authorization 팀의 승인이 필요합니다.

허용되지 않는 행위(Actions)#

다음 행위 패턴들은 권한 카탈로그에 도입하지 않아야 하는 예시입니다:

행위 허용되지 않는 이유
admin 범위가 불명확한 광범위하고 정의되지 않은 권한을 암시함
change update와 중복됨
configure update와 중복됨
destroy 도메인 행위가 아닌 구현 시맨틱을 반영함; delete를 선호함
edit update와 중복됨
list 모호한 read 시맨틱; read를 사용할 것
manage 여러 CRUD 작업을 하나의 모호한 권한으로 묶음
modify update와 중복됨
set update와 중복됨
view 모호한 read 시맨틱; read를 사용할 것
write create, update, delete 작업을 모두 포함하여, 사용자가 create나 update만 필요할 때 실수로 delete 접근을 받는 보안 사고를 일으키는 의도치 않은 권한 상승을 야기함. create, update, delete와 같은 구체적인 행위를 사용할 것

이러한 행위를 가진 권한이 있더라도, 이러한 규칙이 수립되기 전에 도입된 것이며 결국 현재 지침에 맞게 리팩토링될 것입니다.

새로운 행위를 도입해야 하는 경우#

선호 행위 집합 외부의 행위 중 사용자에게 안전하고 직관적인 권한 모델을 제공하기 위해 필요한 것들이 있습니다.

다음과 같은 경우 새로운 행위를 도입할 수 있습니다:

  • 행위가 GitLab 도메인 언어에 이미 존재하는 별개의 라이프사이클 또는 상태 전환을 나타내는 경우. 예를 들어, archive_projectprotect_branch는 GitLab 도메인 언어 내에 이미 확립되어 있기 때문에 사용자가 이해하고 기대하는 구체적인 행위를 나타냅니다.

  • 행위가 GitLab 도메인 언어의 일부인 리소스 간의 관계를 변경하는 경우. 예를 들어, transfer_projectmove_issue는 리소스와 그 상위 네임스페이스 간의 관계를 변경하는 구체적인 행위를 나타냅니다.

  • 행위가 높은 영향력을 가지거나 되돌릴 수 없으며 별개의 도메인 의미를 갖는 경우. 예를 들어, purge_maven_virtual_registry_cachepurge 행위를 사용하는데, 이는 되돌릴 수 없으며 더 넓은 소프트웨어 산업에서 캐싱을 논의할 때 확립된 의미를 가집니다.

리소스 명명 규칙#

권한 이름에서 리소스(및 선택적 하위 리소스)는 항상 다음을 따라야 합니다:

  • 단수 형태를 사용합니다 (예: read_projects 대신 read_project)

  • 행위를 적용하는 도메인 객체와 일치해야 합니다. (예: Issue에 대해 행위를 평가한다면 권한 이름은 {action}_issue 형식이어야 합니다.)

  • 구현 세부 사항을 노출하는 대신 사용자 facing 도메인 용어를 사용합니다. (예: 고객이 해당 리소스를 알 방법이 없다면, 권한 이름에 포함하지 않는 것이 좋습니다)

권한 이름에서 리소스 경계 방지#

권한은 권한 이름에 리소스 경계(예: project, group, user)를 직접 인코딩해서는 안 됩니다.

예를 들어, read_project_insights_dashboardread_group_insights_dashboard와 같이 별도의 권한을 도입하는 것을 피하세요. 대신 read_insights_dashboard처럼 기능 자체를 설명하는 단일 시맨틱 권한을 정의하세요.

권한 이름에 projectgroup과 같은 경계를 포함하는 것은 중복입니다. 왜냐하면 can? 검사에서 subject를 전달하면 이미 범위가 결정되기 때문입니다. 예를 들어:

can?(:read_insights_dashboard, project)
can?(:read_insights_dashboard, group)

예외#

이러한 규칙을 따르지 않는 새로운 권한이 필요하다고 생각되면, Govern:Authorization 팀에 문의하세요. 항상 토론에 열려 있으며, 이 지침은 Engineer의 작업을 어렵게 하는 것이 아니라 더 쉽게 만들기 위한 것입니다.

비공개 권한#

비공개 권한(private permissions)은 조건부 또는 미묘한 기능을 나타내는 좁은 범위의 권한입니다. 이 권한들은 정책 로직에서만 비공개임을 나타내기 위해 밑줄(_)을 접두사로 붙이며, 강제 지점(컨트롤러, 서비스, finder, GraphQL)에서 직접 검사해서는 안 됩니다.

비공개 권한이 존재하는 이유#

GitLab RBAC 모델에서 동일한 행위는 역할에 따라 다르게 동작할 수 있습니다. 예를 들어:

  • Guest자신이 작성했거나 할당된 기밀 이슈를 읽을 수 있습니다.

  • Planner+모든 기밀 이슈를 읽을 수 있습니다.

비공개 권한 없이는 두 경우 모두 단일 read_issue 권한에 매핑되고, 미묘한 차이가 절차적 정책 로직에 묻혀버립니다. 이는 다음과 같은 문제를 야기합니다:

  • 권한 상승 위험: 사용자가 다른 사용자를 초대할 때, 시스템은 초대된 역할의 권한이 초대하는 사용자 자신의 권한을 초과하지 않는지 검증해야 합니다. read_issue와 같은 단순한 권한으로는 작성한 이슈만 읽을 수 있는 Guest와 모든 이슈를 읽을 수 있는 Owner가 동일하게 보입니다.

  • 커스텀 역할 모호성: 단순한 권한으로 구성된 커스텀 역할은 "작성한 이슈만 읽기"를 표현할 수 없습니다. 커스텀 역할은 전체 read_issue(너무 광범위함)를 받거나 아무것도 받지 못하게 됩니다(너무 제한적임).

비공개 권한은 이러한 문제를 해결합니다. 미묘한 차이를 명시적이고 기계가 읽을 수 있도록 만듭니다.

명명 규칙#

비공개 권한은 _<action>_<qualifier>_<resource> 패턴을 따르며, qualifier는 권한이 적용되는 조건을 설명합니다:

권한 설명 일반적인 역할
_read_authored_issue 기밀 여부에 관계없이 자신이 작성한 이슈를 읽음 Guest+, Internal
_read_assigned_issue 기밀 여부에 관계없이 자신에게 할당된 이슈를 읽음 Guest+, Internal
_read_confidential_issue 모든 기밀 이슈를 읽음 Planner, Reporter+

밑줄 접두사는 여러 목적을 제공합니다:

  • 코드 및 YAML 정의에서 비공개 권한을 공개 권한과 시각적으로 구분합니다.

  • 개발자와 툴링에 이 권한이 정책 파일 외부의 can? 검사에 나타나서는 안 된다는 신호를 줍니다.

  • linter가 부적절한 사용을 플래그 처리하기 쉽게 만듭니다.

  • 구성보다 규칙(Convention over configuration). 밑줄 구문은 권한 정의에 메타데이터를 저장하는 것보다 선호됩니다.

Qualifier 명명 규칙#

qualifier는 일반적으로 리소스의 속성이어야 합니다. 리소스 자체에 존재하는 속성을 기반으로, 권한이 적용되는 리소스의 하위 집합을 설명합니다.

qualifier에 대한 지침:

  • qualifier는 리소스의 실제 속성 또는 관계에 대응해야 합니다. 행위자(actor)를 설명하는 qualifier는 사용하지 마세요 (예: admin_read_issue 피하기).

  • 리소스의 설명으로 자연스럽게 읽히는 과거 분사 또는 형용사 형태를 선호합니다 (예: confidential, authored, assigned).

  • qualifier는 동일한 리소스에 대한 동일한 행위가 리소스의 상태에 따라 다른 접근 수준을 필요로 할 때만 도입해야 합니다. 리소스의 모든 인스턴스가 동일한 접근 수준을 요구한다면 qualifier는 필요하지 않습니다.

정책에서 비공개 권한을 사용하는 방법#

비공개 권한은 게이트 역할을 합니다. 역할 YAML 정의를 통해 역할이 비공개 권한을 활성화합니다. 그런 다음 정책은 비공개 권한과 subject 수준 조건을 결합하여 더 넓은 공개 권한을 활성화합니다:

# In the role YAML (e.g., config/authz/roles/guest.yml):
#   raw_permissions:
#     - _read_authored_issue
#     - _read_assigned_issue
#     - read_issue
#
# In the role YAML (e.g., config/authz/roles/reporter.yml):
#   raw_permissions:
#     - _read_authored_issue
#     - _read_assigned_issue
#     - _read_confidential_issue
#     - read_issue

# In the issue policy (e.g., app/policies/issue_policy.rb):
condition(:is_author) { @subject.author == @user }
condition(:is_assignee) { @subject.assignees.include?(@user) }
condition(:is_confidential) { @subject.confidential? }

rule { is_author & can?(:_read_authored_issue) }.policy do
  enable :read_issue
  enable :_read_confidential_issue
end

rule { is_assignee & can?(:_read_assigned_issue) }.policy do
  enable :read_issue
  enable :_read_confidential_issue
end

rule { is_confidential & ~can?(:_read_confidential_issue) }.prevent :read_issue

강제 지점(컨트롤러, 서비스, GraphQL)은 공개 권한만 검사합니다:

# Correct - check the public permission
authorize :read_issue

# Wrong - never check a private permission at an enforcement point
authorize :_read_authored_issue

비공개 권한을 사용해야 하는 경우#

다음과 같은 경우 비공개 권한을 사용합니다:

  • 역할이 subject 수준 조건이 충족될 때만 행위를 수행할 수 있는 경우 (사용자가 작성함, 사용자에게 할당됨, 사용자가 생성함).

  • 다른 역할이 동일한 행위에 대해 서로 다른 수준의 접근을 갖는 경우 (일부는 무조건적, 일부는 조건부).

  • 구분이 권한 상승 검사 또는 커스텀 역할 구성에 중요한 경우.

다음과 같은 경우 비공개 권한을 사용하지 않습니다:

  • 기능 플래그 또는 라이선스 검사. 대신 prevent 규칙을 사용하세요.

  • 설정 기반 제한. 대신 prevent 규칙을 사용하세요.

  • 모든 역할에 동등하게 적용되는 조건. 단일 prevent 규칙을 사용하세요.

권한 정의 파일#

비공개 권한도 다른 권한과 마찬가지로 정의 파일이 필요합니다. 파일 이름은 권한 이름과 일치하도록 밑줄 접두사를 사용합니다:

config/authz/permissions/<resource>/_<action>_<qualifier>.yml

예를 들어:

# config/authz/permissions/issue/_read_authored.yml
---
name: _read_authored_issue
description: Allows users to read issues they authored when they would not otherwise have access