Skip to content

feat: Write roles fingerprints to /var/log/sysroles.jsonl [citest_skip] - #140

Merged
richm merged 2 commits into
mainfrom
fingerprint-write-to-file
Aug 6, 2026
Merged

feat: Write roles fingerprints to /var/log/sysroles.jsonl [citest_skip]#140
richm merged 2 commits into
mainfrom
fingerprint-write-to-file

Conversation

@spetrosi

@spetrosi spetrosi commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Feature: Write roles fingerprints to /var/log/sysroles.jsonl [citest_skip]

Reason: By default logs are printed to rsyslog. This change adds a possibility to write logs to a file on the system for the downstream users.

Result: For the upstream, this makes rsyslog log message more detailed. For the downstream - also writes logs to /var/log/sysroles.jsonl

@spetrosi
spetrosi requested a review from richm as a code owner August 6, 2026 12:41
@spetrosi spetrosi self-assigned this Aug 6, 2026
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Ignore keyword(s) in the title.

⛔ Ignored keywords (1)
  • [citest_skip]

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 6756058b-e036-4568-b8f3-91d74e986efa

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Changes

The sr_fingerprint module now collects role metadata, builds canonical fingerprints, formats syslog records, and optionally writes bounded JSONL logs. Check mode returns fingerprint data without writing. Unit tests cover formatting, persistence, trimming, validation, and failures.

Role fingerprint module

Layer / File(s) Summary
Fingerprint contract and formatting
library/sr_fingerprint.py, tests/unit/test_sr_fingerprint.py
The module defines fingerprint inputs, derived fields, canonical records, syslog formatting, JSONL serialization, and timestamp formatting.
Bounded JSONL persistence
library/sr_fingerprint.py, tests/unit/test_sr_fingerprint.py
The module creates parent directories, appends records under an exclusive lock, trims old records by size, and preserves value types and file metadata where possible.
Execution and error handling
library/sr_fingerprint.py, tests/unit/test_sr_fingerprint.py
The handler validates parameters, supports check mode, writes configured outputs, returns fingerprint data, and reports invalid sizes and write failures.

Suggested reviewers: richm, nhosoi

🚥 Pre-merge checks | ✅ 4 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description Format ⚠️ Warning The description includes Reason, Result, and a valid Signed-off-by line, but it has no required Enhancement: or Feature: section. Add an Enhancement: or Feature: section that describes the change, while retaining the existing required sections.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title uses the required Conventional Commits format and accurately describes the fingerprint logging change.
Description check ✅ Passed The description includes the feature rationale and result, but it omits the Issue Tracker Tickets section and uses Feature instead of Enhancement.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@library/sr_fingerprint.py`:
- Around line 231-232: Update the log-appending flow around _trim_log_file to
handle records where len(new_line) exceeds max_size before trimming or writing:
consistently reject or skip the oversized row, including in check mode, so the
JSONL file never exceeds a positive limit. Add coverage asserting the file
remains within max_size after an oversized record is processed.
- Around line 220-224: Harden _write_jsonl_log and every log_file read/write
path against symlink attacks by opening files with no-follow semantics,
validating each resulting descriptor is a regular file, and avoiding any
subsequent path-based open after validation. Apply the same protections to the
<log_file>.lock sidecar, replacing the current open(lock_path, "w") flow while
preserving locking and logging behavior.
- Around line 283-287: Update _format_fingerprint_key_value to escape
backslashes, quotes, carriage returns, line feeds, and tabs in values before
emitting quoted syslog fields, while preserving existing unquoted formatting
behavior. Add a regression test covering a newline in a field value and verify
the resulting fingerprint value cannot span syslog lines.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 24c4ff37-c3fc-4eb0-8d6d-0330e08bddc7

📥 Commits

Reviewing files that changed from the base of the PR and between aa8ffcf and 1c20fee.

📒 Files selected for processing (2)
  • library/sr_fingerprint.py
  • tests/unit/test_sr_fingerprint.py

Comment thread library/sr_fingerprint.py
Comment on lines +220 to +224
def _write_jsonl_log(log_file, record, max_size=0):
_ensure_parent_dir(log_file)
new_line = _format_fingerprint_jsonl(record) + "\n"
lock_path = log_file + ".lock"
lock_fd = open(lock_path, "w")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Prevent symlink attacks on the log file and lock file.

Line 224 opens <log_file>.lock with "w". If log_file is under a locally writable directory, a local attacker can replace the sidecar with a symlink. A privileged module execution then truncates the symlink target before it acquires the lock.

Apply no-follow descriptor opens and regular-file validation to the lock file and every log_file read or write path. Do not use a path-following open after validation.

🧰 Tools
🪛 ast-grep (0.45.0)

[warning] 223-223: File path is request-/variable-derived; validate and normalize to prevent path traversal.
Context: open(lock_path, "w")
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(open-filename-from-request)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@library/sr_fingerprint.py` around lines 220 - 224, Harden _write_jsonl_log
and every log_file read/write path against symlink attacks by opening files with
no-follow semantics, validating each resulting descriptor is a regular file, and
avoiding any subsequent path-based open after validation. Apply the same
protections to the <log_file>.lock sidecar, replacing the current
open(lock_path, "w") flow while preserving locking and logging behavior.

