InfoGrab DocsInfoGrab Docs

Secrets Manager 성능

요약

Secrets Manager 코드는 OpenBao와 CustomersDot라는 두 원격 서비스를 호출합니다. job을 가져올 때 CustomersDot 오류는 로그에 기록되고 빌드는 예약됩니다. 프레젠터는 빌드마다 프로젝트 서버 블록을 한 번 만듭니다.

Secrets Manager 코드는 OpenBao와 CustomersDot라는 두 원격 서비스를 호출합니다. 성능 문제는 대부분 핫 패스(요청마다, CI job마다 실행되는 것처럼 매우 자주 실행되는 코드)에 이 호출을 추가하거나, 시크릿 수에 비례해 늘어나는 작업에서 발생합니다. Secrets Manager 코드를 변경할 때는 이러한 비용을 염두에 둡니다. 일반적인 조언은 머지 리퀘스트 성능 가이드라인을 참조합니다.

핫 패스#

경로 Secrets Manager 작업 비용 제어
CI job 가져오기, EE::Ci::RegisterJobService#secrets_manager_access_denied? gitlab_secrets_manager 시크릿을 요청하는 빌드에 대한 라이선스, 사용 가능 여부, 권한(entitlement) 확인 CustomersDot 호출당 HTTP 제한 시간 1초, 공유 캐시 1분. 오류가 나면 허용합니다(fail open).
러너 페이로드, EE::Ci::BuildRunnerPresenter 사용 가능 여부와 권한 확인, Secrets Manager 조회, CI JWT 발급 확인 결과를 프로젝트당 한 번, 서로 다른 그룹당 한 번 메모이제이션합니다. 같은 1분 캐시. 오류가 나면 차단합니다(fail closed).
사이드바 메뉴 항목, ChecksNavReadCapability 시크릿을 읽을 수 있는 사용자가 프로젝트 또는 그룹 페이지를 렌더링할 때마다 OpenBao 기능 조회 OpenBao 제한 시간 3초, 사용자와 Secrets Manager별 30초 캐시
시크릿 페이지, Projects::SecretsController#check_read_capability! 같은 기능 조회 같은 30초 캐시, 제한 시간 없음
GraphQL 시크릿 목록 및 개수 요청마다 OpenBao LIST 없음

job을 가져올 때 CustomersDot 오류는 로그에 기록되고 빌드는 예약됩니다. 이후 프레젠터가 기본 제한 시간으로 권한을 다시 확인하며, 접근이 거부되면 SecretsManagement::Entitlement::AccessDeniedError를 발생시킵니다. register job 서비스는 이 오류를 secrets_manager_access_denied 실패 사유로 매핑합니다.

프레젠터는 빌드마다 프로젝트 서버 블록을 한 번 만듭니다. 그룹 서버 블록은 그룹 시크릿마다 만들어지므로, 그룹 시크릿마다 새 CI JWT를 발급하고 내부 이벤트를 추적합니다.

러너는 시크릿 값을 OpenBao에서 직접 읽습니다. Rails는 감사 로그 콜백을 통해서만 각 읽기를 확인합니다.

OpenBao 왕복 호출#

모든 요청은 인라인으로 인증하므로, OpenBao는 호출마다 JWT를 검증합니다. 자세한 내용은 Secrets Manager OpenBao 클라이언트 및 인증을 참조합니다.

작업 OpenBao 호출 참고
생성 7 개수 LIST(한도가 0이면 건너뜀), 메타데이터 읽기, 값 쓰기, 메타데이터 쓰기, CI 정책 읽기 및 쓰기, 최종 메타데이터 쓰기
업데이트, 범위 변경 없음 5 또는 6 메타데이터 읽기, 메타데이터 쓰기, 값 쓰기(값이 주어진 경우에만), CI 정책 읽기 및 쓰기, 최종 메타데이터 쓰기
업데이트, 환경 또는 브랜치 변경 7~9 전체 시크릿 LIST와 이전 정책의 삭제 또는 재작성이 추가됩니다
삭제 4 또는 5 메타데이터 읽기, 삭제, 전체 시크릿 LIST, 이어서 정책 삭제 또는 정책 읽기 및 쓰기
목록 1 상세 메타데이터 경로에 대한 LIST 1회, 로테이션 필드를 선택하면 데이터베이스 쿼리 1회 추가
시크릿 하나 읽기 1 로테이션 레코드에 대한 데이터베이스 쿼리가 최대 2회 추가됩니다
개수 1 모든 키의 LIST. 한도 확인은 limit + 1을 전달하므로 OpenBao가 일찍 멈춥니다.
유효 기능 3 로그인, sys/capabilities-self, 이어서 토큰 폐기

