Skip to content

Commit 7d18cbd

Browse files
committed
fix: align GitHub filter and rule contracts
1 parent 6c3af7e commit 7d18cbd

3 files changed

Lines changed: 116 additions & 3 deletions

File tree

‎filters/audits/github.md‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# GitHub normalization and rule review
2+
3+
Promote senderLogin to origin.user without consuming the vendor field used by rules; normalize workflow failures.
4+
5+
This draft targets UTMStack `v11`. It contains 1 filter changes
6+
and 0 rule changes for this technology only. Review covered
7+
1 filter configurations and 13 matching shipped rule files.
8+
Unchanged rules are listed in the regression manifest; they are not duplicated in the diff.
9+
10+
## Contract and validation
11+
12+
- Compared exact standard names/types with go-sdk v1.1.31 and the supplied UTMStack dictionaries.
13+
- Checked documented pipeline ordering, rename/move behavior, open vendor log fields,
14+
event-side versus alert-side fields, and surviving fields used by affected rule predicates/history/grouping.
15+
- Strict SDK configuration decoding and actual CEL compilation pass for this scope.
16+
- 2 synthetic normalization cases pass, including SDK Event conversion and any
17+
trigger predicate assertions recorded in the manifest.
18+
- The scoped alerts module tests and `git diff --check` pass with the shared contract runner applied.
19+
20+
The shared alert-contract PR supplies the reusable Go runner for the manifest in
21+
`plugins/alerts/testdata/filter-contracts/github.json`. Apply that support before running `go test ./...` in `plugins/alerts`.
22+
23+
The model starts from synthetic extraction results. It does not run complex grok,
24+
JSON/KV/XML/CSV extraction, time conversion, dynamic plugins, historical OpenSearch
25+
queries, or the closed EventProcessor. Raw vendor logs and resulting alerts must
26+
still be checked in staging before rollout. No customer false-positive reduction
27+
has been measured and no production rollout is included.
28+
29+
30+
31+
## References
32+
33+
- [SDK schema](https://github.com/threatwinds/go-sdk/blob/v1.1.31/plugins/plugins.proto)
34+
- [Filter steps](https://github.com/threatwinds/go-sdk/wiki/Filter-Steps-Reference)
35+
- [Standard event schema](https://github.com/threatwinds/go-sdk/wiki/Standard-Event-Schema)
36+
- [Rule implementation](https://github.com/threatwinds/go-sdk/wiki/Implementing-Rules)
37+
38+
`afterEvents`, empty noncapturing grok names, supported numeric strings, and custom
39+
`log.*` fields are accepted. Existing textual protocol casing and vendor action names
40+
are preserved unless a concrete consumer mismatch requires correction.

‎filters/github/github.yml‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -679,8 +679,8 @@ pipeline:
679679
function: string
680680
params:
681681
key: actionResult
682-
value: "failed"
683-
where: 'oneOf("log.conclusion", ["failure", "timed_out", "startup_failure", "action_required"])'
682+
value: failure
683+
where: oneOf("log.conclusion", ["failure", "timed_out", "startup_failure", "action_required"])
684684

685685
# Removing unused fields
686686
- delete:
@@ -696,4 +696,12 @@ pipeline:
696696
- log.sender
697697
- log.pusher
698698
- log.repository.owner
699-
- log.repository
699+
- log.repository
700+
701+
# Promote standard fields while retaining vendor fields used by rules.
702+
- grok:
703+
source: log.senderLogin
704+
patterns:
705+
- fieldName: origin.user
706+
pattern: '{{.greedy}}'
707+
where: exists("log.senderLogin") && !exists("origin.user")
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"technology": "GitHub",
3+
"filters": [
4+
"filters/github/github.yml"
5+
],
6+
"rules": [
7+
"rules/github/action_secret_access.yml",
8+
"rules/github/codeowners_modification.yml",
9+
"rules/github/dependabot_config_poisoning.yml",
10+
"rules/github/environment_protection_bypass.yml",
11+
"rules/github/github_app_token_theft.yml",
12+
"rules/github/mass_repository_cloning.yml",
13+
"rules/github/org_member_role_escalation.yml",
14+
"rules/github/repo_visibility_public.yml",
15+
"rules/github/secret_scanning_alerts.yml",
16+
"rules/github/self_hosted_runner_compromise.yml",
17+
"rules/github/sensitive_data_commits.yml",
18+
"rules/github/workflow_injection_pr_target.yml",
19+
"rules/github/workflow_modifications.yml"
20+
],
21+
"fixtures": [
22+
{
23+
"name": "github_workflow_success",
24+
"filter": "github/github.yml",
25+
"input": {
26+
"log": {
27+
"sender": {
28+
"login": "operator"
29+
},
30+
"workflow_run": {
31+
"conclusion": "success"
32+
}
33+
}
34+
},
35+
"expected": {
36+
"origin.user": "operator",
37+
"log.senderLogin": "operator",
38+
"actionResult": "success"
39+
},
40+
"absent": [],
41+
"rules": {}
42+
},
43+
{
44+
"name": "github_workflow_failure",
45+
"filter": "github/github.yml",
46+
"input": {
47+
"log": {
48+
"sender": {
49+
"login": "operator"
50+
},
51+
"workflow_run": {
52+
"conclusion": "failure"
53+
}
54+
}
55+
},
56+
"expected": {
57+
"origin.user": "operator",
58+
"log.senderLogin": "operator",
59+
"actionResult": "failure"
60+
},
61+
"absent": [],
62+
"rules": {}
63+
}
64+
]
65+
}

0 commit comments

Comments
 (0)