审计事件流

  • 引入于 14.5 版本,功能标志名为 ff_external_audit_events_namespace,默认禁用。
  • 于 14.7 版本适用于 SaaS,在私有化部署版上默认启用。
  • 功能标志 ff_external_audit_events_namespace 移除于 14.8 版本。
  • 为了更好地服务中国企业用户,极狐GitLab 自 15.0 版本开始,将 Stream Audit Event 功能从旗舰版降入专业版。而 GitLab CE 与 EE 版本中,该功能依旧为旗舰版。
  • 子组事件记录引入于 15.2 版本。

用户可以为顶级群组设置 HTTP 端点,接收有关该群组、其中子组和项目的所有审计事件作为结构化 JSON。

顶级群组所有者可以在第三方系统中管理他们的审计日志。任何可以接收结构化 JSON 数据的服务都可以用作端点。

note系统可以多次将单个事件流传输到同一目的地。使用有效负载中的 id 键,针对传入数据进行重复数据删除。

添加新的事件流目的地

caution事件流目的地将接收所有审计事件数据,其中可能包括敏感信息,确保您信任目标端点。

使用 GitLab UI

至少具有群组所有者角色的用户可以为其添加事件流目的地:

  1. 在顶部栏上,选择 菜单 > 群组 并找到您的群组。
  2. 在左侧边栏中,选择 安全与合规 > 审计事件
  3. 在主区域,选择 事件流 选项卡。
    • 当目的地列表为空时,选择 添加事件流,显示添加目的地的部分。
    • 当目的地列表不为空时,选择 事件流 选项卡下的 ,显示添加目的地的部分。
  4. 输入目的地 URL 并选择 添加

在以下情况下启用事件流:

  • 不显示警告。
  • 添加的端点显示在 UI 中。

使用 API

要启用事件流并添加目的地,至少具有群组所有者角色的用户必须在 GraphQL API 中使用 externalAuditEventDestinationCreate mutation。

mutation {
  externalAuditEventDestinationCreate(input: { destinationUrl: "https://mydomain.io/endpoint/ingest", groupPath: "my-group" } ) {
    errors
    externalAuditEventDestination {
      destinationUrl
      verificationToken
      group {
        name
      }
    }
  }
}

以下情况,将启用事件流:

  • 返回的 errors 对象为空。
  • API 响应 200 OK

列出流目的地

至少具有群组所有者角色的用户可以列出事件流目的地。

使用 GitLab UI

引入于 14.9 版本

至少具有群组所有者角色的用户可以列出事件流目的地:

  1. 在顶部栏上,选择 菜单 > 群组 并找到您的组。
  2. 在左侧边栏中,选择 安全与合规 > 审计事件
  3. 在主区域,选择 事件流 选项卡。

使用 API

至少具有群组所有者角色的用户可以随时使用 externalAuditEventDestinations 查询类,查看事件流目的地列表。

query {
  group(fullPath: "my-group") {
    id
    externalAuditEventDestinations {
      nodes {
        destinationUrl
        verificationToken
        id
      }
    }
  }
}

如果结果列表为空,则不会为该群组启用审计事件流。

删除流目的地

至少具有群组所有者角色的用户可以使用 deleteAuditEventDestinations mutation 类,删除事件流目的地。

成功删除最后一个目的地后,将为该群组禁用事件流。

使用 GitLab UI

引入于 14.9 版本

群组的所有者角色可以删除事件流目的地。

  1. 在顶部栏上,选择 菜单 > 群组 并找到您的组。
  2. 在左侧边栏中,选择 安全与合规 > 审计事件
  3. 在主区域,选择 事件流 选项卡。
  4. 选择每一项右侧的

外部流目的地在以下情况下被删除:

  • 不显示警告。
  • 删除的端点不显示在 UI 中。

使用 API

通过指定 ID 删除事件流传输目标。通过列出事件流目的地的详细信息获取所需的 ID。

mutation {
  externalAuditEventDestinationDestroy(input: { id: destination }) {
    errors
  }
}

在以下情况下删除目的地:

  • 返回的 errors 对象为空。
  • API 响应为 200 OK