목록은 OpenBao에서 페이지로 나뉘지 않습니다. ProjectSecrets::ListService와 GroupSecrets::ListService는 모든 시크릿을 불러오고, GraphQL 연결이 메모리에서 배열을 페이지로 나눕니다. 로테이션이 필요한 시크릿을 나열하는 서비스는 로테이션 레코드와 함께 전체 목록을 불러온 뒤 Ruby에서 필터링하고 정렬합니다.

SecretsManagerClient는 timeout: 옵션을 받지만 시크릿 서비스는 이를 설정하지 않습니다. 이러한 호출은 연결과 읽기에 Net::HTTP 기본값인 60초를 사용합니다. 사이드바의 기능 조회만 제한 시간을 설정합니다.

CI 정책 갱신 비용#

CiPolicies::ProjectSecretRefresher와 CiPolicies::GroupSecretRefresher는 생성, 업데이트, 삭제 때마다 실행됩니다. 동작 방식은 Secrets Manager 서비스를 참조합니다.

  • 정책에 시크릿을 추가하면 전체 액세스 제어 목록(ACL) 정책을 읽고 다시 씁니다. 정책에는 해당 범위의 시크릿마다 두 개의 경로가 있으므로, 정책의 크기는 이를 공유하는 시크릿 수에 따라 늘어납니다.
  • 환경과 브랜치가 바뀌지 않아도 업데이트는 정책을 다시 씁니다.
  • 정책에서 시크릿을 제거하면 count_secrets_for_policy를 호출하며, 이 메서드는 메타데이터와 함께 Secrets Manager의 모든 시크릿을 나열합니다. 따라서 삭제와 범위 변경의 비용은 O(시크릿 수)입니다.

배타적 리스#

시크릿 생성, 업데이트, 삭제는 프로젝트 또는 그룹마다 하나의 리스 키를 공유합니다. 권한 업데이트와 삭제, 프로비저닝, 프로비저닝 해제도 마찬가지입니다. 각 리스에는 아래 표에 나온 제한 시간, 즉 TTL(time to live)이 있습니다. Helpers::ExclusiveLeaseHelper#with_exclusive_lease_for는 retries: 0을 사용하므로, 두 번째 호출자는 즉시 "Another secret operation in progress"를 받습니다. 요청은 대기열에 들어가지 않습니다. 부하 상태에서 하나의 프로젝트나 그룹에 대한 병렬 쓰기는 실패하고, 서로 다른 프로젝트나 그룹에 대한 쓰기는 서로를 차단하지 않습니다.

호출자 리스 TTL
시크릿 및 권한 쓰기 30초(DEFAULT_LEASE_TIMEOUT)
프로비저닝 120초
프로비저닝 해제(BaseDeprovisionService::LEASE_TIMEOUT) 120초

쓰기 하나는 클라이언트 제한 시간 없이 최대 아홉 번 OpenBao를 호출합니다. OpenBao가 멈추면 쓰기가 30초 리스를 넘겨 계속 실행될 수 있고, 그러면 두 번째 쓰기가 시작될 수 있습니다.

