InfoGrab DocsInfoGrab Docs

Secrets Manager 로컬 설정

요약

이 페이지는 GDK에서 Secrets Manager를 설정해 기능을 로컬에서 개발하고 테스트하는 과정을 안내합니다. 이 설정은 백엔드 작업용입니다. Secrets Manager UI는 재설계 중이므로, 이 페이지는 UI 단계 대신 Rails 콘솔을 사용합니다.

이 페이지는 GDK에서 Secrets Manager를 설정해 기능을 로컬에서 개발하고 테스트하는 과정을 안내합니다. 기능이 어떻게 구성되어 있는지는 Secrets Manager 개발 가이드라인을 참조합니다.

이 설정은 백엔드 작업용입니다. 프론트엔드만 작업한다면 OpenBao 없이 일반 GDK에서 프론트엔드 스펙을 실행할 수 있습니다. 자세한 내용은 Secrets Manager 프론트엔드 개발을 참조합니다.

Secrets Manager UI는 재설계 중이므로, 이 페이지는 UI 단계 대신 Rails 콘솔을 사용합니다. 콘솔 서비스는 안정적이며, UI가 가리는 오류도 확인할 수 있습니다. 진행 중인 설계는 gitlab-org/gitlab#605033을 참조합니다. 이 이슈는 비공개이며 GitLab 팀 멤버 권한이 필요합니다.

사전 요구 사항#

  • 동작하는 GDK.
  • Premium 또는 Ultimate 라이선스가 있는 GitLab Enterprise Edition. Secrets Manager에는 native_secrets_management 라이선스 기능이 필요합니다.
  • 인스턴스 URL(예: http://gdk.test:3000)에서 HTTP를 제공하는 GDK. OpenBao는 해당 URL에서 OIDC 디스커버리 문서를 가져와 GitLab JWT를 검증하므로, GitLab이 요청을 처리하지 않으면 프로비저닝이 실패합니다.

1단계: GDK에서 OpenBao 활성화#

gdk config set openbao.enabled true
gdk reconfigure
gdk start openbao

GDK는 업스트림 릴리스가 아니라 GitLab 패치가 포함된 내부 빌드로 OpenBao를 빌드합니다. 바이너리는 <gdk-root>/openbao/bin/bao에 생성됩니다.

CLI를 사용하려면 셸 프로필에 다음을 추가합니다.

export BAO_ADDR='http://gdk.test:8200'
export PATH="<gdk-root>/openbao/bin:$PATH"

감사 로그 스트리밍과 관리자 액세스를 포함한 OpenBao 전체 레퍼런스는 GDK의 OpenBao를 참조합니다.

2단계: 인스턴스 등록#

등록은 새로 합류한 개발자가 가장 자주 놓치는 단계입니다.

GDK는 GitLab Self-Managed로 동작하므로, Secrets Manager 사용 가능 여부는 인스턴스 등록에 달려 있습니다. secrets_manager_instance_enrolled 애플리케이션 설정의 기본값은 false입니다. OpenBao가 실행 중이어도 Secrets Manager는 사용할 수 없는 상태로 남습니다.

3단계의 시드 Rake 태스크가 등록을 대신 수행하므로, 이 단계는 프로젝트를 수동으로 프로비저닝할 때 중요합니다.

Rails 콘솔에서 등록합니다.

user = User.find_by_username('root')
SecretsManagement::InstanceEnrollmentService.new(current_user: user).enroll

GDK가 GitLab.com을 시뮬레이션한다면 대신 최상위 그룹을 등록합니다.

group = Group.find_by_full_path('your-root-group')
SecretsManagement::NamespaceEnrollmentService.new(group, current_user: user).enroll

두 서비스 모두 여러 번 실행해도 안전하며, 잘못된 배포 유형은 거부합니다. 네임스페이스 등록은 GitLab.com에서만 동작하고, 인스턴스 등록은 GitLab Self-Managed에서만 동작합니다.

3단계: 동작하는 환경 시딩#

동작하는 환경을 가장 빠르게 얻는 방법은 시드 Rake 태스크입니다. 이 태스크는 루트 네임스페이스 아래에 하위 그룹과 프로젝트를 만들고, 그룹과 프로젝트의 Secrets Manager를 프로비저닝하며, 샘플 시크릿을 추가합니다. 인스턴스 등록도 대신 수행합니다.

bundle exec rake "gitlab:secrets_management:seed[ROOT_NAMESPACE_ID]"

다음 사항에 유의합니다.

  • 이 태스크는 개발 환경에서만 실행됩니다.
  • ROOT_NAMESPACE_ID를 기존 최상위 그룹의 ID로 바꿉니다.
  • 이 태스크는 root 사용자를 사용하며, root가 없으면 첫 번째 관리자를 사용하고 해당 사용자를 그룹의 Owner로 추가합니다.
  • 프로비저닝은 동기적으로 실행되므로 Sidekiq을 기다릴 필요가 없습니다.
  • 등록 방식은 GDK 모드를 따릅니다. 이 태스크는 GDK가 GitLab.com을 시뮬레이션하면 네임스페이스를, 그렇지 않으면 인스턴스를 등록합니다.

이 태스크는 루트 네임스페이스 아래에 다음 계층을 만듭니다.

  • subgroup-a에는 project-a1과 project-a2가 있고, subgroup-a1에는 project-a1a가 있습니다.
  • subgroup-b에는 project-b1이 있고, subgroup-b1에는 project-b1x가 있습니다.
  • project-top1은 루트 네임스페이스 바로 아래에 있습니다.

4단계: 설정 확인#

Rails 콘솔에서 시드된 프로젝트에 대해 두 가지 사용 가능 여부 조건이 모두 통과하는지 확인합니다.

project = Project.find_by_full_path('your-root-group/subgroup-a/project-a1')

SecretsManagement::Availability.for_project?(project) # => true
project.secrets_manager.status                        # => "active"

for_project?가 false를 반환하면 조건을 하나씩 확인합니다.

project.licensed_feature_available?(:native_secrets_management) # license
Gitlab::CurrentSettings.secrets_manager_instance_enrolled        # enrollment

그런 다음 시드된 시크릿을 나열합니다.

user = User.find_by_username('root')
result = SecretsManagement::ProjectSecrets::ListService.new(project, user).execute
result.payload[:secrets].map(&:name)

Rails 콘솔에서 수동으로 프로비저닝#

시더를 실행하지 않고 특정 프로젝트를 프로비저닝하려면 이 방법을 사용합니다.

project = Project.find_by_full_path('your-group/your-project')
user = User.find_by_username('root')
project.add_owner(user) unless project.member?(user)

result = SecretsManagement::ProjectSecretsManagers::InitializeService.new(project, user).execute
secrets_manager = result.payload[:project_secrets_manager]

# Run provisioning now instead of waiting for the background worker.
SecretsManagement::ProjectSecretsManagers::ProvisionService.new(secrets_manager, user).execute

secrets_manager.reload.status # => "active"

시크릿을 만듭니다.

result = SecretsManagement::ProjectSecrets::CreateService.new(project, user).execute(
  name: 'MY_SECRET',
  value: 'super-secret-value',
  description: 'Test secret for local development',
  environment: '*',
  branch: '*'
)

result.success? # => true

그룹은 GroupSecretsManagers 및 GroupSecrets 서비스 네임스페이스로 같은 패턴을 사용합니다. 그룹 시크릿은 branch 대신 protected 파라미터를 받습니다.

독립 실행형 rails runner 스크립트에는 상관 관계 ID가 필요합니다. OpenBao 인가 프로그램이 correlation_id 클레임을 읽기 때문입니다. 호출을 다음과 같이 감쌉니다.

Labkit::Correlation::CorrelationId.use_id('local-testing') do
  # your Secrets Manager calls
end

웹 서버를 거치는 요청은 상관 관계 ID가 자동으로 부여되므로, 이 내용은 스크립트와 콘솔 세션에만 적용됩니다.

OpenBao 직접 확인#

디버깅하는 동안 OpenBao 상태를 살펴보려면 관리자 로그인을 켤 수 있습니다. 이를 위해 먼저 OpenBao 데이터를 초기화해야 합니다.

gdk stop openbao
gdk reset-openbao-data
gdk config set openbao.admin_enabled true
gdk reconfigure
gdk start openbao

그런 다음 로그인합니다.

export BAO_ADDR="http://$(gdk config get openbao.__listen)"
bao login -method=userpass username=admin password=$(cat <gdk-root>/openbao/admin-password.txt)

로컬 데이터 초기화#

gdk stop openbao
gdk reset-openbao-data
gdk start openbao

이 명령은 OpenBao 상태를 지웁니다. 초기화한 뒤에는 시드 태스크를 다시 실행하는 등의 방법으로 프로젝트와 그룹을 다시 프로비저닝합니다.

문제 해결#

Secrets Manager를 사용할 수 없음#

SecretsManagement::Availability.for_project?가 false를 반환합니다. 4단계에 나온 것처럼 조건을 하나씩 확인합니다. GDK에서는 인스턴스가 등록되지 않은 경우가 가장 흔한 원인입니다. 2단계를 참조합니다.

프로비저닝이 인증 또는 키 세트 오류로 실패함#

OpenBao가 GitLab OIDC 디스커버리 문서를 가져오지 못했습니다. GitLab이 인스턴스 URL에서 HTTP를 제공하고 있는지 확인한 뒤 다시 시도합니다. 브라우저에서 http://gdk.test:3000/을 열어 보면 빠르게 확인할 수 있습니다.

OpenBao와 통신할 때 연결이 거부됨#

OpenBao가 실행 중이 아닙니다. gdk start openbao를 실행하고 gdk tail openbao에서 오류를 확인합니다.

Secrets Manager가 프로비저닝 상태에서 멈춤#

백그라운드 워커가 작업을 끝내지 못했습니다. 앞에서 설명한 대로 Rails 콘솔에서 프로비저닝 서비스를 직접 실행하면 실제 오류를 확인할 수 있습니다.

다른 시크릿 작업이 진행 중임#

배타적 리스가 아직 유지되고 있습니다. 만료될 때까지 기다리거나 리스를 취소합니다.

lease_key = "project_secret_operation:project_#{project.id}"
Gitlab::ExclusiveLease.cancel(lease_key, Gitlab::ExclusiveLease.get_uuid(lease_key))

프로비저닝 중 경로가 이미 사용 중임#

이 메시지는 보통 문제가 없습니다. 시크릿 엔진 또는 인증 엔진이 이미 마운트되어 있었고, 프로비저닝 서비스가 이를 처리합니다.

Secrets Manager 로컬 설정

GitLab v19.5
원문 보기

요약

이 페이지는 GDK에서 Secrets Manager를 설정해 기능을 로컬에서 개발하고 테스트하는 과정을 안내합니다. 이 설정은 백엔드 작업용입니다. Secrets Manager UI는 재설계 중이므로, 이 페이지는 UI 단계 대신 Rails 콘솔을 사용합니다.

이 페이지는 GDK에서 Secrets Manager를 설정해 기능을 로컬에서 개발하고 테스트하는 과정을 안내합니다. 기능이 어떻게 구성되어 있는지는 Secrets Manager 개발 가이드라인을 참조합니다.

이 설정은 백엔드 작업용입니다. 프론트엔드만 작업한다면 OpenBao 없이 일반 GDK에서 프론트엔드 스펙을 실행할 수 있습니다. 자세한 내용은 Secrets Manager 프론트엔드 개발을 참조합니다.

Secrets Manager UI는 재설계 중이므로, 이 페이지는 UI 단계 대신 Rails 콘솔을 사용합니다. 콘솔 서비스는 안정적이며, UI가 가리는 오류도 확인할 수 있습니다. 진행 중인 설계는 gitlab-org/gitlab#605033을 참조합니다. 이 이슈는 비공개이며 GitLab 팀 멤버 권한이 필요합니다.

사전 요구 사항#

  • 동작하는 GDK.
  • Premium 또는 Ultimate 라이선스가 있는 GitLab Enterprise Edition. Secrets Manager에는 native_secrets_management 라이선스 기능이 필요합니다.
  • 인스턴스 URL(예: http://gdk.test:3000)에서 HTTP를 제공하는 GDK. OpenBao는 해당 URL에서 OIDC 디스커버리 문서를 가져와 GitLab JWT를 검증하므로, GitLab이 요청을 처리하지 않으면 프로비저닝이 실패합니다.

1단계: GDK에서 OpenBao 활성화#

gdk config set openbao.enabled true
gdk reconfigure
gdk start openbao

GDK는 업스트림 릴리스가 아니라 GitLab 패치가 포함된 내부 빌드로 OpenBao를 빌드합니다. 바이너리는 <gdk-root>/openbao/bin/bao에 생성됩니다.

CLI를 사용하려면 셸 프로필에 다음을 추가합니다.

export BAO_ADDR='http://gdk.test:8200'
export PATH="<gdk-root>/openbao/bin:$PATH"

감사 로그 스트리밍과 관리자 액세스를 포함한 OpenBao 전체 레퍼런스는 GDK의 OpenBao를 참조합니다.

2단계: 인스턴스 등록#

등록은 새로 합류한 개발자가 가장 자주 놓치는 단계입니다.

GDK는 GitLab Self-Managed로 동작하므로, Secrets Manager 사용 가능 여부는 인스턴스 등록에 달려 있습니다. secrets_manager_instance_enrolled 애플리케이션 설정의 기본값은 false입니다. OpenBao가 실행 중이어도 Secrets Manager는 사용할 수 없는 상태로 남습니다.

3단계의 시드 Rake 태스크가 등록을 대신 수행하므로, 이 단계는 프로젝트를 수동으로 프로비저닝할 때 중요합니다.

Rails 콘솔에서 등록합니다.

user = User.find_by_username('root')
SecretsManagement::InstanceEnrollmentService.new(current_user: user).enroll

GDK가 GitLab.com을 시뮬레이션한다면 대신 최상위 그룹을 등록합니다.

group = Group.find_by_full_path('your-root-group')
SecretsManagement::NamespaceEnrollmentService.new(group, current_user: user).enroll

두 서비스 모두 여러 번 실행해도 안전하며, 잘못된 배포 유형은 거부합니다. 네임스페이스 등록은 GitLab.com에서만 동작하고, 인스턴스 등록은 GitLab Self-Managed에서만 동작합니다.

3단계: 동작하는 환경 시딩#

동작하는 환경을 가장 빠르게 얻는 방법은 시드 Rake 태스크입니다. 이 태스크는 루트 네임스페이스 아래에 하위 그룹과 프로젝트를 만들고, 그룹과 프로젝트의 Secrets Manager를 프로비저닝하며, 샘플 시크릿을 추가합니다. 인스턴스 등록도 대신 수행합니다.

bundle exec rake "gitlab:secrets_management:seed[ROOT_NAMESPACE_ID]"

다음 사항에 유의합니다.

  • 이 태스크는 개발 환경에서만 실행됩니다.
  • ROOT_NAMESPACE_ID를 기존 최상위 그룹의 ID로 바꿉니다.
  • 이 태스크는 root 사용자를 사용하며, root가 없으면 첫 번째 관리자를 사용하고 해당 사용자를 그룹의 Owner로 추가합니다.
  • 프로비저닝은 동기적으로 실행되므로 Sidekiq을 기다릴 필요가 없습니다.
  • 등록 방식은 GDK 모드를 따릅니다. 이 태스크는 GDK가 GitLab.com을 시뮬레이션하면 네임스페이스를, 그렇지 않으면 인스턴스를 등록합니다.

이 태스크는 루트 네임스페이스 아래에 다음 계층을 만듭니다.

  • subgroup-a에는 project-a1과 project-a2가 있고, subgroup-a1에는 project-a1a가 있습니다.
  • subgroup-b에는 project-b1이 있고, subgroup-b1에는 project-b1x가 있습니다.
  • project-top1은 루트 네임스페이스 바로 아래에 있습니다.

4단계: 설정 확인#

Rails 콘솔에서 시드된 프로젝트에 대해 두 가지 사용 가능 여부 조건이 모두 통과하는지 확인합니다.

project = Project.find_by_full_path('your-root-group/subgroup-a/project-a1')

SecretsManagement::Availability.for_project?(project) # => true
project.secrets_manager.status                        # => "active"

for_project?가 false를 반환하면 조건을 하나씩 확인합니다.

project.licensed_feature_available?(:native_secrets_management) # license
Gitlab::CurrentSettings.secrets_manager_instance_enrolled        # enrollment

그런 다음 시드된 시크릿을 나열합니다.

user = User.find_by_username('root')
result = SecretsManagement::ProjectSecrets::ListService.new(project, user).execute
result.payload[:secrets].map(&:name)

Rails 콘솔에서 수동으로 프로비저닝#

시더를 실행하지 않고 특정 프로젝트를 프로비저닝하려면 이 방법을 사용합니다.

project = Project.find_by_full_path('your-group/your-project')
user = User.find_by_username('root')
project.add_owner(user) unless project.member?(user)

result = SecretsManagement::ProjectSecretsManagers::InitializeService.new(project, user).execute
secrets_manager = result.payload[:project_secrets_manager]

# Run provisioning now instead of waiting for the background worker.
SecretsManagement::ProjectSecretsManagers::ProvisionService.new(secrets_manager, user).execute

secrets_manager.reload.status # => "active"

시크릿을 만듭니다.

result = SecretsManagement::ProjectSecrets::CreateService.new(project, user).execute(
  name: 'MY_SECRET',
  value: 'super-secret-value',
  description: 'Test secret for local development',
  environment: '*',
  branch: '*'
)

result.success? # => true

그룹은 GroupSecretsManagers 및 GroupSecrets 서비스 네임스페이스로 같은 패턴을 사용합니다. 그룹 시크릿은 branch 대신 protected 파라미터를 받습니다.

독립 실행형 rails runner 스크립트에는 상관 관계 ID가 필요합니다. OpenBao 인가 프로그램이 correlation_id 클레임을 읽기 때문입니다. 호출을 다음과 같이 감쌉니다.

Labkit::Correlation::CorrelationId.use_id('local-testing') do
  # your Secrets Manager calls
end

웹 서버를 거치는 요청은 상관 관계 ID가 자동으로 부여되므로, 이 내용은 스크립트와 콘솔 세션에만 적용됩니다.

OpenBao 직접 확인#

디버깅하는 동안 OpenBao 상태를 살펴보려면 관리자 로그인을 켤 수 있습니다. 이를 위해 먼저 OpenBao 데이터를 초기화해야 합니다.

gdk stop openbao
gdk reset-openbao-data
gdk config set openbao.admin_enabled true
gdk reconfigure
gdk start openbao

그런 다음 로그인합니다.

export BAO_ADDR="http://$(gdk config get openbao.__listen)"
bao login -method=userpass username=admin password=$(cat <gdk-root>/openbao/admin-password.txt)

로컬 데이터 초기화#

gdk stop openbao
gdk reset-openbao-data
gdk start openbao

이 명령은 OpenBao 상태를 지웁니다. 초기화한 뒤에는 시드 태스크를 다시 실행하는 등의 방법으로 프로젝트와 그룹을 다시 프로비저닝합니다.

문제 해결#

Secrets Manager를 사용할 수 없음#

SecretsManagement::Availability.for_project?가 false를 반환합니다. 4단계에 나온 것처럼 조건을 하나씩 확인합니다. GDK에서는 인스턴스가 등록되지 않은 경우가 가장 흔한 원인입니다. 2단계를 참조합니다.

프로비저닝이 인증 또는 키 세트 오류로 실패함#

OpenBao가 GitLab OIDC 디스커버리 문서를 가져오지 못했습니다. GitLab이 인스턴스 URL에서 HTTP를 제공하고 있는지 확인한 뒤 다시 시도합니다. 브라우저에서 http://gdk.test:3000/을 열어 보면 빠르게 확인할 수 있습니다.

OpenBao와 통신할 때 연결이 거부됨#

OpenBao가 실행 중이 아닙니다. gdk start openbao를 실행하고 gdk tail openbao에서 오류를 확인합니다.

Secrets Manager가 프로비저닝 상태에서 멈춤#

백그라운드 워커가 작업을 끝내지 못했습니다. 앞에서 설명한 대로 Rails 콘솔에서 프로비저닝 서비스를 직접 실행하면 실제 오류를 확인할 수 있습니다.

다른 시크릿 작업이 진행 중임#

배타적 리스가 아직 유지되고 있습니다. 만료될 때까지 기다리거나 리스를 취소합니다.

lease_key = "project_secret_operation:project_#{project.id}"
Gitlab::ExclusiveLease.cancel(lease_key, Gitlab::ExclusiveLease.get_uuid(lease_key))

프로비저닝 중 경로가 이미 사용 중임#

이 메시지는 보통 문제가 없습니다. 시크릿 엔진 또는 인증 엔진이 이미 마운트되어 있었고, 프로비저닝 서비스가 이를 처리합니다.