InfoGrab DocsInfoGrab Docs

Secrets Manager 등록

요약

등록은 가용성 게이트 두 가지 중 하나입니다. GitLab.com의 등록은 최상위 그룹 단위입니다. 등록은 단순한 불리언이 아니라 세 가지 상태입니다. NamespaceEnrollment.enrolled?(namespace)와 다른 클래스 쿼리 메서드(opted_out?, beta_enrolled?, add_on_requested?)는 모두 먼저 네임스페이스를 root_ancestor로 해석합니다.

등록은 가용성 게이트 두 가지 중 하나입니다. 등록은 네임스페이스나 인스턴스가 Secrets Manager를 켰는가라는 하나의 질문에 답합니다. 다른 게이트는 native_secrets_management 라이선스입니다. 체험판과 과금 상태에 따라 등록된 네임스페이스가 무엇을 할 수 있는지 결정하는 자격은 별도의 주제입니다. Secrets Manager 이행 및 자격을 참고합니다.

GitLab.com의 네임스페이스 등록#

GitLab.com의 등록은 최상위 그룹 단위입니다. 모델은 ee/app/models/secrets_management/namespace_enrollment.rb의 SecretsManagement::NamespaceEnrollment이며, secrets_manager_namespace_enrollments 테이블이 이를 뒷받침합니다.

칼럼 용도
namespace_id 고유 값. 항상 최상위 그룹입니다.
beta 등록 시점에 설정됩니다. 베타 프로그램을 참고합니다.
disabled_at nil이면 등록된 상태입니다. 타임스탬프는 명시적인 옵트아웃을 나타냅니다.
add_on_requested_at 그룹이 체험판 없이 유료 추가 기능을 구매할 때 설정됩니다. 체험판과 추가 기능을 참고합니다.

등록은 단순한 불리언이 아니라 세 가지 상태입니다.

  • 행이 없음. 그룹이 등록한 적이 없습니다.
  • disabled_at이 nil로 설정된 행. 그룹이 등록되어 있습니다.
  • disabled_at이 설정된 행. 그룹이 명시적으로 옵트아웃했습니다.

NamespaceEnrollment.enrolled?(namespace)와 다른 클래스 쿼리 메서드(opted_out?, beta_enrolled?, add_on_requested?)는 모두 먼저 네임스페이스를 root_ancestor로 해석합니다. 따라서 최상위 그룹으로 호출하든 그 아래의 프로젝트나 하위 그룹으로 호출하든 똑같이 동작합니다.

GitLab Self-Managed의 인스턴스 등록#

GitLab Self-Managed의 등록은 네임스페이스별이 아니라 인스턴스 전체 단위입니다. application_settings의 칼럼 집합이며, ee/app/models/secrets_management/instance_enrollment.rb의 SecretsManagement::InstanceEnrollment를 통해 읽습니다.

칼럼 용도
secrets_manager_instance_enrolled 기본값은 false입니다. true이면 인스턴스가 등록된 상태입니다.
secrets_manager_instance_beta_enrolled 등록 시점에 설정됩니다. 네임스페이스 beta 칼럼과 의미가 같습니다.
secrets_manager_instance_add_on_requested_at 인스턴스가 체험판 없이 유료 추가 기능을 구매할 때 설정됩니다.

InstanceEnrollment.settings는 이 칼럼만 읽고 현재 요청 동안 Gitlab::SafeRequestStore에 캐시합니다. Gitlab::CurrentSettings를 통한 프로세스 수준 캐싱은 CI job 선택에 영향을 주는 검사에는 너무 거칩니다. 이 칼럼에 쓰는 모든 작업은 InstanceEnrollment.expire_settings를 호출하고 Gitlab::CurrentSettings를 만료시켜야 같은 요청의 다음 읽기에서 변경 사항이 보입니다. 이 설정은 REST 애플리케이션 설정 API로 노출되지 않습니다. 아래에서 설명하는 전용 GraphQL 뮤테이션이 이 설정을 바꾸는 유일한 방법입니다.

서비스#

서비스 두 개가 모든 등록 쓰기를 담당합니다. 등록 칼럼을 직접 업데이트하지 않습니다.