Source: Linters/SAST tools

Comment thread library/sr_fingerprint.py
Comment on lines +231 to +232
if max_size > 0 and cur_size + len(new_line) > max_size and cur_size > 0:
_trim_log_file(log_file, len(new_line))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Enforce the configured JSONL size limit for oversized records.

If new_line alone exceeds max_size, Line 231 either skips trimming for an empty file or removes every old row and then appends the oversized row. The file remains larger than max_log_size.

Define an oversized-record policy before appending. Reject or intentionally skip a row that cannot fit. Apply the same policy in check mode. Add a test that asserts the file never exceeds a positive max_size.

🧰 Tools
🪛 ast-grep (0.45.0)

[warning] 232-232: File path is request-/variable-derived; validate and normalize to prevent path traversal.
Context: open(log_file, "a")
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(open-filename-from-request)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@library/sr_fingerprint.py` around lines 231 - 232, Update the log-appending
flow around _trim_log_file to handle records where len(new_line) exceeds
max_size before trimming or writing: consistently reject or skip the oversized
row, including in check mode, so the JSONL file never exceeds a positive limit.
Add coverage asserting the file remains within max_size after an oversized
record is processed.

Comment thread library/sr_fingerprint.py
Comment on lines +283 to +287
def _format_fingerprint_key_value(field, value):
text = "" if value is None else str(value)
if any(char in text for char in ' "='):
return '%s="%s"' % (field, text.replace('"', '""'))
return "%s=%s" % (field, text)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Escape line-control characters in syslog values.

role_name, role_path, and distribution values can contain CR or LF. The current formatter emits them unchanged. A value with a line break can create forged or malformed syslog records.

Escape backslashes, quotes, CR, LF, and tabs before formatting a quoted value. Add a regression test with a newline in a field value.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@library/sr_fingerprint.py` around lines 283 - 287, Update
_format_fingerprint_key_value to escape backslashes, quotes, carriage returns,
line feeds, and tabs in values before emitting quoted syslog fields, while
preserving existing unquoted formatting behavior. Add a regression test covering
a newline in a field value and verify the resulting fingerprint value cannot
span syslog lines.

@spetrosi spetrosi changed the title feat: Write roles fingerprints to /var/log/sysroles.jsonl feat: Write roles fingerprints to /var/log/sysroles.jsonl [citest_skip] Aug 6, 2026
Feature: Write roles fingerprints to /var/log/sysroles.jsonl [citest_skip]

Reason: By default logs are printed to rsyslog. This change adds a possibility to write logs to a file on the system for the downstream users.

Result: For the upstream, this makes rsyslog log message more detailed. For the downstream - also writes logs to /var/log/sysroles.jsonl
Signed-off-by: Sergei Petrosian <spetrosi@redhat.com>
@spetrosi
spetrosi force-pushed the fingerprint-write-to-file branch from 1c20fee to e7e6cb4 Compare August 6, 2026 15:03
The sr_fingerprint module was rewritten to accept structured parameters
(status, role_name, role_path, etc.) instead of a free-form sr_message.
Update the role tasks and tests to match the new module interface.

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

spetrosi commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

[citest]

@richm
richm merged commit 5ccbb4e into main Aug 6, 2026
12 of 13 checks passed
@richm
richm deleted the fingerprint-write-to-file branch August 6, 2026 22:09
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.

2 participants