대량 처리 경로#

  • 그룹 이전. EE::Groups::TransferService#bulk_initiate_secrets_manager_deprovisions는 GROUP_QUERY_BATCH_SIZE와 PROJECT_QUERY_BATCH_SIZE(둘 다 1000)의 each_batch로 하위 트리를 순회합니다. 각 배치는 bulk_initiate_for_groups와 bulk_initiate_for_projects를 통해 active 상태 Secrets Manager에 delete_all을 한 번 실행합니다. 데이터베이스 트리거가 행마다 태스크를 삽입합니다. 이 코드는 이전 트랜잭션 안에서 실행되므로 Sidekiq job은 큐에 넣지 않습니다. 레코드별 서비스 호출을 사용하면 요청 안에서 하위 항목마다 여러 쿼리와 큐 등록이 한 번씩 실행됩니다.
  • 프로젝트 이전은 레코드 하나의 프로비저닝을 해제합니다.
  • 프로젝트와 그룹 삭제는 ON DELETE CASCADE와 트리거에 의존합니다.
  • 유지 관리 및 리퍼 cron은 태스크를 배치로 처리하고 태스크별로 오류를 격리합니다. 상수는 Secrets Manager 워커 및 정책을 참조합니다.
  • ReconcileNamespaceSecretCountsCronWorker는 Secrets Manager마다 워커 하나를 500개 단위 배치로 큐에 넣으며, 최대 1시간의 무작위 지연으로 분산합니다.
  • EmitSecretsStoredBillableEventCronWorker는 루트 네임스페이스 500개 단위 배치로 bulk_perform_async_with_contexts를 사용합니다.

CustomersDot과 권한#

상태, 캐시, 대체 동작은 Secrets Manager 이행 및 권한을 참조합니다. 성능 측면은 다음과 같습니다.

  • 캐시되지 않은 해석 한 번은 순차적인 HTTP 호출 두 번(체험판 조회, 이어서 컨슈머 해석)을 수행합니다.
  • Gitlab::SubscriptionPortal::Client는 각 응답을 Cache-Control max-age 동안 캐시하며, max-age가 없으면 120초(CDOT_CACHE_FALLBACK_TTL) 동안 캐시합니다. max-age가 0이면 캐시하지 않습니다.
  • job 가져오기와 러너 페이로드 확인은 모두 JOB_PICKUP_CACHE_TTL(1분)로 설정한 cache_ttl을 전달합니다. Rails 정책, 뮤테이션, UI 헬퍼는 자체적인 요청 간 캐시 없이 권한을 해석합니다.
  • 실시간 해석은 매번 마지막으로 확인된 정상 레코드도 Redis에 씁니다.
호출자 호출당 HTTP 제한 시간
기본 Entitlement.for 기능 플래그 뒤에서는 2초, 그렇지 않으면 Gitlab::HTTP 기본값
job 가져오기 확인 1초
secrets_read 이미터 0.25초
뮤테이션의 Entitlement.for! Gitlab::HTTP 기본값

Net::HTTP는 GET에서 읽기 제한 시간 초과를 한 번 재시도하므로, 멈춘 호출은 제한 시간의 약 두 배가 걸릴 수 있습니다.

개수와 한도#

개수 출처 시점
생성 시 한도 확인 limit + 1을 사용한 OpenBao LIST 생성할 때마다
GraphQL 시크릿 개수 OpenBao LIST 요청마다
NamespaceSecretCount 데이터베이스 행 secrets_stored 청구 경로에서만 읽음

ReconcileNamespaceSecretCountWorker는 OpenBao LIST 한 번과 삽입 또는 업데이트 한 번으로 NamespaceSecretCount를 갱신합니다. 생성과 삭제 후, 그리고 일일 cron에서 실행됩니다. 예약된 job을 포함해 네임스페이스별로 중복이 제거되며, 데이터베이스 상태 신호가 나빠지면 실행을 미룹니다.

감사 로그와 청구 이벤트#

OpenBao는 자체 요청에 응답하기 전에 POST /internal/secrets_manager/audit_logs의 응답을 기다립니다. 이 엔드포인트는 요청 유형 줄을 건너뛰고 AuditLogWorker를 큐에 넣습니다.

  • AuditLogWorker는 긴급도가 낮고, 원시 페이로드를 기준으로 중복이 제거되며, 감사 테이블이 정상이 아니면 실행을 미룹니다.
  • 처리된 읽기마다 청구 메타데이터를 위해 권한을 해석하므로 CustomersDot을 호출할 수 있습니다.
  • 이 엔드포인트는 1MB 이상의 본문을 거부합니다.