自定义 HTTP headers

  • API 引入于 15.1 版本,功能标志为 streaming_audit_event_headers。默认禁用。
  • API 在 SaaS 版和私有化部署版上启用于 15.2 版本。
  • UI 引入于 15.2 版本,功能标志custom_headers_streaming_audit_events_ui。默认禁用。
在私有化部署版上,默认情况下此功能的 API 可用。要隐藏该功能,请让管理员禁用功能标志 streaming_audit_event_headers。 在 SaaS 上,此功能的 API 可用。

每个流传输目标最多可以包含 20 个自定义 HTTP header,其中包含每个流传输事件。

添加自定义 HTTP headers

使用 API 或 UI 添加自定义 HTTP headers。您可以通过列出群组的外部审计目的地,来获取目的地 ID。

使用 API

群组所有者可以使用 GraphQL auditEventsStreamingHeadersCreate mutation 添加 HTTP header。

mutation {
  auditEventsStreamingHeadersCreate(input: { destinationId: "gid://gitlab/AuditEvents::ExternalAuditEventDestination/24601", key: "foo", value: "bar" }) {
    errors
  }
}

如果返回的 errors 对象为空,则创建 header。

使用 UI

在私有化部署版上,此功能的 UI 默认不可用。要按群组使其可用,询问管理员启用功能标志 custom_headers_streaming_audit_events_ui。在 SaaS 版上,此功能的 UI 不可用。此功能的 UI 尚未准备好用于生产。

至少具有群组所有者角色的用户可以为其添加事件流目的地和自定义 HTTP 标头:

  1. 在顶部栏上,选择 菜单 > 群组 并找到您的群组。
  2. 在左侧边栏中,选择 安全与合规 > 审计事件
  3. 在主区域,选择 事件流 选项卡。
    • 当目的地列表为空时,选择 添加事件流,显示用于添加目的地的部分。
    • 当目的地列表不为空时,选择 ,显示用于添加目的地部分。
  4. 输入要添加的目的地 URL。
  5. 找到 自定义 HTTP header 表。
  6. Header 列中,添加 header 的名称。
  7. 列中,添加 header 的值。
  8. 忽略 启用 复选框,因为它不起作用。
  9. 根据需要输入尽可能多的名称和值对。当您为 header 输入唯一名称和值时,表格中会自动出现一个新行。每个端点最多可以添加 20 个 header。
  10. 填写完所有 header 后,选择 添加,添加新端点。

在以下情况下,说明成功启用了事件流:

  • 不显示警告。
  • 添加的端点显示在 UI 中。

更新自定义 HTTP headers

引入于 15.2 版本。

群组所有者可以使用 GraphQL auditEventsStreamingHeadersCreate mutation 更新 HTTP header。

mutation {
  auditEventsStreamingHeadersUpdate(input: { headerId: "gid://gitlab/AuditEvents::Streaming::Header/24255", key: "new-foo", value: "new-bar" }) {
    errors
  }
}

删除自定义 HTTP headers

群组所有者可以使用 GraphQL auditEventsStreamingHeadersDestroy mutation 删除 HTTP header。您可以通过列出群组的所有自定义 header,获取 header ID。

mutation {
  auditEventsStreamingHeadersDestroy(input: { headerId: "gid://gitlab/AuditEvents::Streaming::Header/1" }) {
    errors
  }
}

如果返回的 errors 对象为空,则删除 header。

列出所有自定义 headers

使用 API 或 UI 列出所有自定义 HTTP header。

使用 API

您可以使用 GraphQL externalAuditEventDestinations 查询列出顶级群组的所有自定义 header 及其值和 ID。此查询返回的 ID 值是您需要传递给 deletion mutation 的值。

query {
  group(fullPath: "your-group") {
    id
    externalAuditEventDestinations {
      nodes {
        destinationUrl
        id
        headers {
          nodes {
            key
            value
            id
          }
        }
      }
    }
  }
}

使用 UI

在私有化部署版上,此功能的 UI 默认不可用。要按群组使其可用,询问管理员启用功能标志 custom_headers_streaming_audit_events_ui。在 SaaS 版上,此功能的 UI 不可用。此功能的 UI 尚未准备好用于生产。

至少具有群组所有者角色的用户可以为其添加事件流目的地和自定义 HTTP header:

  1. 在顶部栏上,选择 菜单 > 群组 并找到您的群组。
  2. 在左侧边栏中,选择 安全与合规 > 审计事件
  3. 在主区域,选择 事件流 选项卡。
  4. 选择项目右侧的
  5. 显示项目自定义 header 的只读视图。
  6. 选择 取消 关闭只读视图。

验证事件真实性

引入于 14.8 版本。

每个流目的地都有唯一的验证令牌(verificationToken),可用于验证事件的真实性。此令牌是在创建事件目的地时生成的,并且无法更改。

每个流事件都包含一个随机的字母数字标识符,用于 X-Gitlab-Event-Streaming-Token HTTP header,当列出流目的地时,可以根据目的地的值进行验证。

使用 UI

引入于 15.2 版本。

至少具有群组所有者角色的用户可以列出事件流目的地并查看验证令牌:

  1. 在顶部栏上,选择 菜单 > 群组 并找到您的群组。
  2. 在左侧边栏中,选择 安全与合规 > 审计事件
  3. 在主区域,选择 事件流
  4. 查看每个项目右侧的验证令牌。

Git 操作的审计事件流

  • 引入于 14.9 版本,功能标志名为 audit_event_streaming_git_operations。默认禁用。
  • 在 SaaS 上启用于 15.0 版本。
  • 在私有化部署版上默认启用于 15.1 版本。
在私有化部署版,此功能默认可用。要隐藏此功能,请询问管理员禁用功能标志 audit_event_streaming_git_operations。在 SaaS 上,此功能可用。

当登录用户推送或拉取项目的远程 Git 仓库时,可以发送审计事件流:

  • 使用 SSH
  • 使用 HTTP 或 HTTPS。
  • 在 GitLab UI 中使用 下载 按钮 ()。

对于未登录的用户,不会捕获审计事件。例如,在下载公开项目时。

要为 Git 操作配置审计事件流,请参阅添加新的事件流目的地

Headers

Headers 的格式如下:

POST /logs HTTP/1.1
Host: <DESTINATION_HOST>
Content-Type: application/x-www-form-urlencoded
X-Gitlab-Event-Streaming-Token: <DESTINATION_TOKEN>

SSH 事件的示例负载

抓取:

{
  "id": 1,
  "author_id": 1,
  "entity_id": 29,
  "entity_type": "Project",
  "details": {
    "author_name": "Administrator",
    "target_id": 29,
    "target_type": "Project",
    "target_details": "example-project",
    "custom_message": {
      "protocol": "ssh",
      "action": "git-upload-pack"
    },
    "ip_address": "127.0.0.1",
    "entity_path": "example-group/example-project"
  },
  "ip_address": "127.0.0.1",
  "author_name": "Administrator",
  "entity_path": "example-group/example-project",
  "target_details": "example-project",
  "created_at": "2022-02-23T06:21:05.283Z",
  "target_type": "Project",
  "target_id": 29
}

推送:

{
  "id": 1,
  "author_id": 1,
  "entity_id": 29,
  "entity_type": "Project",
  "details": {
    "author_name": "Administrator",
    "target_id": 29,
    "target_type": "Project",
    "target_details": "example-project",
    "custom_message": {
      "protocol": "ssh",
      "action": "git-receive-pack"
    },
    "ip_address": "127.0.0.1",
    "entity_path": "example-group/example-project"
  },
  "ip_address": "127.0.0.1",
  "author_name": "Administrator",
  "entity_path": "example-group/example-project",
  "target_details": "example-project",
  "created_at": "2022-02-23T06:23:08.746Z",
  "target_type": "Project",
  "target_id": 29
}

HTTP 和 HTTPS 事件的示例负载

抓取:

{
  "id": 1,
  "author_id": 1,
  "entity_id": 29,
  "entity_type": "Project",
  "details": {
    "author_name": "Administrator",
    "target_id": 29,
    "target_type": "Project",
    "target_details": "example-project",
    "custom_message": {
      "protocol": "http",
      "action": "git-upload-pack"
    },
    "ip_address": "127.0.0.1",
    "entity_path": "example-group/example-project"
  },
  "ip_address": "127.0.0.1",
  "author_name": "Administrator",
  "entity_path": "example-group/example-project",
  "target_details": "example-project",
  "created_at": "2022-02-23T06:25:43.938Z",
  "target_type": "Project",
  "target_id": 29
}