서비스 파일
SecretsManagement::NamespaceEnrollmentService ee/app/services/secrets_management/namespace_enrollment_service.rb
SecretsManagement::InstanceEnrollmentService ee/app/services/secrets_management/instance_enrollment_service.rb

두 서비스 모두 감사 추적을 위해 current_user:를 받으며 같은 네 가지 작업을 제공합니다.

메서드 동작
enroll 등록 레코드를 만들거나 다시 활성화합니다. 등록이 허용되지 않거나 이미 등록된 경우 실패합니다.
unenroll 네임스페이스나 인스턴스를 옵트아웃합니다.
enroll_with_add_on_intent 필요하면 등록한 다음 add_on_requested_at을 기록합니다. 유료 추가 기능 구매 흐름에서 사용합니다.
revert_add_on_intent enroll_with_add_on_intent가 변경한 내용을 정확히 되돌립니다. 해당 흐름의 이후 단계가 실패할 때 사용합니다.

NamespaceEnrollmentService#unenroll은 행을 삭제하지 않고 disabled_at을 설정합니다. 저장된 시크릿은 보존되며, 다시 등록하면 유료 추가 기능 의사를 잃지 않고 재개됩니다.

InstanceEnrollmentService#unenroll은 인스턴스 등록이 행이 아니라 칼럼 집합이므로 아무것도 삭제하지 않고 항상 secrets_manager_instance_enrolled를 지웁니다.

이미 등록된 네임스페이스에서 enroll을 호출하거나 이미 옵트아웃한 네임스페이스에서 unenroll을 호출하면 오류 응답을 반환하며 감사 이벤트를 만들지 않습니다. 등록한 적 없는 그룹에서 unenroll을 호출하면 옵트아웃된 행을 만들고 감사 이벤트를 기록하며 성공합니다.

각 서비스는 쓰기마다 SecretsManagement::Entitlement::Resolver.clear_cache로 자격 리졸버 캐시도 지웁니다. 이렇게 하지 않으면 등록이 바뀐 뒤에도 자격 캐시의 TTL(time to live) 동안 CI job 선택이 시크릿 액세스를 계속 허용하거나 거부할 수 있습니다.

가용성과 등록#

모든 가용성 확인은 ee/lib/secrets_management/availability.rb의 SecretsManagement::Availability를 거칩니다. 네임스페이스 등록과 인스턴스 등록 중 무엇을 참조할지 결정하는 곳이기도 하므로, 호출하는 쪽에서 Gitlab.com?으로 직접 분기할 필요가 없습니다.

메서드 확인 대상
for_project?(project) 라이선스와 enabled_for_project?.
for_group?(group) 라이선스와 enabled_for_group?.
for_instance? 라이선스와 InstanceEnrollment.enrolled?.
enabled_for_project?(project) 등록. 라이선스 확인 없음. for_project?에서만 호출되므로 액세스 경로에서 호출하지 않습니다.
enabled_for_group?(group) 아래의 유료 최상위 그룹 예외를 포함한 등록. 라이선스 확인 없음. for_group?에서만 호출되므로 액세스 경로에서 호출하지 않습니다.

enabled_for_group?와 for_group?는 다음과 같이 라우팅합니다.

  • GitLab.com에서는 NamespaceEnrollment.enrolled?(resource).
  • GitLab Self-Managed에서는 InstanceEnrollment.enrolled?.

GitLab.com의 유료 최상위 그룹 예외#

GitLab.com의 최상위 그룹은 액세스를 얻기 위해 등록 행이 필요하지 않습니다. enabled_for_group?가 이를 자동으로 허용하므로, 그룹이 등록하기 전에도 체험판 call-to-action에 접근할 수 있습니다. 명시적인 옵트아웃은 여전히 이 허용보다 우선합니다. NamespaceEnrollment.opted_out?(group)이 true이면 유료 경험 허용이 있더라도 그룹은 사용할 수 없습니다. 이 예외는 GitLab.com의 루트 그룹에만 적용됩니다. GitLab Self-Managed와 루트가 아닌 그룹을 포함한 다른 모든 경우는 단순한 enrolled? 확인으로 돌아갑니다.

가용성이 적용되는 위치#