속도 제한#

권한 갱신 뮤테이션은 자체 애플리케이션 속도 제한이 있는 유일한 Secrets Manager 엔드포인트이며, secrets_manager_entitlement_refresh로 사용자당 분당 10회입니다. 각 갱신은 CustomersDot 캐시를 건너뛰고 실시간 CustomersDot 호출을 두 번 수행합니다. 그 밖의 Secrets Manager 엔드포인트나 뮤테이션에는 자체 속도 제한이 없습니다. 액세스 토큰 REST 엔드포인트는 JWT를 로컬에서 발급하며 OpenBao를 호출하지 않습니다.

성능 검토 체크리스트#

  1. 변경 사항이 CI job 가져오기, 러너 페이로드, 사이드바에 OpenBao 또는 CustomersDot 호출을 추가하는지 확인합니다.
  2. 지연 시간에 민감한 경로의 새 호출이 제한 시간을 설정하는지, 그리고 의도적으로 fail open 또는 fail closed로 동작하는지 확인합니다.
  3. 변경 사항이 시크릿, 프로젝트, 그룹을 순회하는 반복문 안에 호출이나 데이터베이스 쿼리를 추가하는지 확인합니다.
  4. 새 쓰기 경로가 리프레셔의 전체 LIST처럼 시크릿 수에 비례해 늘어나는 작업을 추가하는지 확인합니다.
  5. 새 쓰기가 엔터티별 리스를 사용하는지, 그리고 리스 TTL보다 충분히 일찍 끝날 수 있는지 확인합니다.
  6. 핫 패스의 새 권한 호출자가 cache_ttl을 전달하는지, 그리고 대응하는 뮤테이션이 캐시를 지우는지 확인합니다.
  7. 대량 처리 경로가 일정한 배치 크기의 each_batch를 사용하며, 트랜잭션 안에서 레코드별 서비스 호출을 피하는지 확인합니다.
  8. 새 개수가 목적에 맞는 출처를 읽는지 확인합니다. 한도에는 OpenBao를, 청구에는 NamespaceSecretCount를 사용합니다.

Secrets Manager 성능

GitLab v19.5
원문 보기

요약

Secrets Manager 코드는 OpenBao와 CustomersDot라는 두 원격 서비스를 호출합니다. job을 가져올 때 CustomersDot 오류는 로그에 기록되고 빌드는 예약됩니다. 프레젠터는 빌드마다 프로젝트 서버 블록을 한 번 만듭니다.

Secrets Manager 코드는 OpenBao와 CustomersDot라는 두 원격 서비스를 호출합니다. 성능 문제는 대부분 핫 패스(요청마다, CI job마다 실행되는 것처럼 매우 자주 실행되는 코드)에 이 호출을 추가하거나, 시크릿 수에 비례해 늘어나는 작업에서 발생합니다. Secrets Manager 코드를 변경할 때는 이러한 비용을 염두에 둡니다. 일반적인 조언은 머지 리퀘스트 성능 가이드라인을 참조합니다.

핫 패스#

경로 Secrets Manager 작업 비용 제어
CI job 가져오기, EE::Ci::RegisterJobService#secrets_manager_access_denied? gitlab_secrets_manager 시크릿을 요청하는 빌드에 대한 라이선스, 사용 가능 여부, 권한(entitlement) 확인 CustomersDot 호출당 HTTP 제한 시간 1초, 공유 캐시 1분. 오류가 나면 허용합니다(fail open).
러너 페이로드, EE::Ci::BuildRunnerPresenter 사용 가능 여부와 권한 확인, Secrets Manager 조회, CI JWT 발급 확인 결과를 프로젝트당 한 번, 서로 다른 그룹당 한 번 메모이제이션합니다. 같은 1분 캐시. 오류가 나면 차단합니다(fail closed).
사이드바 메뉴 항목, ChecksNavReadCapability 시크릿을 읽을 수 있는 사용자가 프로젝트 또는 그룹 페이지를 렌더링할 때마다 OpenBao 기능 조회 OpenBao 제한 시간 3초, 사용자와 Secrets Manager별 30초 캐시
시크릿 페이지, Projects::SecretsController#check_read_capability! 같은 기능 조회 같은 30초 캐시, 제한 시간 없음
GraphQL 시크릿 목록 및 개수 요청마다 OpenBao LIST 없음

