Skip to content

Add CloudTrail S3 admin audit helper#90

Open
souf92i wants to merge 4 commits into
BAWES-Universe:masterfrom
souf92i:codex-cloudtrail-s3-admin-audit
Open

Add CloudTrail S3 admin audit helper#90
souf92i wants to merge 4 commits into
BAWES-Universe:masterfrom
souf92i:codex-cloudtrail-s3-admin-audit

Conversation

@souf92i
Copy link
Copy Markdown

@souf92i souf92i commented May 15, 2026

/claim #55

Summary

  • Adds an offline CloudTrail S3 admin-event audit helper for the Phase 7 compromise-assessment path.
  • Filters the exact risky bucket-admin event types listed in the issue, including lifecycle, CORS, policy, replication, logging, and public-access-block changes.
  • Summarizes matching events by event name, IAM user, bucket, severity, key suffix, source IP, user agent, region, and error code.
  • Redacts full AWS access key IDs and secret-shaped values while preserving the last four key characters needed for the incident evidence package.
  • Documents the operator workflow and includes a synthetic fixture verifier for JSON and CSV exports.

Scope

This is a separate Phase 7 CloudTrail audit slice. It does not overlap with the existing Civil ID backend/frontend fixes, S3 env-var credential PRs, n8n workflow audit, bucket guardrail audit, or secret-scanning PRs.

No live AWS/IAM/S3 calls were made. No CloudTrail exports, key rotation/deletion, bucket policy changes, candidate records, or credential material are included.

Verification

  • node tools/check-cloudtrail-s3-admin-audit.mjs
  • node --check tools/audit-cloudtrail-s3-admin-events.mjs
  • node --check tools/check-cloudtrail-s3-admin-audit.mjs
  • git diff --check

The repo's documented full suite command currently fails before test bootstrap because run-tests.sh invokes docker-compose without a compose file, while this checkout only includes named compose files such as docker-compose-local.yml, docker-compose-dev.yml, and docker-compose-prod.yml.

Summary by CodeRabbit

  • New Features

    • CloudTrail S3 admin event auditing capability for detecting suspicious bucket activity in exported logs
    • Support for JSON, JSONL, and CSV input formats with Markdown and CSV report outputs
    • Automatic event severity classification and credential redaction
  • Documentation

    • Comprehensive guide with usage examples and input format specifications
  • Tests

    • Added validation tests for audit functionality

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

Warning

Rate limit exceeded

@souf92i has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 8 minutes and 30 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1d11f211-05fd-449f-be10-aef477943f92

📥 Commits

Reviewing files that changed from the base of the PR and between 444d363 and 75dc587.

📒 Files selected for processing (3)
  • docs/cloudtrail-s3-admin-audit.md
  • tools/audit-cloudtrail-s3-admin-events.mjs
  • tools/check-cloudtrail-s3-admin-audit.mjs
📝 Walkthrough

Walkthrough

This PR introduces a complete offline CloudTrail S3 admin event audit tool. The implementation reads CloudTrail exports in JSON, JSONL, or CSV format, detects suspicious S3 bucket-admin events from a curated event name allowlist, assigns severity based on error codes and event types, and generates Markdown or CSV reports with credential redaction. Documentation and end-to-end tests verify the tool's input handling, event filtering, and output formatting.

Changes

CloudTrail Audit Implementation

Layer / File(s) Summary
CLI entry point and input parsing
tools/audit-cloudtrail-s3-admin-events.mjs
Sets up suspicious S3 event names and default watch users, parses --input, --watch-user, --format, and --help arguments with validation, and loads offline CloudTrail exports in JSON, JSONL, and CSV formats with automatic format detection.
Event normalization and detection
tools/audit-cloudtrail-s3-admin-events.mjs
Extracts and normalizes event fields (timestamp, event name, user, access key, IP, bucket, region, error code), infers bucket names from resource ARNs, filters events matching the suspicious allowlist, assigns severity levels, and builds review notes for watched users and non-standard bucket names.
Report generation (CSV and Markdown)
tools/audit-cloudtrail-s3-admin-events.mjs
Aggregates event counts by event name, user, and bucket; outputs CSV format with credential redaction; renders Markdown report with summary sections and event table; provides escaping and redaction helpers for both formats.
Main control flow and error handling
tools/audit-cloudtrail-s3-admin-events.mjs
Orchestrates argument parsing, file loading, event classification, and report output; catches errors with user feedback and usage message; sets non-zero exit code on failure; executes the main function.

Documentation and Verification

Layer / File(s) Summary
User guide documentation
docs/cloudtrail-s3-admin-audit.md
Documents the incident scope, specific S3 bucket-admin events to flag, supported input formats with expected CSV columns, command-line usage for report generation and adding watched users, output expectations including key redaction (last four characters), and fixture test verification steps.
End-to-end verification test
tools/check-cloudtrail-s3-admin-audit.mjs
Creates synthetic CloudTrail JSON and CSV fixtures, invokes the audit tool in Markdown and CSV modes, validates event counts, severity levels, event names, user identities, access-key suffix formatting, and confirms sensitive values are redacted or absent from output.