推送:

{
  "id": 1,
  "author_id": 1,
  "entity_id": 29,
  "entity_type": "Project",
  "details": {
    "author_name": "Administrator",
    "target_id": 29,
    "target_type": "Project",
    "target_details": "example-project",
    "custom_message": {
      "protocol": "http",
      "action": "git-receive-pack"
    },
    "ip_address": "127.0.0.1",
    "entity_path": "example-group/example-project"
  },
  "ip_address": "127.0.0.1",
  "author_name": "Administrator",
  "entity_path": "example-group/example-project",
  "target_details": "example-project",
  "created_at": "2022-02-23T06:26:29.294Z",
  "target_type": "Project",
  "target_id": 29
}

来自 GitLab UI 下载按钮的事件负载示例

抓取:

{
  "id": 1,
  "author_id": 99,
  "entity_id": 29,
  "entity_type": "Project",
  "details": {
    "custom_message": "Repository Download Started",
    "author_name": "example_username",
    "target_id": 29,
    "target_type": "Project",
    "target_details": "example-group/example-project",
    "ip_address": "127.0.0.1",
    "entity_path": "example-group/example-project"
  },
  "ip_address": "127.0.0.1",
  "author_name": "example_username",
  "entity_path": "example-group/example-project",
  "target_details": "example-group/example-project",
  "created_at": "2022-02-23T06:27:17.873Z",
  "target_type": "Project",
  "target_id": 29
}

合并请求批准操作的审计事件流

引入于 14.9 版本。

与项目内执行的合并批准操作相关的审计事件流。

Headers

Headers 的格式如下:

POST /logs HTTP/1.1
Host: <DESTINATION_HOST>
Content-Type: application/x-www-form-urlencoded
X-Gitlab-Event-Streaming-Token: <DESTINATION_TOKEN>

示例负载

{
  "id": 1,
  "author_id": 1,
  "entity_id": 6,
  "entity_type": "Project",
  "details": {
    "author_name": "example_username",
    "target_id": 20,
    "target_type": "MergeRequest",
    "target_details": "merge request title",
    "custom_message": "Approved merge request",
    "ip_address": "127.0.0.1",
    "entity_path": "example-group/example-project"
  },
  "ip_address": "127.0.0.1",
  "author_name": "example_username",
  "entity_path": "example-group/example-project",
  "target_details": "merge request title",
  "created_at": "2022-03-09T06:53:11.181Z",
  "target_type": "MergeRequest",
  "target_id": 20
}

合并请求创建操作的审计事件流

引入于 15.2 版本。

使用 /logs 端点流式传输与合并请求创建操作相关的审计事件。

发送包含 X-Gitlab-Audit-Event-Type header 且值为 merge_request_create 的 API 请求。系统使用 JSON 有效负载进行响应,其中 event_type 字段设置为 merge_request_create

Headers

格式如下:

POST /logs HTTP/1.1
Host: <DESTINATION_HOST>
Content-Type: application/x-www-form-urlencoded
X-Gitlab-Audit-Event-Type: merge_request_create
X-Gitlab-Event-Streaming-Token: <DESTINATION_TOKEN>

示例负载

{
  "id": 1,
  "author_id": 1,
  "entity_id": 24,
  "entity_type": "Project",
  "details": {
    "author_name": "example_user",
    "target_id": 132,
    "target_type": "MergeRequest",
    "target_details": "Update test.md",
    "custom_message": "Added merge request",
    "ip_address": "127.0.0.1",
    "entity_path": "example-group/example-project"
  },
  "ip_address": "127.0.0.1",
  "author_name": "Administrator",
  "entity_path": "example-group/example-project",
  "target_details": "Update test.md",
  "created_at": "2022-07-04T00:19:22.675Z",
  "target_type": "MergeRequest",
  "target_id": 132,
  "event_type": "merge_request_create"
}

项目派生操作的审计事件流

引入于 15.2 版本。

使用 /logs 端点流式传输与项目派生创建操作相关的审计事件。