job을 가져올 때 CustomersDot 오류는 로그에 기록되고 빌드는 예약됩니다. 이후 프레젠터가 기본 제한 시간으로 권한을 다시 확인하며, 접근이 거부되면 SecretsManagement::Entitlement::AccessDeniedError를 발생시킵니다. register job 서비스는 이 오류를 secrets_manager_access_denied 실패 사유로 매핑합니다.

프레젠터는 빌드마다 프로젝트 서버 블록을 한 번 만듭니다. 그룹 서버 블록은 그룹 시크릿마다 만들어지므로, 그룹 시크릿마다 새 CI JWT를 발급하고 내부 이벤트를 추적합니다.

러너는 시크릿 값을 OpenBao에서 직접 읽습니다. Rails는 감사 로그 콜백을 통해서만 각 읽기를 확인합니다.

OpenBao 왕복 호출#

모든 요청은 인라인으로 인증하므로, OpenBao는 호출마다 JWT를 검증합니다. 자세한 내용은 Secrets Manager OpenBao 클라이언트 및 인증을 참조합니다.

작업 OpenBao 호출 참고
생성 7 개수 LIST(한도가 0이면 건너뜀), 메타데이터 읽기, 값 쓰기, 메타데이터 쓰기, CI 정책 읽기 및 쓰기, 최종 메타데이터 쓰기
업데이트, 범위 변경 없음 5 또는 6 메타데이터 읽기, 메타데이터 쓰기, 값 쓰기(값이 주어진 경우에만), CI 정책 읽기 및 쓰기, 최종 메타데이터 쓰기
업데이트, 환경 또는 브랜치 변경 7~9 전체 시크릿 LIST와 이전 정책의 삭제 또는 재작성이 추가됩니다
삭제 4 또는 5 메타데이터 읽기, 삭제, 전체 시크릿 LIST, 이어서 정책 삭제 또는 정책 읽기 및 쓰기
목록 1 상세 메타데이터 경로에 대한 LIST 1회, 로테이션 필드를 선택하면 데이터베이스 쿼리 1회 추가
시크릿 하나 읽기 1 로테이션 레코드에 대한 데이터베이스 쿼리가 최대 2회 추가됩니다
개수 1 모든 키의 LIST. 한도 확인은 limit + 1을 전달하므로 OpenBao가 일찍 멈춥니다.
유효 기능 3 로그인, sys/capabilities-self, 이어서 토큰 폐기

목록은 OpenBao에서 페이지로 나뉘지 않습니다. ProjectSecrets::ListService와 GroupSecrets::ListService는 모든 시크릿을 불러오고, GraphQL 연결이 메모리에서 배열을 페이지로 나눕니다. 로테이션이 필요한 시크릿을 나열하는 서비스는 로테이션 레코드와 함께 전체 목록을 불러온 뒤 Ruby에서 필터링하고 정렬합니다.

SecretsManagerClient는 timeout: 옵션을 받지만 시크릿 서비스는 이를 설정하지 않습니다. 이러한 호출은 연결과 읽기에 Net::HTTP 기본값인 60초를 사용합니다. 사이드바의 기능 조회만 제한 시간을 설정합니다.

CI 정책 갱신 비용#

CiPolicies::ProjectSecretRefresher와 CiPolicies::GroupSecretRefresher는 생성, 업데이트, 삭제 때마다 실행됩니다. 동작 방식은 Secrets Manager 서비스를 참조합니다.

  • 정책에 시크릿을 추가하면 전체 액세스 제어 목록(ACL) 정책을 읽고 다시 씁니다. 정책에는 해당 범위의 시크릿마다 두 개의 경로가 있으므로, 정책의 크기는 이를 공유하는 시크릿 수에 따라 늘어납니다.
  • 환경과 브랜치가 바뀌지 않아도 업데이트는 정책을 다시 씁니다.
  • 정책에서 시크릿을 제거하면 count_secrets_for_policy를 호출하며, 이 메서드는 메타데이터와 함께 Secrets Manager의 모든 시크릿을 나열합니다. 따라서 삭제와 범위 변경의 비용은 O(시크릿 수)입니다.

