Skip to content

Add CloudTrail S3 admin audit helper#75

Open
jamilahmadzai wants to merge 2 commits into
BAWES-Universe:masterfrom
jamilahmadzai:security/cloudtrail-s3-admin-audit
Open

Add CloudTrail S3 admin audit helper#75
jamilahmadzai wants to merge 2 commits into
BAWES-Universe:masterfrom
jamilahmadzai:security/cloudtrail-s3-admin-audit

Conversation

@jamilahmadzai
Copy link
Copy Markdown

@jamilahmadzai jamilahmadzai commented May 14, 2026

/claim #55

Summary

  • add an offline CloudTrail S3 bucket-admin audit CLI for maintainer-exported JSON
  • generate redacted Markdown/CSV reports for high-risk bucket control events, scoped by bucket prefix and IAM user
  • document usage and add a synthetic fixture/regression check

Safety boundary

No live AWS/IAM calls, bucket policy changes, key rotation, candidate data, raw CloudTrail exports, account IDs, access keys, or secret keys are included. The report prints access-key suffixes only.

Verification

  • node tools/check-cloudtrail-s3-admin-audit.mjs
  • node tools/audit-cloudtrail-s3-admin-events.mjs tools/fixtures/cloudtrail-s3-admin-events.sample.json --format csv
  • git diff --check HEAD~1

Summary by CodeRabbit

  • New Features

    • CLI audit tool for CloudTrail S3 admin events with Markdown/CSV output, file/directory input, optional file write, and filters for bucket prefixes and IAM users
    • Reports redact access key identifiers (last four chars only)
  • Documentation

    • Guide with command examples, supported input shapes, and privacy guidance for offline audits
  • Tests

    • Built-in validation check using a bundled fixture plus a negative test to ensure parsing errors fail cleanly

Review Change Stack

Payout

PayPal: jamilurrehman722@gmail.com (if a direct payout method is needed).
Payment method: Algora bounty-platform payout to GitHub user @jamilahmadzai for issue #55.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

📝 Walkthrough

Walkthrough

This PR introduces a complete offline CloudTrail S3 admin event auditing workflow: a Node.js CLI script that parses CloudTrail JSON exports, filters for bucket-admin events, and renders Markdown or CSV reports; a test fixture with representative events; a verification script that validates audit output against expected content; and user documentation describing scope, usage, privacy redaction, and how to verify the tool via the synthetic fixture.

Changes

CloudTrail S3 Admin Audit Feature

Layer / File(s) Summary
Audit Script Implementation
tools/audit-cloudtrail-s3-admin-events.mjs
CLI parses command-line arguments (format, output path, bucket-prefix/user filters), recursively discovers .json files, normalizes different CloudTrail JSON shapes into consistent records, filters by S3 admin API allowlist with optional bucket/user matching, projects key fields (timestamp, event, user, access-key suffix, bucket, error code), sorts events, and renders either Markdown (with API/user summaries and event table) or CSV (with fixed column order and proper escaping).
Test Fixture and Verification
tools/fixtures/cloudtrail-s3-admin-events.sample.json, tools/check-cloudtrail-s3-admin-audit.mjs
Fixture contains 5 representative S3 CloudTrail events (including scope and out-of-scope types). Check script executes the audit tool against the fixture, validates Markdown includes expected event names, verifies CSV header and structure, and asserts out-of-scope events (PutObject) and unrelated buckets are excluded.
Audit Tool Documentation
docs/security/cloudtrail-s3-admin-audit.md
User guide documents event scope, command usage with optional flags, supported input export formats (CloudTrail Records, raw arrays, single events, Event History), privacy boundary (raw exports not committed, access keys redacted to last 4 chars), and how to run the synthetic fixture check.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A rabbit hops through CloudTrail logs today,
Sniffing out S3 admin leaks and play,
Bucket configs filtered, access keys redacted tight,
CSV and Markdown reports burning bright,
Security audits hopping left and right! 🔐

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a CloudTrail S3 admin audit helper tool with documentation, scripts, and fixtures.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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

@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: 1

🤖 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 `@tools/audit-cloudtrail-s3-admin-events.mjs`:
- Around line 112-113: The JSON.parse in function readRecords can throw without
indicating which file failed; wrap the parse in a try/catch around
JSON.parse(fs.readFileSync(filePath, "utf8")) inside readRecords, and on error
either throw a new Error that includes the filePath and the original error
message (e.g., `new Error(\`Failed to parse JSON for ${filePath}:
${err.message}\`)`) or log the filePath plus err before rethrowing so callers
can identify the bad file; ensure you preserve the original error stack/message
when rethrowing.
🪄 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: 7ecbfafc-e46b-4ac5-b522-c1e745e00453

📥 Commits

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

📒 Files selected for processing (4)
  • docs/security/cloudtrail-s3-admin-audit.md
  • tools/audit-cloudtrail-s3-admin-events.mjs
  • tools/check-cloudtrail-s3-admin-audit.mjs
  • tools/fixtures/cloudtrail-s3-admin-events.sample.json

Comment thread tools/audit-cloudtrail-s3-admin-events.mjs Outdated
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.

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

45-60: ⚡ Quick win

Harden the negative-test flow and always clean temporary fixtures.

The current try/catch catches its own sentinel failure path, which can blur diagnostics, and the temp dir is never removed.

Proposed patch
 const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "studenthub-cloudtrail-"));
 const invalidFixture = path.join(tempDir, "invalid.json");
 fs.writeFileSync(invalidFixture, "{not-json");

-try {
-  execFileSync(process.execPath, [auditScript, invalidFixture], {
-    encoding: "utf8",
-    stdio: ["ignore", "pipe", "pipe"],
-  });
-  throw new Error("Expected invalid JSON input to fail");
-} catch (error) {
-  const stderr = String(error.stderr ?? "");
-  if (!stderr.includes("Failed to parse JSON") || !stderr.includes(invalidFixture)) {
-    throw new Error("Invalid JSON errors should include the failing file path");
-  }
-}
+let invalidRunError;
+try {
+  execFileSync(process.execPath, [auditScript, invalidFixture], {
+    encoding: "utf8",
+    stdio: ["ignore", "pipe", "pipe"],
+  });
+} catch (error) {
+  invalidRunError = error;
+} finally {
+  fs.rmSync(tempDir, { recursive: true, force: true });
+}
+
+if (!invalidRunError) {
+  throw new Error("Expected invalid JSON input to fail");
+}
+
+const stderr = String(invalidRunError.stderr ?? "");
+if (!stderr.includes("Failed to parse JSON") || !stderr.includes(invalidFixture)) {
+  throw new Error("Invalid JSON errors should include the failing file path");
+}
🤖 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 45 - 60, The negative
test currently throws a sentinel error inside the try block and then catches it,
and it never cleans up tempDir; change the flow to track whether execFileSync
failed (e.g., let execFailed = false), run execFileSync(process.execPath,
[auditScript, invalidFixture], ...) inside try and set execFailed = true in the
catch where you validate stderr includes "Failed to parse JSON" and
invalidFixture, and after the try/catch throw a failure if execFailed is false
(meaning the command unexpectedly succeeded); ensure you always remove the
temporary fixture and directory in a finally block using fs.rmSync(tempDir, {
recursive: true, force: true }) or equivalent; refer to the existing symbols
tempDir, invalidFixture, execFileSync, and the stderr validation code when
applying this change.
🤖 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.

Nitpick comments:
In `@tools/check-cloudtrail-s3-admin-audit.mjs`:
- Around line 45-60: The negative test currently throws a sentinel error inside
the try block and then catches it, and it never cleans up tempDir; change the
flow to track whether execFileSync failed (e.g., let execFailed = false), run
execFileSync(process.execPath, [auditScript, invalidFixture], ...) inside try
and set execFailed = true in the catch where you validate stderr includes
"Failed to parse JSON" and invalidFixture, and after the try/catch throw a
failure if execFailed is false (meaning the command unexpectedly succeeded);
ensure you always remove the temporary fixture and directory in a finally block
using fs.rmSync(tempDir, { recursive: true, force: true }) or equivalent; refer
to the existing symbols tempDir, invalidFixture, execFileSync, and the stderr
validation code when applying this change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cdebb631-dd46-4b51-a303-4e6cf6dca8d4

📥 Commits

Reviewing files that changed from the base of the PR and between cfa6fd8 and 93537b5.

📒 Files selected for processing (2)
  • tools/audit-cloudtrail-s3-admin-events.mjs
  • tools/check-cloudtrail-s3-admin-audit.mjs
🚧 Files skipped from review as they are similar to previous changes (1)
  • tools/audit-cloudtrail-s3-admin-events.mjs

@jamilahmadzai jamilahmadzai force-pushed the security/cloudtrail-s3-admin-audit branch from 93537b5 to d9eee09 Compare May 15, 2026 00:22
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