가용성과 등록은 세 개의 별도 계층에서 확인합니다. 등록 레코드를 제거하는 등의 방법으로 어느 한 계층이라도 비활성화하면, 추가 코드 없이 세 계층 모두에 적용되어야 합니다.

계층 위치
Rails 정책 secrets_manager_enabled(프로젝트) 및 group_secrets_manager_enabled(그룹) 정책 조건이 Availability.for_project?와 Availability.for_group?를 호출합니다.
뷰 렌더링 ee/app/helpers/secrets_management/enrollment_helper.rb의 SecretsManagement::EnrollmentHelper. 뷰를 위해 EE::ApplicationHelper에 믹스인되며, before_action 콜백도 호출할 수 있도록 Projects::SecretsController와 Groups::SecretsController에도 명시적으로 포함됩니다.
CI 러너 페이로드 Ci::BuildRunnerPresenter(ee/app/presenters/ee/ci/build_runner_presenter.rb). project_secrets_manager_payload와 group_secrets_manager_payload는 Availability.for_project? 또는 Availability.for_group?가 false이면 {}를 반환하므로, 네임스페이스를 등록 해제한 뒤 선택된 job은 시크릿을 받지 못합니다. 이미 실행 중인 job은 받은 시크릿을 유지합니다.

헬퍼 메서드는 다음과 같습니다.

메서드 용도
allow_secrets_manager_namespace_enrollment?(namespace) 그룹 설정 페이지에 네임스페이스 등록 토글을 표시할지 여부.
allow_secrets_manager_instance_enrollment? 관리자 설정 페이지에 인스턴스 등록 토글을 표시할지 여부.
secrets_manager_available_for_group?(group) Availability.for_group?와 read_secrets_manager 권한.
secrets_manager_available_for_project?(project) Availability.for_project?와 read_project_secrets_manager 권한.
secrets_manager_available_and_active_for_group?(group) Availability.for_group?와 GroupSecretsManager 레코드가 active?인지 여부. 권한 확인 없음.
secrets_manager_available_and_active_for_project?(project) Availability.for_project?와 ProjectSecretsManager 레코드가 active?인지 여부. 권한 확인 없음.

인가#

등록 자체를 변경할 수 있는 권한은 Secrets Manager를 사용할 수 있는 권한과 별개입니다. 따라서 네임스페이스가 등록되기 전에도 등록 토글이 동작합니다.

권한 대상
create_secrets_manager_enrollment 그룹 Owner(네임스페이스), 인스턴스 관리자(인스턴스).
delete_secrets_manager_enrollment 그룹 Owner(네임스페이스), 인스턴스 관리자(인스턴스).
read_secrets_manager_enrollment 그룹 Owner(네임스페이스), 인스턴스 관리자(인스턴스).

권한 정의는 config/authz/permissions/secrets_manager_enrollment/{create,delete,read}.yml에 있으며, config/authz/roles/owner.yml에서 Owner 권한에 부여됩니다.

그룹의 경우 EE::GroupPolicy는 NamespaceEnrollment.enrollment_allowed?(@subject)가 true일 때만 세 권한을 모두 부여합니다. 이 메서드는 라이선스와 해당 그룹이 라이선스가 있는 GitLab.com 최상위 그룹인지 확인합니다. 인스턴스의 경우 EE::GlobalPolicy는 InstanceEnrollment.enrollment_allowed?가 true일 때 admin에게 세 권한을 모두 활성화합니다.

SecretsManagement::NamespaceEnrollmentPolicy(ee/app/policies/secrets_management/namespace_enrollment_policy.rb)는 등록 대상 네임스페이스의 그룹 정책에 곧바로 위임합니다. namespace_path를 받는 GraphQL 뮤테이션은 Rails authorize 선언 외에 해당 그룹으로 범위를 지정한 authorize_granular_token을 사용합니다. 인스턴스 뮤테이션은 인스턴스 경계로 범위를 지정한 authorize_granular_token을 사용합니다.

감사 이벤트#

enroll과 unenroll을 호출할 때마다 Gitlab::Audit::Auditor.audit으로 감사 이벤트를 만듭니다.