배타적 리스#

시크릿 생성, 업데이트, 삭제는 프로젝트 또는 그룹마다 하나의 리스 키를 공유합니다. 권한 업데이트와 삭제, 프로비저닝, 프로비저닝 해제도 마찬가지입니다. 각 리스에는 아래 표에 나온 제한 시간, 즉 TTL(time to live)이 있습니다. Helpers::ExclusiveLeaseHelper#with_exclusive_lease_for는 retries: 0을 사용하므로, 두 번째 호출자는 즉시 "Another secret operation in progress"를 받습니다. 요청은 대기열에 들어가지 않습니다. 부하 상태에서 하나의 프로젝트나 그룹에 대한 병렬 쓰기는 실패하고, 서로 다른 프로젝트나 그룹에 대한 쓰기는 서로를 차단하지 않습니다.

호출자 리스 TTL
시크릿 및 권한 쓰기 30초(DEFAULT_LEASE_TIMEOUT)
프로비저닝 120초
프로비저닝 해제(BaseDeprovisionService::LEASE_TIMEOUT) 120초

쓰기 하나는 클라이언트 제한 시간 없이 최대 아홉 번 OpenBao를 호출합니다. OpenBao가 멈추면 쓰기가 30초 리스를 넘겨 계속 실행될 수 있고, 그러면 두 번째 쓰기가 시작될 수 있습니다.

대량 처리 경로#

  • 그룹 이전. EE::Groups::TransferService#bulk_initiate_secrets_manager_deprovisions는 GROUP_QUERY_BATCH_SIZE와 PROJECT_QUERY_BATCH_SIZE(둘 다 1000)의 each_batch로 하위 트리를 순회합니다. 각 배치는 bulk_initiate_for_groups와 bulk_initiate_for_projects를 통해 active 상태 Secrets Manager에 delete_all을 한 번 실행합니다. 데이터베이스 트리거가 행마다 태스크를 삽입합니다. 이 코드는 이전 트랜잭션 안에서 실행되므로 Sidekiq job은 큐에 넣지 않습니다. 레코드별 서비스 호출을 사용하면 요청 안에서 하위 항목마다 여러 쿼리와 큐 등록이 한 번씩 실행됩니다.
  • 프로젝트 이전은 레코드 하나의 프로비저닝을 해제합니다.
  • 프로젝트와 그룹 삭제는 ON DELETE CASCADE와 트리거에 의존합니다.
  • 유지 관리 및 리퍼 cron은 태스크를 배치로 처리하고 태스크별로 오류를 격리합니다. 상수는 Secrets Manager 워커 및 정책을 참조합니다.
  • ReconcileNamespaceSecretCountsCronWorker는 Secrets Manager마다 워커 하나를 500개 단위 배치로 큐에 넣으며, 최대 1시간의 무작위 지연으로 분산합니다.
  • EmitSecretsStoredBillableEventCronWorker는 루트 네임스페이스 500개 단위 배치로 bulk_perform_async_with_contexts를 사용합니다.

CustomersDot과 권한#

상태, 캐시, 대체 동작은 Secrets Manager 이행 및 권한을 참조합니다. 성능 측면은 다음과 같습니다.

  • 캐시되지 않은 해석 한 번은 순차적인 HTTP 호출 두 번(체험판 조회, 이어서 컨슈머 해석)을 수행합니다.
  • Gitlab::SubscriptionPortal::Client는 각 응답을 Cache-Control max-age 동안 캐시하며, max-age가 없으면 120초(CDOT_CACHE_FALLBACK_TTL) 동안 캐시합니다. max-age가 0이면 캐시하지 않습니다.
  • job 가져오기와 러너 페이로드 확인은 모두 JOB_PICKUP_CACHE_TTL(1분)로 설정한 cache_ttl을 전달합니다. Rails 정책, 뮤테이션, UI 헬퍼는 자체적인 요청 간 캐시 없이 권한을 해석합니다.
  • 실시간 해석은 매번 마지막으로 확인된 정상 레코드도 Redis에 씁니다.
