유출된 비밀에 대한 자동 응답
GitLab 비밀 감지는 특정 유형의 유출된 비밀을 발견했을 때 자동으로 응답합니다.
자동 응답은 다음을 수행할 수 있습니다:
- 비밀을 자동으로 취소합니다.
- 비밀을 발급한 파트너에게 알립니다. 파트너는 비밀을 취소하거나 소유자에게 알리거나 남용에 대해 보호할 수 있습니다.
지원되는 비밀 유형 및 작업
GitLab은 다음 유형의 비밀에 대한 자동 응답을 지원합니다:
비밀 유형 | 수행되는 작업 | GitLab.com에서 지원 | 자체 관리에서 지원 |
---|---|---|---|
GitLab 개인 액세스 토큰 | 즉시 토큰 취소, 소유자에게 이메일 발송 | ✅ | ✅ 15.9 이상 |
Amazon Web Services (AWS) IAM 액세스 키 | AWS에 알림 | ✅ | ⚙ |
Google Cloud 서비스 계정 키, API 키, 및 OAuth 클라이언트 비밀 | Google Cloud에 알림 | ✅ | ⚙ |
Postman API 키 | Postman에 알림; Postman 키 소유자에게 알림 | ✅ | ⚙ |
구성 요소 기호
- ✅ - 기본적으로 사용 가능
- ⚙ - 토큰 취소 API를 사용한 수동 통합 필요
기능 가용성
- 비기본 브랜치에서 활성화됨 GitLab 15.11.
자격 증명은 비밀 감지가 발견했을 때만 후처리됩니다:
- 공개 프로젝트에서, 공개적으로 노출된 자격 증명은 증가된 위협을 초래하기 때문입니다. 개인 프로젝트로의 확대는 문제 391379에서 고려 중입니다.
- GitLab Ultimate이 포함된 프로젝트에서, 기술적인 이유로. 모든 계층으로의 확대는 문제 391763에서 추적됩니다.
고급 아키텍처
이 다이어그램은 후처리 후크가 GitLab 애플리케이션에서 비밀을 어떻게 취소하는지를 설명합니다:
-
비밀 감지 작업이 있는 파이프라인이 완료되어 스캔 보고서를 생성합니다(1).
-
보고서는 서비스 클래스에 의해 처리됩니다(2). 이 서비스 클래스는 토큰 취소가 가능할 경우 비동기 워커를 예약합니다.
-
비동기 워커는(3) 외부에 배포된 HTTP 서비스와 통신합니다(4 및 5) 자동으로 취소할 수 있는 비밀의 종류를 결정합니다.
-
워커는(6 및 7) GitLab Token Revocation API가 취소할 수 있는 탐지된 비밀 목록을 전송합니다.
-
GitLab Token Revocation API는 각 취소 가능한 토큰을 해당 공급자의 파트너 API로 전송합니다. 더 많은 정보는 GitLab Token Revocation API 문서를 참조하세요.
유출된 자격 증명 알림을 위한 파트너 프로그램
GitLab은 자격 증명이 GitLab.com의 공개 저장소에 유출될 때 파트너에게 알립니다.
클라우드 또는 SaaS 제품을 운영하고 있으며 이러한 알림을 받는 데 관심이 있다면, 에픽 4944에서 자세히 알아보세요.
파트너는 GitLab Token Revocation API에 의해 호출되는 파트너 API를 구현해야 합니다.
파트너 API 구현
파트너 API는 GitLab Token Revocation API와 통합되어 유출된 토큰 취소 요청을 수신하고 응답합니다.
서비스는 아이덴포텐트하고 속도 제한이 적용된 공개 접근 가능 HTTP API여야 합니다.
서비스에 대한 요청은 하나 이상의 유출된 토큰과 요청 본문의 서명이 포함된 헤더를 포함할 수 있습니다.
우리는 이 서명을 사용하여 수신 요청을 검증할 것을 강력히 권장합니다. 이는 GitLab에서 발송된 진정한 요청임을 입증하는 데 도움이 됩니다.
아래의 다이어그램은 유출된 토큰을 수신, 검증 및 취소하는 데 필요한 단계를 자세히 설명합니다:
- GitLab Token Revocation API가 (1) 취소 요청을 파트너 API에 전송합니다. 요청에는 요청 본문의 공개 키 식별자 및 서명이 포함된 헤더가 있습니다.
- 파트너 API는 GitLab에 (2) 공개 키 목록을 요청합니다. 응답 (3)은 키 회전의 경우 여러개의 공개 키를 포함할 수 있으며, 요청 헤더에 있는 식별자로 필터링해야 합니다.
- 파트너 API는 공개 키를 사용하여 실제 요청 본문에 대해 서명을 검증합니다 (4).
- 파트너 API는 유출된 토큰을 처리하며, 이는 자동 취소를 포함할 수 있습니다 (5).
- 파트너 API는 적절한 HTTP 상태 코드로 GitLab Token Revocation API에 응답합니다 (6):
- 성공적인 응답 코드(HTTP 200~299)는 파트너가 요청을 수신하고 처리했음을 확인합니다.
- 오류 코드(HTTP 400 이상)는 GitLab Token Revocation API가 요청을 재시도하게 만듭니다.
취소 요청
이 JSON 스키마 문서는 취소 요청의 본문을 설명합니다:
{
"type": "array",
"items": {
"description": "유출된 토큰",
"type": "object",
"properties": {
"type": {
"description": "토큰의 유형입니다. 이는 공급업체별로 다르며 귀하의 취소 서비스에 맞게 사용자 정의할 수 있습니다.",
"type": "string",
"examples": [
"my_api_token"
]
},
"token": {
"description": "비밀 감지 분석기가 일치시킨 하위 문자열입니다. 대부분의 경우, 이는 전체 토큰 자체입니다.",
"type": "string",
"examples": [
"XXXXXXXXXXXXXXXX"
]
},
"url": {
"description": "유출된 토큰이 감지된 GitLab에서 호스팅되는 원본 파일의 URL입니다.",
"type": "string",
"examples": [
"https://gitlab.example.com/some-repo/-/raw/abcdefghijklmnop/compromisedfile1.java"
]
}
}
}
}
예시:
[{"type": "my_api_token", "token": "XXXXXXXXXXXXXXXX", "url": "https://example.com/some-repo/-/raw/abcdefghijklmnop/compromisedfile1.java"}]
이 예시에서, 비밀 감지가 my_api_token
의 인스턴스가 유출되었음을 확인했습니다.
토큰의 값은 귀하에게 제공되며, 유출된 토큰이 포함된 파일의 원시 콘텐츠에 대한 공개 접근 가능 URL도 함께 제공됩니다.
요청은 두 개의 특수 헤더를 포함합니다:
헤더 | 유형 | 설명 |
---|---|---|
Gitlab-Public-Key-Identifier |
string | 이 요청을 서명하기 위해 사용된 키 쌍의 고유 식별자입니다. 주로 키 회전을 지원하는 데 사용됩니다. |
Gitlab-Public-Key-Signature |
string | 요청 본문의 base64로 인코딩된 서명입니다. |
이 헤더를 GitLab 공개 키 엔드포인트와 함께 사용하여 취소 요청이 진짜인지 확인할 수 있습니다.
공개 키 엔드포인트
GitLab은 폐기 요청을 검증하는 데 사용되는 공개 키를 검색하기 위한 공개 접근 가능 엔드포인트를 유지합니다. 요청 시 엔드포인트를 제공할 수 있습니다.
이 JSON 스키마 문서는 공개 키 엔드포인트의 응답 본문을 설명합니다:
{
"type": "object",
"properties": {
"public_keys": {
"description": "토큰 폐기 요청에 서명하는 데 사용되는 GitLab에서 관리하는 공개 키의 배열입니다.",
"type": "array",
"items": {
"type": "object",
"properties": {
"key_identifier": {
"description": "키 쌍에 대한 고유 식별자입니다. Gitlab-Public-Key-Identifier 헤더의 값과 일치시킵니다.",
"type": "string"
},
"key": {
"description": "공개 키의 값입니다.",
"type": "string"
},
"is_current": {
"description": "키가 현재 활성 상태이며 새로운 요청에 서명하는지 여부입니다.",
"type": "boolean"
}
}
}
}
}
}
예:
{
"public_keys": [
{
"key_identifier": "6917d7584f0fa65c8c33df5ab20f54dfb9a6e6ae",
"key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEN05/VjsBwWTUGYMpijqC5pDtoLEf\nuWz2CVZAZd5zfa/NAlSFgWRDdNRpazTARndB2+dHDtcHIVfzyVPNr2aznw==\n-----END PUBLIC KEY-----\n",
"is_current": true
}
]
}
요청 검증하기
Gitlab-Public-Key-Signature
헤더를 요청 본문과 검증하여 폐기 요청이 진본인지 확인할 수 있습니다. 위의 API 응답에서 가져온 해당 공개 키를 사용합니다. 우리는 ECDSA를 사용하여 SHA256 해싱을 통해 서명을 생성하고, 이를 헤더 값에 base64로 인코딩합니다.
아래의 Python 스크립트는 서명을 검증하는 방법을 보여줍니다. 이는 암호화 작업을 위한 인기 있는 pyca/cryptography 모듈을 사용합니다:
import hashlib
import base64
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.serialization import load_pem_public_key
from cryptography.hazmat.primitives.asymmetric import ec
public_key = str.encode("") # 공개 키 엔드포인트에서 얻은 값
signature_header = "" # `Gitlab-Public-Key-Signature` 헤더에서 얻은 값
request_body = str.encode(r'') # 폐기 요청 본문에서 얻은 값
pk = load_pem_public_key(public_key)
decoded_signature = base64.b64decode(signature_header)
pk.verify(decoded_signature, request_body, ec.ECDSA(hashes.SHA256())) # 실패 시 예외 발생
print("서명 확인 완료!")
주요 단계는 다음과 같습니다:
-
사용 중인 암호화 라이브러리에 적합한 형식으로 공개 키를 로드합니다.
-
Gitlab-Public-Key-Signature
헤더 값의 base64를 디코딩합니다. -
ECDSA와 SHA256 해싱을 지정하여 디코딩된 서명에 대해 본문을 검증합니다.