发送包含 X-Gitlab-Audit-Event-Type 标头和值为 project_fork_operation 的 API 请求。系统使用 JSON 有效负载进行响应,其中 event_type 字段设置为 project_fork_operation

Headers

格式如下:

POST /logs HTTP/1.1
Host: <DESTINATION_HOST>
Content-Type: application/x-www-form-urlencoded
X-Gitlab-Audit-Event-Type: project_fork_operation
X-Gitlab-Event-Streaming-Token: <DESTINATION_TOKEN>

示例负载

{
  "id": 1,
  "author_id": 1,
  "entity_id": 24,
  "entity_type": "Project",
  "details": {
    "author_name": "example_username",
    "target_id": 24,
    "target_type": "Project",
    "target_details": "example-project",
    "custom_message": "Forked project to another-group/example-project-forked",
    "ip_address": "127.0.0.1",
    "entity_path": "example-group/example-project"
  },
  "ip_address": "127.0.0.1",
  "author_name": "example_username",
  "entity_path": "example-group/example-project",
  "target_details": "example-project",
  "created_at": "2022-06-30T03:43:35.384Z",
  "target_type": "Project",
  "target_id": 24,
  "event_type": "project_fork_operation"
}

项目群组关联操作的审计事件流

引入于 15.2 版本。

使用 /logs 端点流式传输与项目群组关联的创建、更新和删除相关的审计事件。

发送包含 X-Gitlab-Audit-Event-Type 标头的 API 请求,其值为:

  • project_group_link_create
  • project_group_link_update
  • project_group_link_destroy

系统使用 JSON 有效负载响应,并将 event_type 字段设置为:

  • project_group_link_create
  • project_group_link_update
  • project_group_link_destroy

示例 Headers

格式如下:

POST /logs HTTP/1.1
Host: <DESTINATION_HOST>
Content-Type: application/x-www-form-urlencoded
X-Gitlab-Audit-Event-Type: project_group_link_create
X-Gitlab-Event-Streaming-Token: <DESTINATION_TOKEN>

创建项目群组关联的示例负载

{
  "id": 1,
  "author_id": 1,
  "entity_id": 24,
  "entity_type": "Project",
  "details": {
    "author_name": "example-user",
    "target_id": 31,
    "target_type": "Group",
    "target_details": "another-group",
    "custom_message": "Added project group link",
    "ip_address": "127.0.0.1",
    "entity_path": "example-group/example-project"
  },
  "ip_address": "127.0.0.1",
  "author_name": "example-user",
  "entity_path": "example-group/example-project",
  "target_details": "another-group",
  "created_at": "2022-07-04T00:43:09.318Z",
  "target_type": "Group",
  "target_id": 31,
  "event_type": "project_group_link_create"
}

更新项目群组关联的示例负载

{
  "id": 1,
  "author_id": 1,
  "entity_id": 24,
  "entity_type": "Project",
  "details": {
    "author_name": "example-user",
    "target_id": 31,
    "target_type": "Group",
    "target_details": "another-group",
    "custom_message": "Changed project group link profile group_access from Developer to Guest",
    "ip_address": "127.0.0.1",
    "entity_path": "example-group/example-project"
  },
  "ip_address": "127.0.0.1",
  "author_name": "example-user",
  "entity_path": "example-group/example-project",
  "target_details": "another-group",
  "created_at": "2022-07-04T00:43:28.328Z",
  "target_type": "Group",
  "target_id": 31,
  "event_type": "project_group_link_update"
}

删除项目群组关联的示例负载

{
  "id": 1,
  "author_id": 1,
  "entity_id": 24,
  "entity_type": "Project",
  "details": {
    "author_name": "example-user",
    "target_id": 31,
    "target_type": "Group",
    "target_details": "another-group",
    "custom_message": "Removed project group link",
    "ip_address": "127.0.0.1",
    "entity_path": "example-group/example-project"
  },
  "ip_address": "127.0.0.1",
  "author_name": "example-user",
  "entity_path": "example-group/example-project",
  "target_details": "another-group",
  "created_at": "2022-07-04T00:42:56.279Z",
  "target_type": "Group",
  "target_id": 31,
  "event_type": "project_group_link_destroy"
}