호출자 호출당 HTTP 제한 시간
기본 Entitlement.for 기능 플래그 뒤에서는 2초, 그렇지 않으면 Gitlab::HTTP 기본값
job 가져오기 확인 1초
secrets_read 이미터 0.25초
뮤테이션의 Entitlement.for! Gitlab::HTTP 기본값

Net::HTTP는 GET에서 읽기 제한 시간 초과를 한 번 재시도하므로, 멈춘 호출은 제한 시간의 약 두 배가 걸릴 수 있습니다.

개수와 한도#

개수 출처 시점
생성 시 한도 확인 limit + 1을 사용한 OpenBao LIST 생성할 때마다
GraphQL 시크릿 개수 OpenBao LIST 요청마다
NamespaceSecretCount 데이터베이스 행 secrets_stored 청구 경로에서만 읽음

ReconcileNamespaceSecretCountWorker는 OpenBao LIST 한 번과 삽입 또는 업데이트 한 번으로 NamespaceSecretCount를 갱신합니다. 생성과 삭제 후, 그리고 일일 cron에서 실행됩니다. 예약된 job을 포함해 네임스페이스별로 중복이 제거되며, 데이터베이스 상태 신호가 나빠지면 실행을 미룹니다.

감사 로그와 청구 이벤트#

OpenBao는 자체 요청에 응답하기 전에 POST /internal/secrets_manager/audit_logs의 응답을 기다립니다. 이 엔드포인트는 요청 유형 줄을 건너뛰고 AuditLogWorker를 큐에 넣습니다.

  • AuditLogWorker는 긴급도가 낮고, 원시 페이로드를 기준으로 중복이 제거되며, 감사 테이블이 정상이 아니면 실행을 미룹니다.
  • 처리된 읽기마다 청구 메타데이터를 위해 권한을 해석하므로 CustomersDot을 호출할 수 있습니다.
  • 이 엔드포인트는 1MB 이상의 본문을 거부합니다.

속도 제한#

권한 갱신 뮤테이션은 자체 애플리케이션 속도 제한이 있는 유일한 Secrets Manager 엔드포인트이며, secrets_manager_entitlement_refresh로 사용자당 분당 10회입니다. 각 갱신은 CustomersDot 캐시를 건너뛰고 실시간 CustomersDot 호출을 두 번 수행합니다. 그 밖의 Secrets Manager 엔드포인트나 뮤테이션에는 자체 속도 제한이 없습니다. 액세스 토큰 REST 엔드포인트는 JWT를 로컬에서 발급하며 OpenBao를 호출하지 않습니다.

성능 검토 체크리스트#

  1. 변경 사항이 CI job 가져오기, 러너 페이로드, 사이드바에 OpenBao 또는 CustomersDot 호출을 추가하는지 확인합니다.
  2. 지연 시간에 민감한 경로의 새 호출이 제한 시간을 설정하는지, 그리고 의도적으로 fail open 또는 fail closed로 동작하는지 확인합니다.
  3. 변경 사항이 시크릿, 프로젝트, 그룹을 순회하는 반복문 안에 호출이나 데이터베이스 쿼리를 추가하는지 확인합니다.
  4. 새 쓰기 경로가 리프레셔의 전체 LIST처럼 시크릿 수에 비례해 늘어나는 작업을 추가하는지 확인합니다.
  5. 새 쓰기가 엔터티별 리스를 사용하는지, 그리고 리스 TTL보다 충분히 일찍 끝날 수 있는지 확인합니다.
  6. 핫 패스의 새 권한 호출자가 cache_ttl을 전달하는지, 그리고 대응하는 뮤테이션이 캐시를 지우는지 확인합니다.
  7. 대량 처리 경로가 일정한 배치 크기의 each_batch를 사용하며, 트랜잭션 안에서 레코드별 서비스 호출을 피하는지 확인합니다.
  8. 새 개수가 목적에 맞는 출처를 읽는지 확인합니다. 한도에는 OpenBao를, 청구에는 NamespaceSecretCount를 사용합니다.