Sequence Diagram

sequenceDiagram
  participant CLI as CLI Arguments
  participant Parser as Input Parser
  participant Normalizer as Event Normalizer
  participant Detector as Event Detector
  participant Reporter as Report Generator
  CLI->>Parser: File paths, format, watched users
  Parser->>Parser: Auto-detect JSON/JSONL/CSV
  Parser->>Normalizer: Raw CloudTrail events
  Normalizer->>Normalizer: Extract fields, infer buckets
  Normalizer->>Detector: Normalized event shape
  Detector->>Detector: Filter suspicious names
  Detector->>Detector: Assign severity, build notes
  Detector->>Reporter: Classified events
  Reporter->>Reporter: Aggregate counts
  Reporter->>Reporter: Redact credentials
  Reporter->>CLI: Markdown or CSV report
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A new audit tool hops through CloudTrail logs so vast,
Sniffing out S3 admin events both present and past,
JSON, JSONL, CSV—it reads them all with ease,
Redacting secrets swiftly and sorting with such breeze!
Reports in Markdown, CSV too—let the auditing spree flow free! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Add CloudTrail S3 admin audit helper' directly and clearly summarizes the main change—introduction of a new CloudTrail S3 admin audit helper tool with documentation and testing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

Copy link
Copy Markdown
Author

souf92i commented May 15, 2026

Pushed a small follow-up in souf92i:codex-cloudtrail-s3-admin-audit (444d3630) to make the smoke verifier path handling portable by using fileURLToPath(...) instead of URL.pathname.

Verification run locally:

  • node tools/check-cloudtrail-s3-admin-audit.mjs
  • node --check tools/audit-cloudtrail-s3-admin-events.mjs
  • node --check tools/check-cloudtrail-s3-admin-audit.mjs
  • git diff --check

The repository wrapper sh run-tests.sh is still blocked in this checkout by Docker Compose returning no configuration file provided: not found, so the targeted helper checks above are the relevant passing verification for this PR.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
tools/check-cloudtrail-s3-admin-audit.mjs (1)

16-97: ⚡ Quick win

Expand fixture/assertion coverage to the full risky-event matrix.

Current checks exercise only a subset of flagged event names, and CSV-output mode is validated only with JSON input. Please add synthetic cases for the remaining risky event names and include at least one --format csv run that ingests CSV input too, so allowlist and parser regressions are caught early.

🤖 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 `@tools/check-cloudtrail-s3-admin-audit.mjs` around lines 16 - 97, Add
synthetic events covering every risky event name to the test fixtures and add a
CSV-format invocation that uses the csvInput fixture: extend the JSON written by
writeFileSync(jsonInput, ...) to include records for the remaining flagged
eventNames (e.g., PutBucketAcl, PutBucketPolicy, PutBucketCors, PutObjectAcl,
etc.) and ensure corresponding assertions (using
assert.match/assert.doesNotMatch) check counts and severity labels for those
names; also add a second execFileSync call that runs script with '--format',
'csv' and '--input', csvInput (not just JSON) and assert the CSV output contains
expected headers and rows and redacted access key suffixes, mirroring the
existing JSON CSV assertions so parser/allowlist regressions are caught.
tools/audit-cloudtrail-s3-admin-events.mjs (1)

104-109: ⚖️ Poor tradeoff

Consider narrowing the JSONL fallback condition.

The broad catch on line 104 treats any JSON parse error as a JSONL file, but the nested JSON.parse(line) on line 108 is not wrapped in a try-catch. If the initial parse failed due to malformed JSON rather than JSONL format, the line-by-line parse will likely throw an uncaught error with a less helpful message.

🤖 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 `@tools/audit-cloudtrail-s3-admin-events.mjs` around lines 104 - 109, The catch
is too broad: when JSON.parse(raw) fails we should only treat the input as JSONL
if the error is a SyntaxError and raw contains newlines, and we must guard the
per-line JSON.parse, e.g. inside the JSONL fallback wrap JSON.parse(line) with a
try/catch (or use a safeParse helper) and either skip/bubble malformed lines or
collect/log parse errors before calling normalizeEvent; update the block
handling raw, JSON.parse, normalizeEvent, and the JSONL mapping so malformed
individual lines don't throw uncaught exceptions.
🤖 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 `@docs/cloudtrail-s3-admin-audit.md`:
- Line 3: Replace the ambiguous incident range "Apr 17-19" used in Issue `#55`
Phase 7 with an explicit date-time range including year and timezone (for
example "2026-04-17T00:00:00Z to 2026-04-19T23:59:59Z UTC"); update the
CloudTrail export instructions that mention "export CloudTrail events for the
suspicious Apr 17-19 window" so they reference the full ISO-8601 timestamps and
specified timezone to ensure operators export the correct window when reviewing
whether service IAM users performed bucket-admin operations.