이벤트 범위 발생시키는 곳
secrets_manager_namespace_enroll 그룹 NamespaceEnrollmentService#enroll
secrets_manager_namespace_unenroll 그룹 NamespaceEnrollmentService#unenroll, 그리고 실패한 추가 기능 기록을 롤백할 때
secrets_manager_instance_enroll 인스턴스 InstanceEnrollmentService#enroll
secrets_manager_instance_unenroll 인스턴스 InstanceEnrollmentService#unenroll, 그리고 실패한 추가 기능 기록을 롤백할 때
secrets_manager_add_on_enable 그룹 또는 인스턴스 두 서비스 중 하나의 audit_add_on_conversion. 과금에서 추가 기능을 확인하면 한 번 호출됩니다

인스턴스 범위 이벤트는 scope와 target 모두에 Gitlab::Audit::InstanceScope를 사용합니다. 타입 정의는 config/audit_events/types/secrets_manager_*.yml에 있습니다.

GraphQL#

쿼리#

필드 타입 리졸버
namespaceSecretsManagerEnrollment SecretsManagerEnrollment (namespace, beta) NamespaceEnrollmentResolver
instanceSecretsManagerEnrollment SecretsManagerInstanceEnrollment (enrolled, beta) InstanceEnrollmentResolver

NamespaceEnrollmentResolver는 최상위 그룹 경로에 대해서만 해석합니다. 하위 그룹이나 프로젝트 경로는 null을 반환합니다. 또한 활성화된 행만 반환하므로, 옵트아웃한 그룹은 비활성 상태의 레코드가 아니라 null로 해석됩니다. 이렇게 하면 레코드가 있으면 무조건 「등록됨」으로 취급하는 이전 프론트엔드 코드가 잘못된 양성 표시를 하지 않습니다. 프로젝트나 하위 그룹의 가용성을 확인하려면 대신 secrets_manager_available_for_*? 뷰 헬퍼를 사용합니다.

인스턴스 쿼리 타입은 config/authz/permission_groups/assignable_permissions/secrets_management/secrets_manager_enrollment/read.yml의 할당 가능한 권한을 기반으로 인스턴스 경계의 authorize_granular_token을 선언합니다.

네임스페이스 등록 타입과 등록 뮤테이션 네 개는 이 요구 사항보다 먼저 만들어졌으며 config/authz/graphql/authorization_todo.txt에 나열되어 있습니다. 새 GraphQL 타입은 이 파일에 추가할 수 없습니다.

뮤테이션#

뮤테이션 가드
NamespaceSecretsManagerEnroll create_secrets_manager_enrollment이며 GitLab.com에서만 실행됩니다.
NamespaceSecretsManagerUnenroll delete_secrets_manager_enrollment이며 GitLab.com에서만 실행됩니다.
InstanceSecretsManagerEnroll authorize!(:global)을 통한 can_admin_all_resources?.
InstanceSecretsManagerUnenroll authorize!(:global)을 통한 can_admin_all_resources?.

파일은 ee/app/graphql/mutations/secrets_management/enrollment/ 아래에 있으며 ee/app/graphql/ee/types/mutation_type.rb에 등록됩니다. NamespaceEnroll은 RequiresActiveNamespace concern을 통해 대상 그룹이 보관되었거나 삭제 대기 중이면 뮤테이션도 거부합니다. NamespaceUnenroll은 이 확인을 적용하지 않으므로, 보관되었거나 삭제 대기 중인 그룹도 등록 해제할 수 있습니다.

UI 화면#

  • 네임스페이스 등록 토글은 ee/app/assets/javascripts/pages/projects/shared/permissions/secrets_manager/에 있는 그룹 설정 페이지의 일부입니다.
  • 인스턴스 등록 토글은 관리자 애플리케이션 설정 페이지에 있으며, ee/app/views/admin/application_settings/_secrets_manager_instance_enrollment.html.haml에서 렌더링되고 ee/app/assets/javascripts/admin/application_settings/general/secrets_manager_instance_enrollment/의 Vue 컴포넌트가 뒷받침합니다.

두 토글은 앞에서 설명한 뷰 헬퍼의 allow_secrets_manager_namespace_enrollment?와 allow_secrets_manager_instance_enrollment?로 제어되므로, 등록이 허용되지 않으면 비활성화된 상태로 표시되지 않고 완전히 숨겨집니다.

Secrets Manager 등록

GitLab v19.5
원문 보기

요약

등록은 가용성 게이트 두 가지 중 하나입니다. GitLab.com의 등록은 최상위 그룹 단위입니다. 등록은 단순한 불리언이 아니라 세 가지 상태입니다. NamespaceEnrollment.enrolled?(namespace)와 다른 클래스 쿼리 메서드(opted_out?, beta_enrolled?, add_on_requested?)는 모두 먼저 네임스페이스를 root_ancestor로 해석합니다.

등록은 가용성 게이트 두 가지 중 하나입니다. 등록은 네임스페이스나 인스턴스가 Secrets Manager를 켰는가라는 하나의 질문에 답합니다. 다른 게이트는 native_secrets_management 라이선스입니다. 체험판과 과금 상태에 따라 등록된 네임스페이스가 무엇을 할 수 있는지 결정하는 자격은 별도의 주제입니다. Secrets Manager 이행 및 자격을 참고합니다.

GitLab.com의 네임스페이스 등록#

GitLab.com의 등록은 최상위 그룹 단위입니다. 모델은 ee/app/models/secrets_management/namespace_enrollment.rb의 SecretsManagement::NamespaceEnrollment이며, secrets_manager_namespace_enrollments 테이블이 이를 뒷받침합니다.

칼럼 용도
namespace_id 고유 값. 항상 최상위 그룹입니다.
beta 등록 시점에 설정됩니다. 베타 프로그램을 참고합니다.
disabled_at nil이면 등록된 상태입니다. 타임스탬프는 명시적인 옵트아웃을 나타냅니다.
add_on_requested_at 그룹이 체험판 없이 유료 추가 기능을 구매할 때 설정됩니다. 체험판과 추가 기능을 참고합니다.

등록은 단순한 불리언이 아니라 세 가지 상태입니다.

  • 행이 없음. 그룹이 등록한 적이 없습니다.
  • disabled_at이 nil로 설정된 행. 그룹이 등록되어 있습니다.
  • disabled_at이 설정된 행. 그룹이 명시적으로 옵트아웃했습니다.

NamespaceEnrollment.enrolled?(namespace)와 다른 클래스 쿼리 메서드(opted_out?, beta_enrolled?, add_on_requested?)는 모두 먼저 네임스페이스를 root_ancestor로 해석합니다. 따라서 최상위 그룹으로 호출하든 그 아래의 프로젝트나 하위 그룹으로 호출하든 똑같이 동작합니다.

GitLab Self-Managed의 인스턴스 등록#

GitLab Self-Managed의 등록은 네임스페이스별이 아니라 인스턴스 전체 단위입니다. application_settings의 칼럼 집합이며, ee/app/models/secrets_management/instance_enrollment.rb의 SecretsManagement::InstanceEnrollment를 통해 읽습니다.

칼럼 용도
secrets_manager_instance_enrolled 기본값은 false입니다. true이면 인스턴스가 등록된 상태입니다.
secrets_manager_instance_beta_enrolled 등록 시점에 설정됩니다. 네임스페이스 beta 칼럼과 의미가 같습니다.
secrets_manager_instance_add_on_requested_at 인스턴스가 체험판 없이 유료 추가 기능을 구매할 때 설정됩니다.

InstanceEnrollment.settings는 이 칼럼만 읽고 현재 요청 동안 Gitlab::SafeRequestStore에 캐시합니다. Gitlab::CurrentSettings를 통한 프로세스 수준 캐싱은 CI job 선택에 영향을 주는 검사에는 너무 거칩니다. 이 칼럼에 쓰는 모든 작업은 InstanceEnrollment.expire_settings를 호출하고 Gitlab::CurrentSettings를 만료시켜야 같은 요청의 다음 읽기에서 변경 사항이 보입니다. 이 설정은 REST 애플리케이션 설정 API로 노출되지 않습니다. 아래에서 설명하는 전용 GraphQL 뮤테이션이 이 설정을 바꾸는 유일한 방법입니다.

서비스#

서비스 두 개가 모든 등록 쓰기를 담당합니다. 등록 칼럼을 직접 업데이트하지 않습니다.

서비스 파일
SecretsManagement::NamespaceEnrollmentService ee/app/services/secrets_management/namespace_enrollment_service.rb
SecretsManagement::InstanceEnrollmentService ee/app/services/secrets_management/instance_enrollment_service.rb

두 서비스 모두 감사 추적을 위해 current_user:를 받으며 같은 네 가지 작업을 제공합니다.

메서드 동작
enroll 등록 레코드를 만들거나 다시 활성화합니다. 등록이 허용되지 않거나 이미 등록된 경우 실패합니다.
unenroll 네임스페이스나 인스턴스를 옵트아웃합니다.
enroll_with_add_on_intent 필요하면 등록한 다음 add_on_requested_at을 기록합니다. 유료 추가 기능 구매 흐름에서 사용합니다.
revert_add_on_intent enroll_with_add_on_intent가 변경한 내용을 정확히 되돌립니다. 해당 흐름의 이후 단계가 실패할 때 사용합니다.

NamespaceEnrollmentService#unenroll은 행을 삭제하지 않고 disabled_at을 설정합니다. 저장된 시크릿은 보존되며, 다시 등록하면 유료 추가 기능 의사를 잃지 않고 재개됩니다.

InstanceEnrollmentService#unenroll은 인스턴스 등록이 행이 아니라 칼럼 집합이므로 아무것도 삭제하지 않고 항상 secrets_manager_instance_enrolled를 지웁니다.

이미 등록된 네임스페이스에서 enroll을 호출하거나 이미 옵트아웃한 네임스페이스에서 unenroll을 호출하면 오류 응답을 반환하며 감사 이벤트를 만들지 않습니다. 등록한 적 없는 그룹에서 unenroll을 호출하면 옵트아웃된 행을 만들고 감사 이벤트를 기록하며 성공합니다.

각 서비스는 쓰기마다 SecretsManagement::Entitlement::Resolver.clear_cache로 자격 리졸버 캐시도 지웁니다. 이렇게 하지 않으면 등록이 바뀐 뒤에도 자격 캐시의 TTL(time to live) 동안 CI job 선택이 시크릿 액세스를 계속 허용하거나 거부할 수 있습니다.

가용성과 등록#

모든 가용성 확인은 ee/lib/secrets_management/availability.rb의 SecretsManagement::Availability를 거칩니다. 네임스페이스 등록과 인스턴스 등록 중 무엇을 참조할지 결정하는 곳이기도 하므로, 호출하는 쪽에서 Gitlab.com?으로 직접 분기할 필요가 없습니다.

메서드 확인 대상
for_project?(project) 라이선스와 enabled_for_project?.
for_group?(group) 라이선스와 enabled_for_group?.
for_instance? 라이선스와 InstanceEnrollment.enrolled?.
enabled_for_project?(project) 등록. 라이선스 확인 없음. for_project?에서만 호출되므로 액세스 경로에서 호출하지 않습니다.
enabled_for_group?(group) 아래의 유료 최상위 그룹 예외를 포함한 등록. 라이선스 확인 없음. for_group?에서만 호출되므로 액세스 경로에서 호출하지 않습니다.

enabled_for_group?와 for_group?는 다음과 같이 라우팅합니다.

  • GitLab.com에서는 NamespaceEnrollment.enrolled?(resource).
  • GitLab Self-Managed에서는 InstanceEnrollment.enrolled?.

GitLab.com의 유료 최상위 그룹 예외#

GitLab.com의 최상위 그룹은 액세스를 얻기 위해 등록 행이 필요하지 않습니다. enabled_for_group?가 이를 자동으로 허용하므로, 그룹이 등록하기 전에도 체험판 call-to-action에 접근할 수 있습니다. 명시적인 옵트아웃은 여전히 이 허용보다 우선합니다. NamespaceEnrollment.opted_out?(group)이 true이면 유료 경험 허용이 있더라도 그룹은 사용할 수 없습니다. 이 예외는 GitLab.com의 루트 그룹에만 적용됩니다. GitLab Self-Managed와 루트가 아닌 그룹을 포함한 다른 모든 경우는 단순한 enrolled? 확인으로 돌아갑니다.

가용성이 적용되는 위치#

가용성과 등록은 세 개의 별도 계층에서 확인합니다. 등록 레코드를 제거하는 등의 방법으로 어느 한 계층이라도 비활성화하면, 추가 코드 없이 세 계층 모두에 적용되어야 합니다.

계층 위치
Rails 정책 secrets_manager_enabled(프로젝트) 및 group_secrets_manager_enabled(그룹) 정책 조건이 Availability.for_project?와 Availability.for_group?를 호출합니다.
뷰 렌더링 ee/app/helpers/secrets_management/enrollment_helper.rb의 SecretsManagement::EnrollmentHelper. 뷰를 위해 EE::ApplicationHelper에 믹스인되며, before_action 콜백도 호출할 수 있도록 Projects::SecretsController와 Groups::SecretsController에도 명시적으로 포함됩니다.
CI 러너 페이로드 Ci::BuildRunnerPresenter(ee/app/presenters/ee/ci/build_runner_presenter.rb). project_secrets_manager_payload와 group_secrets_manager_payload는 Availability.for_project? 또는 Availability.for_group?가 false이면 {}를 반환하므로, 네임스페이스를 등록 해제한 뒤 선택된 job은 시크릿을 받지 못합니다. 이미 실행 중인 job은 받은 시크릿을 유지합니다.

헬퍼 메서드는 다음과 같습니다.

메서드 용도
allow_secrets_manager_namespace_enrollment?(namespace) 그룹 설정 페이지에 네임스페이스 등록 토글을 표시할지 여부.
allow_secrets_manager_instance_enrollment? 관리자 설정 페이지에 인스턴스 등록 토글을 표시할지 여부.
secrets_manager_available_for_group?(group) Availability.for_group?와 read_secrets_manager 권한.
secrets_manager_available_for_project?(project) Availability.for_project?와 read_project_secrets_manager 권한.
secrets_manager_available_and_active_for_group?(group) Availability.for_group?와 GroupSecretsManager 레코드가 active?인지 여부. 권한 확인 없음.
secrets_manager_available_and_active_for_project?(project) Availability.for_project?와 ProjectSecretsManager 레코드가 active?인지 여부. 권한 확인 없음.

인가#

등록 자체를 변경할 수 있는 권한은 Secrets Manager를 사용할 수 있는 권한과 별개입니다. 따라서 네임스페이스가 등록되기 전에도 등록 토글이 동작합니다.

권한 대상
create_secrets_manager_enrollment 그룹 Owner(네임스페이스), 인스턴스 관리자(인스턴스).
delete_secrets_manager_enrollment 그룹 Owner(네임스페이스), 인스턴스 관리자(인스턴스).
read_secrets_manager_enrollment 그룹 Owner(네임스페이스), 인스턴스 관리자(인스턴스).

권한 정의는 config/authz/permissions/secrets_manager_enrollment/{create,delete,read}.yml에 있으며, config/authz/roles/owner.yml에서 Owner 권한에 부여됩니다.

그룹의 경우 EE::GroupPolicy는 NamespaceEnrollment.enrollment_allowed?(@subject)가 true일 때만 세 권한을 모두 부여합니다. 이 메서드는 라이선스와 해당 그룹이 라이선스가 있는 GitLab.com 최상위 그룹인지 확인합니다. 인스턴스의 경우 EE::GlobalPolicy는 InstanceEnrollment.enrollment_allowed?가 true일 때 admin에게 세 권한을 모두 활성화합니다.

SecretsManagement::NamespaceEnrollmentPolicy(ee/app/policies/secrets_management/namespace_enrollment_policy.rb)는 등록 대상 네임스페이스의 그룹 정책에 곧바로 위임합니다. namespace_path를 받는 GraphQL 뮤테이션은 Rails authorize 선언 외에 해당 그룹으로 범위를 지정한 authorize_granular_token을 사용합니다. 인스턴스 뮤테이션은 인스턴스 경계로 범위를 지정한 authorize_granular_token을 사용합니다.

감사 이벤트#

enroll과 unenroll을 호출할 때마다 Gitlab::Audit::Auditor.audit으로 감사 이벤트를 만듭니다.

이벤트 범위 발생시키는 곳
secrets_manager_namespace_enroll 그룹 NamespaceEnrollmentService#enroll
secrets_manager_namespace_unenroll 그룹 NamespaceEnrollmentService#unenroll, 그리고 실패한 추가 기능 기록을 롤백할 때
secrets_manager_instance_enroll 인스턴스 InstanceEnrollmentService#enroll
secrets_manager_instance_unenroll 인스턴스 InstanceEnrollmentService#unenroll, 그리고 실패한 추가 기능 기록을 롤백할 때
secrets_manager_add_on_enable 그룹 또는 인스턴스 두 서비스 중 하나의 audit_add_on_conversion. 과금에서 추가 기능을 확인하면 한 번 호출됩니다

인스턴스 범위 이벤트는 scope와 target 모두에 Gitlab::Audit::InstanceScope를 사용합니다. 타입 정의는 config/audit_events/types/secrets_manager_*.yml에 있습니다.

GraphQL#

쿼리#

필드 타입 리졸버
namespaceSecretsManagerEnrollment SecretsManagerEnrollment (namespace, beta) NamespaceEnrollmentResolver
instanceSecretsManagerEnrollment SecretsManagerInstanceEnrollment (enrolled, beta) InstanceEnrollmentResolver

NamespaceEnrollmentResolver는 최상위 그룹 경로에 대해서만 해석합니다. 하위 그룹이나 프로젝트 경로는 null을 반환합니다. 또한 활성화된 행만 반환하므로, 옵트아웃한 그룹은 비활성 상태의 레코드가 아니라 null로 해석됩니다. 이렇게 하면 레코드가 있으면 무조건 「등록됨」으로 취급하는 이전 프론트엔드 코드가 잘못된 양성 표시를 하지 않습니다. 프로젝트나 하위 그룹의 가용성을 확인하려면 대신 secrets_manager_available_for_*? 뷰 헬퍼를 사용합니다.

인스턴스 쿼리 타입은 config/authz/permission_groups/assignable_permissions/secrets_management/secrets_manager_enrollment/read.yml의 할당 가능한 권한을 기반으로 인스턴스 경계의 authorize_granular_token을 선언합니다.

네임스페이스 등록 타입과 등록 뮤테이션 네 개는 이 요구 사항보다 먼저 만들어졌으며 config/authz/graphql/authorization_todo.txt에 나열되어 있습니다. 새 GraphQL 타입은 이 파일에 추가할 수 없습니다.

뮤테이션#

뮤테이션 가드
NamespaceSecretsManagerEnroll create_secrets_manager_enrollment이며 GitLab.com에서만 실행됩니다.
NamespaceSecretsManagerUnenroll delete_secrets_manager_enrollment이며 GitLab.com에서만 실행됩니다.
InstanceSecretsManagerEnroll authorize!(:global)을 통한 can_admin_all_resources?.
InstanceSecretsManagerUnenroll authorize!(:global)을 통한 can_admin_all_resources?.

파일은 ee/app/graphql/mutations/secrets_management/enrollment/ 아래에 있으며 ee/app/graphql/ee/types/mutation_type.rb에 등록됩니다. NamespaceEnroll은 RequiresActiveNamespace concern을 통해 대상 그룹이 보관되었거나 삭제 대기 중이면 뮤테이션도 거부합니다. NamespaceUnenroll은 이 확인을 적용하지 않으므로, 보관되었거나 삭제 대기 중인 그룹도 등록 해제할 수 있습니다.

UI 화면#

  • 네임스페이스 등록 토글은 ee/app/assets/javascripts/pages/projects/shared/permissions/secrets_manager/에 있는 그룹 설정 페이지의 일부입니다.
  • 인스턴스 등록 토글은 관리자 애플리케이션 설정 페이지에 있으며, ee/app/views/admin/application_settings/_secrets_manager_instance_enrollment.html.haml에서 렌더링되고 ee/app/assets/javascripts/admin/application_settings/general/secrets_manager_instance_enrollment/의 Vue 컴포넌트가 뒷받침합니다.

두 토글은 앞에서 설명한 뷰 헬퍼의 allow_secrets_manager_namespace_enrollment?와 allow_secrets_manager_instance_enrollment?로 제어되므로, 등록이 허용되지 않으면 비활성화된 상태로 표시되지 않고 완전히 숨겨집니다.