Skip to content

feat: Sigma rules - #196

Draft
MichaelThamm wants to merge 33 commits into
mainfrom
feat/sigma-rules-2
Draft

MichaelThamm wants to merge 33 commits into
mainfrom
feat/sigma-rules-2

Conversation

@MichaelThamm

@MichaelThamm MichaelThamm commented May 8, 2026

Copy link
Copy Markdown
Contributor

Issue

We need a Sigma rules feature in cos-lib to unblock these PRs:

Solution

What

Introduces a SigmaRules utility and the supporting type definitions so downstream charm libraries (e.g. charmlibs.interfaces.otlp) can aggregate and forward Sigma detection rules with Juju topology, the same way AlertRules/RecordingRules handle PromQL/LogQL.

SigmaRules (src/cosl/rules.py)

  • add(rule_dict) — accepts a single Sigma rule or a {"rules": [...]} collection; skips entries missing required fields.
  • add_path(dir_path, *, recursive=False) — aggregates rule files (.rule/.rules/.yml/.yaml) from a file or directory.
  • as_dict() — returns the collection in SigmaRuleFileFormat.
  • Topology injection into each rule's tags as namespace.value (e.g. juju_model.foo):
    • existing namespaces are not overwritten (caller-set juju_* tags win),
    • tags are sorted for deterministic relation data (avoids spurious relation-changed churn),
    • re-injection is idempotent.

Unlike PromQL/LogQL, Sigma rules have no grouping/expr concept, so there is no expression rewriting — only tags enrichment.

Types (src/cosl/types.py)

  • New TypedDicts: SigmaRuleLogSource, SigmaRuleFormat, SigmaRuleFileFormat.

Tests

  • tests/test_rules_sigma.py (348 lines) covering add/add_path/as_dict, topology injection precedence, deterministic tag ordering, and idempotent re-injection.
  • Fixture rule files under tests/sigma_rules/ (single rules + a collection).

Notes

  • Additive and backward compatible — no changes to existing AlertRules/RecordingRules behavior.

Checklist

  • I have added or updated relevant documentation.
  • PR title makes an appropriate release note and follows conventional commits syntax.
  • Merge target is the correct branch, and relevant tandem backport PRs opened.
  • This change warrants a release, so I have updated the project.version field in the pyproject.toml file.

Context

Testing Instructions

Upgrade Notes

MichaelThamm and others added 2 commits May 8, 2026 15:22
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
@MichaelThamm MichaelThamm changed the title chore feat: Sigma rules rework pt.1 May 8, 2026
@MichaelThamm MichaelThamm changed the title feat: Sigma rules rework pt.1 feat: Sigma rules rework pt.2 May 8, 2026
Co-authored-by: Copilot <copilot@github.com>
@MichaelThamm MichaelThamm changed the title feat: Sigma rules rework pt.2 feat: Sigma rules pt.2 May 8, 2026
@MichaelThamm MichaelThamm mentioned this pull request May 8, 2026
4 tasks
@niwamo niwamo mentioned this pull request Jun 18, 2026
4 tasks
MichaelThamm and others added 14 commits June 18, 2026 17:07
* feat: log files ignored due to unrecognized suffix in _multi_suffix_glob

When rule files are skipped because they don't carry a recognized suffix
(.rule, .rules, .yml, .yaml), emit an info-level log so operators can
understand why their files are being silently ignored.

Closes canonical/cos-configuration-k8s-operator#129

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* bump version

* fix: replace deprecated urlopen capath with ssl.SSLContext; bump to 1.9.2

cafile/capath/cadefault params were removed in Python 3.13. Build an
SSLContext from the cert path and pass it via the context= param instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add unit tests for LokiEmitter._send_request cert handling

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: verify _multi_suffix_glob logs files with unrecognized suffixes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: wrap long line in test to satisfy black

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread src/cosl/rules.py Outdated
Comment thread src/cosl/rules.py

Unlike Prometheus/Loki rules, Sigma rules are independent (no grouping concept):
detection logic lives in a ``detection`` block instead of an ``expr`` field. A rule
may carry an ``id`` (UUID) for reference, but it is optional and not enforced here as

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure to be careful with UUID since it can cause many relation-changed events. Ask Luca for details.

Comment thread src/cosl/loki_logger.py

@MichaelThamm MichaelThamm Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert this change

Comment thread src/cosl/rules.py

# --- Free functions for file I/O, reusable across rule backends --- #

_RULE_FILE_SUFFIXES = [".rule", ".rules", ".yml", ".yaml"]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure that this works with Sigma rules. I think this is all-encompasing, but Sigma should filter to only YAML.

@MichaelThamm
MichaelThamm changed the base branch from feat/sigma-rules to main June 26, 2026 15:17
@MichaelThamm MichaelThamm changed the title feat: Sigma rules pt.2 feat: Sigma rules Jun 26, 2026
Comment thread tests/test_rules_sigma.py
def test_existing_juju_model_uuid_tag_not_overwritten(sigma):
sigma.add(_rule("Upstream UUID", tags=["juju_model_uuid.deadbeef"]))
tags = sigma.rules[0]["tags"]
assert "juju_model_uuid.deadbeef" in tags

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update name deadbeef

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants