Files
clawsec/skills/clawsec-suite/CHANGELOG.md
T
davida-ps 63de5ce08d Security Audit Suppression Mechanism (fulfills https://github.com/prompt-security/clawsec/issues/25) (#40)
* auto-claude: subtask-1-1 - Create config loading utility with multi-path fallback

Created load_suppression_config.mjs with:
- Multi-path fallback: ~/.openclaw/security-audit.json -> .clawsec/allowlist.json
- Environment variable support (OPENCLAW_AUDIT_CONFIG)
- Custom path support via CLI argument
- Schema validation (checkId, skill, reason, suppressedAt required)
- Malformed JSON error handling
- Graceful fallback to empty suppressions when no config exists
- ISO 8601 date format validation with warnings

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

* auto-claude: subtask-1-2 - Create example config file template

- Added security-audit-config.example.json with two suppression examples
- Included examples for clawsec-suite and openclaw-audit-watchdog
- Created comprehensive README.md explaining configuration format
- All required fields documented (checkId, skill, reason, suppressedAt)
- ISO 8601 date format demonstrated
- JSON validated successfully

* auto-claude: subtask-1-3 - Add unit tests for config loading

Added comprehensive unit tests for suppression config loading:
- Valid config with all required fields
- Malformed date warning (non-blocking)
- Missing required field validation
- Malformed JSON error handling
- File not found graceful fallback
- Custom path priority
- Environment variable override
- Missing/empty suppressions array handling

All 10 tests passing.

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

* auto-claude: subtask-2-1 - Add suppression filtering to render_report.mjs

Implements suppression filtering logic for security audit findings:
- Import loadSuppressionConfig for config loading
- Add --config CLI argument for custom config paths
- Create extractSkillName() to extract skill names from findings (tries multiple fields)
- Create filterFindings() to split findings into active/suppressed
- Match suppressions by BOTH checkId AND skill name (exact match required)
- Attach suppression metadata (reason, suppressedAt) to suppressed findings
- Modify render() to accept suppressedFindings parameter
- Apply filtering in main execution before rendering

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

* auto-claude: subtask-2-2 - Add INFO-SUPPRESSED section to report output

- Added lineForSuppressedFinding() to format suppressed findings
- Added INFO-SUPPRESSED section showing suppressed findings with reason and date
- Suppressed findings are not counted in summary (already filtered)
- Follows existing code patterns for report sections

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

* auto-claude: subtask-3-1 - Add --config flag to run_audit_and_format.sh

- Added --config flag to accept path to config file
- Added --help flag with usage documentation
- Config flag is passed to openclaw audit commands when provided
- Follows existing pattern for --label flag

* auto-claude: subtask-4-1 - Create integration tests for render_report with suppressions

Created comprehensive integration tests covering:
- Suppressed findings appear in INFO-SUPPRESSED section
- Active findings appear in CRITICAL/WARN section
- Summary counts exclude suppressed findings
- Backward compatibility (no config)
- Partial matches don't suppress (checkId or skill alone)
- Multiple suppressions work correctly
- Skill name extraction from path field
- Skill name extraction from title field
- Empty suppressions array behaves like no config

Bug fix in render_report.mjs:
- Summary counts now recalculated after filtering suppressed findings
- Previously summary showed original counts instead of filtered counts

All 10 tests passing.

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

* auto-claude: subtask-4-2 - Manual E2E test with real openclaw audit

- Fixed run_audit_and_format.sh to pass --config flag to render_report.mjs
- Enhanced lineForFinding() to display skill names for better clarity
- Enhanced lineForSuppressedFinding() to display skill names consistently
- Created comprehensive E2E test documentation in E2E-TEST-RESULTS.md
- All E2E verification points passed:
  * Config loading from custom paths
  * Suppression matching by checkId + skill name
  * INFO-SUPPRESSED section display
  * Suppression reason and date display
  * Summary count accuracy (excludes suppressed findings)
  * Non-suppressed findings preservation
  * Skill name display in all findings
- All integration tests still passing (10/10)

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

* auto-claude: subtask-5-1 - Update README.md with suppression feature

* auto-claude: subtask-5-2 - Update SKILL.md with usage examples

* - Add backslash escaping before quote escaping in oneline() function
- Prevents incomplete string escaping vulnerability
- Resolves CodeQL alert: https://github.com/prompt-security/clawsec/security/code-scanning/16

* Fix regex in extractSkillName function and simplify error handling in suppression config tests

* Enhance suppression mechanism in OpenClaw Audit Watchdog

- Updated README.md to clarify suppression configuration and activation requirements.
- Improved SKILL.md with examples for suppressing known findings.
- Refactored load_suppression_config.mjs to implement opt-in gating for suppressions.
- Modified render_report.mjs to support suppression flag in report generation.
- Enhanced run_audit_and_format.sh and runner.sh scripts to accept --enable-suppressions flag.
- Added test cases for suppression configuration, including validation for enabledFor sentinel and opt-in behavior.
- Introduced new test files for empty and invalid suppression configurations.

* Fix type assertion for checksums file entries in Checksums component

* Update ESLint configuration and dependencies to pin @eslint/js to version 9.28.0

* Update CHANGELOG.md for advisory suppression module and OpenClaw Audit Watchdog enhancements

* Refactor finding comparison logic in render_report.mjs to simplify equality checks

* chore(clawsec-suite): bump version to 0.1.2

* chore(openclaw-audit-watchdog): bump version to 0.1.0

* Remove suppressed matches tracking from state to prevent re-evaluation alerts

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-16 18:55:06 +02:00

6.7 KiB

Changelog

All notable changes to the ClawSec Suite will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[0.1.2]

Added

  • Advisory suppression module (hooks/clawsec-advisory-guardian/lib/suppression.mjs).
  • loadAdvisorySuppression() -- loads suppression config with enabledFor: ["advisory"] sentinel gate.
  • isAdvisorySuppressed() -- matches advisory.id === rule.checkId + case-insensitive skill name.
  • Advisory guardian handler integration: partitions matches into active/suppressed after findMatches().
  • Suppressed matches tracked in state file (prevents re-evaluation) but not alerted.
  • Soft notification message for suppressed matches count.
  • Advisory suppression tests (13 tests in advisory_suppression.test.mjs).
  • Documentation in SKILL.md for advisory suppression/allowlist mechanism.

Changed

  • Advisory guardian handler (handler.ts) now loads suppression config and filters matches before alerting.

Security

  • Advisory suppression gated by config file sentinel (enabledFor: ["advisory"]) -- no CLI flag needed but config must explicitly opt in.
  • Suppressed matches are still tracked in state to maintain audit trail.

[0.1.1] - 2026-02-16

Added

  • Added scripts/discover_skill_catalog.mjs to dynamically discover installable skills from https://clawsec.prompt.security/skills/index.json.
  • Added test/skill_catalog_discovery.test.mjs to validate remote-catalog loading and fallback behavior.
  • Added CI signing-key drift guard script: scripts/ci/verify_signing_key_consistency.sh.

Changed

  • Updated SKILL.md to use dynamic catalog discovery commands instead of hard-coded optional-skill names.
  • Updated advisory feed defaults to signed-host URL (https://clawsec.prompt.security/advisories/feed.json).
  • Improved checksum manifest key compatibility in feed verification logic (supports basename and advisories/* key formats).
  • Kept openclaw-audit-watchdog as a standalone skill (not embedded in clawsec-suite).

Security

  • Signing key drift control: CI now enforces that all public key references (inline SKILL.md PEM, canonical .pem files, workflow-generated keys) resolve to the same fingerprint. Prevents stale, fabricated, or rotated-but-not-propagated key material from reaching releases.
    • Enforced in: .github/workflows/skill-release.yml, .github/workflows/deploy-pages.yml
    • Guard script: scripts/ci/verify_signing_key_consistency.sh

Fixed

  • Fixed fabricated signing key in SKILL.md: The manual installation script contained a hallucinated Ed25519 public key and fingerprint (35866e1b...) that never corresponded to the actual release signing key. Replaced with the real public key derived from the GitHub-secret-held private key. The bogus key was introduced in v0.0.10 (Integration/signing work #20) and went undetected because no consistency check existed at the time.
  • Corrected checksums.sig naming in release verification documentation.

[0.0.10] - 2026-02-11

Security

Transport Security Hardening

  • TLS Version Enforcement: Eliminated support for TLS 1.0 and TLS 1.1, enforcing minimum TLS 1.2 for all HTTPS connections
  • Certificate Validation: Enabled strict certificate validation (rejectUnauthorized: true) to prevent MITM attacks
  • Domain Allowlist: Restricted advisory feed connections to approved domains only:
    • clawsec.prompt.security (official ClawSec feed host)
    • prompt.security (parent domain)
    • raw.githubusercontent.com (GitHub raw content)
    • github.com (GitHub releases)
  • Strong Cipher Suites: Configured modern cipher suites (AES-GCM, ChaCha20-Poly1305) for secure connections

Signature Verification & Checksum Validation

  • Fixed unverified file publication: Refactored deploy-pages.yml workflow to download release assets to temporary directory before signature verification, ensuring unverified files never reach public directory
  • Fixed schema mismatch: Updated deploy-pages.yml to generate checksums.json with proper schema_version and algorithm fields that match parser expectations
  • Fixed missing checksums abort: Updated loadRemoteFeed to gracefully skip checksum verification when checksums.json is missing (e.g., GitHub raw content), while still enforcing fail-closed signature verification
  • Fixed parser strictness: Enhanced parseChecksumsManifest to accept legacy manifest formats through a fallback chain:
    1. schema_version (new standard)
    2. version (skill-release.yml format)
    3. generated_at (old deploy-pages.yml format)
    4. "1" (ultimate fallback)

Changed

  • Advisory feed loader now uses secureFetch wrapper with TLS 1.2+ enforcement and domain validation
  • Checksum verification is now graceful: feeds load successfully from sources without checksums (e.g., GitHub raw) while maintaining fail-closed signature verification
  • Workflow release mirroring flow changed from download → verify → skip to download to temp → verify → mirror (fail = delete temp)

Fixed

  • Unverified skill releases no longer published to public directory on signature verification failure
  • Schema mismatch between generated and expected checksums manifest fields
  • Feed loading failures when checksums.json missing from upstream sources
  • Parser rejection of valid legacy manifest formats

Security Impact

  • Fail-closed security maintained: All feed signatures still verified; invalid signatures reject feed loading
  • No backward compatibility break: Legacy manifests continue working through fallback chain
  • Enhanced transport security: Connections protected against downgrade attacks and MITM
  • Defense in depth: Multiple layers of verification (domain, TLS, certificate, signature, checksum)

Release Notes Template

When creating a new release, copy this template to the GitHub release notes:

## Security Improvements

### Transport Security
✅ TLS 1.2+ enforcement (eliminated TLS 1.0, 1.1)
✅ Strict certificate validation
✅ Domain allowlist (prompt.security, github.com only)
✅ Modern cipher suites (AES-GCM, ChaCha20-Poly1305)

### Signature & Checksum Verification
✅ Unverified files never published (temp directory workflow)
✅ Proper schema fields in generated checksums.json
✅ Graceful fallback when checksums missing (GitHub raw)
✅ Legacy manifest format support (backward compatible)

### Testing
All verification tests passed:
- ✅ Unit tests: 14/14 passed
- ✅ Parser lenience: 3/3 legacy formats accepted
- ✅ Remote loading: Gracefully handles missing checksums
- ✅ Workflow security: Temp directory prevents unverified publication