감사 이벤트 개발 가이드라인
GitLab v19.1이 가이드는 감사 이벤트가 동작하는 방식과 새로운 감사 이벤트를 계측하는 방법에 대한 개요를 제공합니다. 감사 이벤트는 GitLab owner와 관리자가 애플리케이션 전반에서 수행된 중요한 작업 기록을 확인하기 위한 도구입니다.
이 가이드는 감사 이벤트가 동작하는 방식과 새로운 감사 이벤트를 계측하는 방법에 대한 개요를 제공합니다.
감사 이벤트란 무엇인가요?#
감사 이벤트는 GitLab owner와 관리자가 애플리케이션 전반에서 수행된 중요한 작업 기록을 확인하기 위한 도구입니다.
감사 이벤트가 되어서는 안 되는 것은 무엇인가요?#
어떤 이벤트든 감사 이벤트를 트리거할 수 있지만, 모든 이벤트가 감사 이벤트가 되어야 하는 것은 아닙니다. 일반적으로 감사 이벤트로 적합하지 않은 이벤트는 다음과 같습니다:
-
특정 사용자에게 귀속될 수 없는 이벤트.
-
관리자 또는 owner 페르소나에게 특별히 관심 대상이 아닌 이벤트.
-
제품 기능 도입에 대한 추적 정보인 이벤트.
-
방향 페이지의 지금 계획되지 않은 사항에 대한 논의에서 다루어지는 이벤트.
질문이 있으시면 @gitlab-org/software-supply-chain-security/compliance에 연락하여 감사 이벤트 또는 다른 접근 방식이 이벤트에 가장 적합한지 확인하세요.
감사 이벤트 스키마#
감사 이벤트를 계측하려면 다음 속성들을 제공해야 합니다:
| 속성 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
| name | String | false | 감사할 작업 이름. 이벤트 유형을 나타냄. 오류 추적에 사용됨 |
| author | User | true | 변경을 작성한 사용자. 내부 사용자일 수 있음. 예를 들어, 휴면 프로젝트 삭제 감사 이벤트는 GitLab-Admin-Bot이 작성함 |
| scope | User, Project, Group, or Instance | true | 감사 이벤트가 속하는 범위 |
| target | Object | true | 감사 대상 객체 |
| message | String | true | 작업을 설명하는 메시지 (번역되지 않음) |
| created_at | DateTime | false | 작업이 발생한 시간. 기본값은 DateTime.current |
새로운 감사 이벤트 계측 방법#
-
새 감사 이벤트를 위한 YAML 타입 정의를 생성합니다.
-
Gitlab::Audit::Auditor.audit을 호출하고 액션 블록을 전달합니다.
다음과 같은 감사 이벤트 계측 방법은 더 이상 사용되지 않습니다:
-
ee/lib/ee/audit/에 새 클래스를 만들고AuditEventService를 확장하기 -
성공적인 작업 후
AuditEventService호출하기
Gitlab::Audit::Auditor 서비스를 사용하면 두 가지 방법으로 감사 이벤트를 계측할 수 있습니다:
-
여러 이벤트를 위한 블록 사용.
-
단일 이벤트를 위한 표준 메서드 호출 사용.
블록을 사용하여 여러 이벤트 기록하기#
이 방법은 이벤트가 호출 스택 깊은 곳에서 발생할 때 사용할 수 있습니다.
예를 들어, 사용자가 머지 리퀘스트 승인 규칙을 업데이트할 때 여러 감사 이벤트를 기록할 수 있습니다. 이 사용자 흐름의 일부로, 승인자와 승인 그룹 모두에 대한 변경 사항을 감사하고 싶습니다. 시작 서비스(예: MergeRequestRuleUpdateService)에서 execute 호출을 다음과 같이 감쌀 수 있습니다:
# in the initiating service
audit_context = {
name: 'update_merge_approval_rule',
author: current_user,
scope: project_alpha,
target: merge_approval_rule,
message: 'Attempted to update an approval rule'
}
::Gitlab::Audit::Auditor.audit(audit_context) do
service.execute
end
모델(예: ApprovalProjectRule)에서는 모델 콜백(예: after_save 또는 after_add)에 감사 이벤트를 푸시할 수 있습니다.
# in the model
include Auditable
def audit_add(model)
push_audit_event('Added an approver on Security rule')
end
def audit_remove(model)
push_audit_event('Removed an approver on Security rule')
end
이 방법은 비동기적이거나 여러 프로세스에 걸쳐 있는 작업(예: 백그라운드 job)은 지원하지 않습니다.
표준 메서드 호출을 사용하여 단일 이벤트 기록하기#
이 방법을 사용하면 단일 감사 이벤트를 기록할 수 있으며 더 적은 구성 요소가 관련됩니다.
if merge_approval_rule.save
audit_context = {
name: 'create_merge_approval_rule',
author: current_user,
scope: project_alpha,
target: merge_approval_rule,
message: 'Created a new approval rule',
created_at: DateTime.current # Useful for pre-dating an audit event when created asynchronously.
}
::Gitlab::Audit::Auditor.audit(audit_context)
end
데이터 볼륨 고려 사항#
모든 감사 이벤트는 데이터베이스에 저장되므로, 새로운 감사 이벤트에서 생성될 것으로 예상되는 데이터의 양과 생성 속도를 고려하세요. 데이터베이스에 많은 데이터를 생성하는 새로운 감사 이벤트의 경우, 스트리밍 전용 감사 이벤트를 추가하는 것을 고려하세요. 이에 대해 질문이 있으시면 이슈나 머지 리퀘스트에서 @gitlab-org/govern/compliance/backend에 핑을 보내세요.
감사 이벤트 계측 흐름#
감사 이벤트를 계측하는 두 가지 방법은 서로 다른 흐름을 가집니다.
블록을 사용하여 여러 이벤트 기록하기#
작업 블록을 Gitlab::Audit::Auditor로 감싸면, 작업이 시작될 때 사용 가능한 초기 감사 컨텍스트(즉, author, scope, target) 객체를 캡처합니다.
체인의 상호작용 클래스에서 Auditable 믹스인과 함께 추가적인 계측이 필요하며, 이를 통해 Gitlab::Audit::EventQueue를 통해 감사 이벤트 큐에 감사 이벤트를 추가합니다.
EventQueue는 SafeRequestStore를 통해 로컬 스레드에 저장되었다가, Gitlab::Audit::Auditor에서 감사 이벤트를 기록할 때 추출됩니다.
skinparam shadowing false skinparam BoxPadding 10 skinparam ParticipantPadding 20
participant "Instrumented Class" as A participant "Audit::Auditor" as A1 #LightBlue participant "Audit::EventQueue" as B #LightBlue participant "Interacted Class" as C participant "AuditEvent" as D
A->A1: audit { block } activate A1 A1->B: begin! A1->C: block.call activate A1 #FFBBBB activate C C-->B: push [ message ] C-->A1: true deactivate A1 deactivate C A1->B: read activate A1 #FFBBBB activate B B-->A1: [ messages ] deactivate B A1->D: bulk_insert! deactivate A1 A1->B: end! A1-->A: deactivate A1
표준 메서드 호출을 사용하여 단일 이벤트 기록하기#
이 방법은 더 직관적인 흐름을 가지며, EventQueue와 로컬 스레드에 의존하지 않습니다.
skinparam shadowing false skinparam BoxPadding 10 skinparam ParticipantPadding 20
participant "Instrumented Class" as A participant "Audit::Auditor" as B #LightBlue participant "AuditEvent" as C
A->B: audit activate B B->C: bulk_insert! B-->A: deactivate B
데이터베이스에 기록하는 것 외에도, 이러한 이벤트는 로그 파일에도 기록됩니다.
이벤트 타입 정의#
History
- GitLab 15.4에서 도입됨.
모든 새로운 감사 이벤트는 config/audit_events/types/ 또는 ee/config/audit_events/types/에 저장된 타입 정의를 가져야 하며, 이는 GitLab의 모든 감사 가능한 이벤트에 대한 단일 진실 공급원(Single Source Of Truth, SSOT)을 포함합니다.
새로운 감사 이벤트 타입 추가하기#
새로운 감사 이벤트 타입을 추가하려면:
- YAML 정의를 생성합니다. 다음 방법 중 하나를 선택할 수 있습니다:
bin/audit-event-type CLI를 사용하여 YAML 정의를 자동으로 생성합니다.
-
수동으로
config/audit_events/types/에 이벤트 타입 이름과 일치하는 파일 이름으로 새 파일을 생성합니다. 예를 들어, 사용자가 프로젝트에 추가될 때 트리거되는 이벤트 타입의 정의는config/audit_events/types/project_add_user.yml에 저장될 수 있습니다. -
config/audit_events/types/type_schema.json에 정의된 스키마를 준수하는 내용을 파일에 추가합니다. -
Gitlab::Audit::Auditor에 대한 모든 호출이 파일에 정의된name을 사용하도록 합니다.
스키마#
| 필드 | 필수 여부 | 설명 |
|---|---|---|
| name | yes | 이벤트 유형을 설명하는 고유한 소문자 언더스코어 이름. 파일 이름과 일치해야 함 |
| description | yes | 이 이벤트가 트리거되는 방식에 대한 사람이 읽을 수 있는 설명 |
| group | yes | 이 감사 이벤트를 도입한 그룹 이름. 예: manage::compliance |
| introduced_by_issue | yes | 이 타입의 추가를 제안한 이슈 URL |
| introduced_by_mr | yes | 이 새 타입을 추가한 MR URL |
| milestone | yes | 이 타입이 추가된 마일스톤 |
| saved_to_database | yes | 이벤트를 데이터베이스와 JSON 로그에 저장할지 여부 표시 |
| streamed | yes | 이벤트를 외부 서비스로 스트리밍해야 하는지 여부 표시 (구성된 경우) |
| scope | yes | 이 감사 이벤트 타입을 사용할 수 있는 범위 목록. Project, User, Group, Instance 중 하나 이상을 포함하는 배열이어야 함 |
문서 생성하기#
감사 이벤트 타입 문서는 자동으로 생성되어 GitLab 문서 사이트의 해당 페이지에 게시됩니다.
새로운 감사 이벤트 타입을 추가하는 경우, 문서를 업데이트하려면
gitlab:audit_event_types:compile_docs Rake 태스크를
실행합니다:
bundle exec rake gitlab:audit_event_types:compile_docs
문서가 최신 상태인지 확인하려면
gitlab:audit_event_types:check_docs Rake 태스크를
실행합니다:
bundle exec rake gitlab:audit_event_types:check_docs
이벤트 스트리밍#
엔티티가 Group 또는 Project인 모든 이벤트는 감사 로그에 기록되고, 하나 이상의 이벤트 스트리밍 대상으로 스트리밍됩니다. 엔티티가 다음과 같을 때:
-
Group이면, 이벤트는 그룹의 루트 상위 항목의 이벤트 스트리밍 대상으로 스트리밍됩니다. -
Project이면, 이벤트는 프로젝트의 루트 상위 항목의 이벤트 스트리밍 대상으로 스트리밍됩니다.
GitLab 데이터베이스에 저장되지 않는 스트리밍 전용 이벤트를 추가할 수 있습니다. 스트리밍 전용 이벤트는 주로 많은 양의 데이터를 생성하는 작업에 사용됩니다. 예시는 이 머지 리퀘스트를 참조하세요. 이 기능은 활발하게 개발 중입니다. 기능 개발에 대한 업데이트는 상위 에픽을 팔로우하세요.
I18N과 감사 이벤트 :message 속성#
감사 이벤트 메시지는 의도적으로 번역하지 않습니다. 번역된 메시지는 데이터베이스에 저장되어 사용자의 로케일 설정에 관계없이 사용자에게 제공되기 때문입니다.
예를 들어, 인증된 사용자의 로케일을 사용하여 감사 이벤트 메시지를 기록하고 해당 대상에서 사용하는 언어와 다른 언어로 외부 스트리밍 대상에 메시지를 스트리밍할 수 있습니다. 이는 사용자에게 혼란을 줄 수 있습니다.