In `@tools/audit-cloudtrail-s3-admin-events.mjs`:
- Around line 57-59: The conditional that checks if args.watchUsers ===
DEFAULT_USERS and reassigns args.watchUsers to new Set(DEFAULT_USERS) is dead
code because args.watchUsers is already initialized as new Set(DEFAULT_USERS);
remove the entire if block referencing args.watchUsers and DEFAULT_USERS (the
identity comparison and reassignment) to eliminate dead code and keep the
already-safe clone behavior from the earlier initialization of args.watchUsers.
- Line 19: The ACCESS_KEY_PATTERN constant currently uses an incorrect regex
(/AKIA[0-9A-Z]{12,20}/g); update it to match AWS access key format by
restricting the character set to base32 and the length to the standard
20-character key (AKIA + 16 chars) or the full AWS range if desired — for
example replace ACCESS_KEY_PATTERN with a regex like /AKIA[2-7A-Z]{16}/g for
standard keys or /AKIA[2-7A-Z]{16,128}/g to allow the full documented range.

---

Nitpick comments:
In `@tools/audit-cloudtrail-s3-admin-events.mjs`:
- Around line 104-109: The catch is too broad: when JSON.parse(raw) fails we
should only treat the input as JSONL if the error is a SyntaxError and raw
contains newlines, and we must guard the per-line JSON.parse, e.g. inside the
JSONL fallback wrap JSON.parse(line) with a try/catch (or use a safeParse
helper) and either skip/bubble malformed lines or collect/log parse errors
before calling normalizeEvent; update the block handling raw, JSON.parse,
normalizeEvent, and the JSONL mapping so malformed individual lines don't throw
uncaught exceptions.

In `@tools/check-cloudtrail-s3-admin-audit.mjs`:
- Around line 16-97: Add synthetic events covering every risky event name to the
test fixtures and add a CSV-format invocation that uses the csvInput fixture:
extend the JSON written by writeFileSync(jsonInput, ...) to include records for
the remaining flagged eventNames (e.g., PutBucketAcl, PutBucketPolicy,
PutBucketCors, PutObjectAcl, etc.) and ensure corresponding assertions (using
assert.match/assert.doesNotMatch) check counts and severity labels for those
names; also add a second execFileSync call that runs script with '--format',
'csv' and '--input', csvInput (not just JSON) and assert the CSV output contains
expected headers and rows and redacted access key suffixes, mirroring the
existing JSON CSV assertions so parser/allowlist regressions are caught.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro

Run ID: bd77db9d-9e17-4526-8638-68d4ef83d5e3

📥 Commits

Reviewing files that changed from the base of the PR and between 7b023ff and 444d363.

📒 Files selected for processing (3)
  • docs/cloudtrail-s3-admin-audit.md
  • tools/audit-cloudtrail-s3-admin-events.mjs
  • tools/check-cloudtrail-s3-admin-audit.mjs

Comment thread docs/cloudtrail-s3-admin-audit.md Outdated
Comment thread tools/audit-cloudtrail-s3-admin-events.mjs Outdated
Comment thread tools/audit-cloudtrail-s3-admin-events.mjs Outdated
Copy link
Copy Markdown
Author

souf92i commented May 15, 2026

Pushed follow-up 0cbbbca3 for the latest review comments.

Changes:

  • Made the incident window explicit as 2026-04-17T00:00:00Z to 2026-04-19T23:59:59Z UTC in the CloudTrail audit docs.
  • Tightened the AWS access-key redaction pattern to fixed-length AKIA[2-7A-Z]{16} and updated synthetic fixtures to continue exercising redaction.
  • Removed the dead watchUsers === DEFAULT_USERS branch in argument parsing.

Verification:

  • node tools/check-cloudtrail-s3-admin-audit.mjs
  • node --check tools/audit-cloudtrail-s3-admin-events.mjs
  • node --check tools/check-cloudtrail-s3-admin-audit.mjs
  • git diff --check

The repo-level sh run-tests.sh remains blocked by the local Docker Compose issue: no configuration file provided: not found.

Copy link
Copy Markdown
Author

souf92i commented May 16, 2026

Pushed follow-up 75dc5873 for the remaining CodeRabbit feedback.

Changes:

  • Narrowed JSONL fallback so valid-but-wrong JSON shapes now fail with the explicit Records array message instead of being treated as JSONL.
  • Wrapped JSONL per-line parsing with a line-numbered error for malformed lines.
  • Expanded the verification fixture to cover the full current risky S3 admin event matrix and added a CSV-output run that reads CSV input.
  • Fixed a redaction false positive where long event names such as PutBucketReplicationConfiguration could be masked as secret-shaped text.

Verification:

  • node tools/check-cloudtrail-s3-admin-audit.mjs
  • node --check tools/audit-cloudtrail-s3-admin-events.mjs
  • node --check tools/check-cloudtrail-s3-admin-audit.mjs
  • git diff --check

Repo-level sh run-tests.sh is still blocked locally by Docker Compose config: no configuration file provided: not found.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant