<!-- Sanitized reference copy. Original comments removed; OAuth domains generalized.
     Logic is otherwise unchanged and includes known review issues.
     Read README.md and the draft Technical Review Notes before use. -->

<group name="gitlab,repository_activity,">

  <rule id="110080" level="5">
    <decoded_as>json</decoded_as>
    <field name="integration.log_type">^gitlab_shell$</field>
    <field name="command" type="pcre2">^git-receive-pack$</field>
    <description>GitLab Git-over-SSH push: $(gl_project_path) by $(gl_username) from $(remote_ip)</description>
    <group>git_push,repository_changed,git_ssh,</group>
  </rule>

  <rule id="110081" level="4">
    <decoded_as>json</decoded_as>
    <field name="integration.log_type">^gitlab_shell$</field>
    <field name="command" type="pcre2">^git-upload-pack$</field>
    <description>GitLab Git-over-SSH fetch/clone: $(gl_project_path) by $(gl_username) from $(remote_ip)</description>
    <group>git_fetch,data_access,git_ssh,</group>
  </rule>

  <rule id="110082" level="11" frequency="8" timeframe="600" ignore="600">
    <if_matched_sid>110081</if_matched_sid>
    <same_field>gl_username</same_field>
    <different_field>gl_project_path</different_field>
    <description>GitLab: $(gl_username) cloned/fetched many distinct repositories over SSH in a short window</description>
    <mitre><id>T1213.003</id></mitre>
    <group>data_access,mass_clone,anomaly,</group>
  </rule>

  <rule id="110083" level="7">
    <decoded_as>json</decoded_as>
    <field name="integration.log_type">^workhorse$</field>
    <field name="route_id">^git_upload_pack$</field>
    <field name="written_bytes" type="pcre2">^\d{9,}$</field>
    <description>GitLab large repository clone served to $(remote_ip): $(uri), $(written_bytes) bytes, agent $(user_agent)</description>
    <mitre><id>T1213.003</id></mitre>
    <group>data_access,large_transfer,</group>
  </rule>

  <rule id="110084" level="10">
    <if_sid>110083</if_sid>
    <field name="written_bytes" type="pcre2">^\d{10,}$</field>
    <description>GitLab very large repository clone served to $(remote_ip): $(uri), $(written_bytes) bytes</description>
    <mitre><id>T1213.003</id></mitre>
    <group>data_access,bulk_egress,</group>
  </rule>

  <rule id="110085" level="10" frequency="6" timeframe="900" ignore="600">
    <if_matched_sid>110083</if_matched_sid>
    <same_field>remote_ip</same_field>
    <description>GitLab repeated large clones from a single source: $(remote_ip)</description>
    <mitre><id>T1213.003</id></mitre>
    <group>data_access,bulk_egress,anomaly,</group>
  </rule>

  <rule id="110086" level="6" frequency="10" timeframe="600" ignore="300">
    <if_matched_sid>110083</if_matched_sid>
    <same_field>uri</same_field>
    <different_field>remote_ip</different_field>
    <description>GitLab one repository cloned in volume from many sources: $(uri)</description>
    <group>data_access,mass_clone,</group>
  </rule>

  <rule id="110087" level="3">
    <decoded_as>json</decoded_as>
    <field name="integration.log_type">^production_json$</field>
    <field name="path" type="pcre2">/-/autocomplete/users\.json</field>
    <status type="pcre2">^200$</status>
    <field name="meta.client_id" type="pcre2">^ip/</field>
    <description>GitLab anonymous project member-list read from $(remote_ip), project $(meta.project)</description>
    <group>anonymous_access,page_render_byproduct,</group>
  </rule>

  <rule id="110088" level="3">
    <decoded_as>json</decoded_as>
    <field name="integration.log_type">^production_json$</field>
    <field name="controller" type="pcre2">^Projects::(Blob|Raw|Tree|Blame|Commits|Refs)Controller$</field>
    <field name="meta.client_id" type="pcre2">^ip/</field>
    <description>GitLab anonymous repository-content read from $(remote_ip): $(controller), project $(meta.project)</description>
    <group>anonymous_access,content_read,</group>
  </rule>

  <rule id="110089" level="9" frequency="60" timeframe="300" ignore="1800">
    <if_matched_sid>110088</if_matched_sid>
    <same_field>meta.project</same_field>
    <different_field>remote_ip</different_field>
    <description>GitLab sustained anonymous crawl of project $(meta.project) from rotating sources</description>
    <mitre><id>T1595</id></mitre>
    <group>scraping,resource_abuse,</group>
  </rule>

  <rule id="110090" level="3">
    <decoded_as>json</decoded_as>
    <field name="integration.log_type">^production_json$</field>
    <field name="path">^/api/graphql$</field>
    <field name="meta.client_id" type="pcre2">^ip/</field>
    <description>GitLab anonymous GraphQL query from $(remote_ip), project $(meta.project)</description>
    <group>anonymous_access,</group>
  </rule>

  <rule id="110091" level="8" frequency="80" timeframe="300" ignore="1800">
    <if_matched_sid>110090</if_matched_sid>
    <same_field>meta.project</same_field>
    <different_field>remote_ip</different_field>
    <description>GitLab high-volume anonymous GraphQL against project $(meta.project) from rotating sources</description>
    <mitre><id>T1595</id></mitre>
    <group>scraping,resource_abuse,</group>
  </rule>

  <rule id="110097" level="8" frequency="120" timeframe="300" ignore="900">
    <if_matched_sid>110088</if_matched_sid>
    <same_field>remote_ip</same_field>
    <description>GitLab sustained anonymous content crawl from a single source: $(remote_ip)</description>
    <mitre><id>T1595</id></mitre>
    <group>scraping,resource_abuse,</group>
  </rule>

  <rule id="110079" level="3">
    <decoded_as>json</decoded_as>
    <field name="integration.log_type">^production_json$</field>
    <field name="meta.client_id" type="pcre2">^ip/</field>
    <field name="duration_s" type="pcre2">^[1-9]\d*\.</field>
    <description>GitLab expensive anonymous request, project $(meta.project) from $(remote_ip): $(duration_s)s</description>
    <group>resource_abuse,performance,</group>
  </rule>

  <rule id="110098" level="6" frequency="20" timeframe="300" ignore="900">
    <if_matched_sid>110079</if_matched_sid>
    <same_field>meta.project</same_field>
    <description>GitLab repeated expensive anonymous requests against project $(meta.project)</description>
    <group>resource_abuse,performance,</group>
  </rule>

  <rule id="110092" level="10" frequency="4" timeframe="900" ignore="600">
    <if_matched_sid>110064</if_matched_sid>
    <same_field>meta.user</same_field>
    <different_field>meta.project</different_field>
    <description>GitLab: $(meta.user) pushed to several distinct repositories in a short window</description>
    <mitre><id>T1195</id></mitre>
    <group>git_push,anomaly,</group>
  </rule>

  <rule id="110093" level="9" frequency="2" timeframe="600" ignore="600">
    <if_matched_sid>110064</if_matched_sid>
    <same_field>meta.user</same_field>
    <different_field>remote_ip</different_field>
    <description>GitLab: $(meta.user) pushed from more than one source address in a short window</description>
    <mitre><id>T1078</id></mitre>
    <group>git_push,impossible_travel_candidate,anomaly,</group>
  </rule>

  <rule id="110094" level="10">
    <if_sid>110064</if_sid>
    <field name="ua" type="pcre2">(?i)gitlab-runner|go-git|python-requests|curl/|libgit2</field>
    <description>GitLab push using an automation user agent by $(meta.user) from $(remote_ip): $(ua)</description>
    <mitre><id>T1195</id></mitre>
    <group>git_push,automation_push,anomaly,</group>
  </rule>

  <rule id="110095" level="3">
    <decoded_as>json</decoded_as>
    <field name="integration.log_type">^production_json$</field>
    <field name="controller">^Repositories::GitHttpController$</field>
    <action type="pcre2">^git_upload_pack$</action>
    <status type="pcre2">^200$</status>
    <description>GitLab Git-over-HTTP fetch/clone by $(meta.user) from $(remote_ip): $(meta.project)</description>
    <group>git_fetch,data_access,</group>
  </rule>

  <rule id="110096" level="3">
    <decoded_as>json</decoded_as>
    <field name="integration.log_type">^workhorse$</field>
    <field name="route_id" type="pcre2">^git_(upload|receive)_pack$</field>
    <description>GitLab Git transfer via workhorse: $(route_id), $(uri), $(written_bytes) bytes out, $(read_bytes) bytes in</description>
    <group>git_transfer,volume_baseline,</group>
  </rule>

</group>
