Add audit-logs download command#195
Conversation
Wraps GET /audit-logs/export/chunk (kernel-go-sdk v0.75.0). Chunks are verified against X-Content-Sha256 before being appended to the output file, and a sidecar state file persists the cursor and committed byte offset so an interrupted download resumes without duplicating rows. Ranges over the API's 30-day cap fail fast with ready-to-run per-window commands. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
--include-get lifts the exclusion. Because chunks are appended verbatim, a second exclusion can't stack client-side the way search filters, so --exclude-method with the GET default active is rejected with guidance rather than silently replacing it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Bind resume state to a credential identity (hashed API key or OAuth org ID) so switching credentials can't mix organizations in one archive - Validate the output file against recorded progress on resume; a missing or shortened file now fails instead of being zero-extended and reported complete - Fail closed on missing X-Has-More and X-Content-Sha256 headers, and validate pagination headers before any bytes are written - Commit initial state before the first fetch so an early failure retries without --force; --force removes stale state immediately - Write state via os.CreateTemp and use 0600/0700 modes for outputs - Cap buffered chunk responses at 256 MiB - Fix stale -o references in errors; document that resume needs explicit --start/--end Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The server controls chunk sizing and every chunk is checksum-verified, so the client-side byte ceiling only added a failure mode. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The params fingerprint already invalidates stale state files, and the state is too short-lived to need format versioning. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ee8ccd4. Configure here.
|
|
sjmiller609
left a comment
There was a problem hiding this comment.
looks good, either as follow up or before merge, maybe you want to test interrupting one of the chunk downloads, e.g. cut your wifi then turn it back on, see if it can retry the missed chunks properly
- Pass option.WithMaxRetries(0) to ExportChunk so the chunk loop exclusively owns retries; the SDK's default two inner retries tripled request volume against 429/5xx responses. - Require --force to overwrite an existing .partial file so a rerun cannot silently truncate a completed download preserved after a finalization failure. - Deduplicate the output writability check and drop a redundant Chmod. - Document the 30-day range limit and add a usage example. - Cover SDK retry suppression against a real httptest server, checksum mismatch recovery, existing-partial protection, rerun after a finalization failure, and the remaining chunk header validations.
Seven total attempts give six retry delays (1+2+4+8+8+8s = 31s); the previous six attempts only backed off for 23 seconds.
1854044 to
58060a0
Compare
Partial files are internal transfer state, not user output; requiring --force to replace one made reruns after an interrupted or partially-finalized download needlessly strict. --force again gates only the final output path.
fang title-cases the first word of error messages, which mangles a
leading path ("/tmp/out.gz" renders as "/Tmp/Out.gz"). Start the
messages with "output" / "partial file" so the path is untouched.
OpenFile's 0600 mode only applies when the file is created; a stale partial reused via O_TRUNC keeps its previous permissions, and the final rename would publish the archive with them. Chmod the partial after opening and assert the published file mode in the stale-partial test.

Summary
Adds
kernel audit-logs downloadfor verified chunked audit-log exports.[start, end)range of at most 30 days.--exclude-methodtogether to the API..partialfile (replacing any stale one from a prior run) and publishes the final.jsonl.gzonly after all chunks complete.--forceis passed; forced replacement happens only during the final rename.Test plan
go test ./...go vet ./...httptestserverNote
Medium Risk
New CLI path writes sensitive audit data to disk with careful partial-file handling; behavior is well tested but touches export APIs and local file I/O.
Overview
Adds
kernel audit-logs downloadfor bulk export of gzip-compressed JSONL over a required exclusive[start, end)window (max 30 days), reusing the same filter flags as search (including default GET exclusion viaauditLogExcludeMethods).The implementation pages through
ExportChunk, validates each response withX-Content-Sha256and pagination headers, and applies its own retry policy (up to 7 attempts, capped backoff; SDK retries disabled) for transient failures. Output is written to a.partialfile with restrictive permissions and only renamed to the final path after all chunks succeed; failed runs drop the partial, and a completed partial is kept if final rename fails.--forceis required to overwrite an existing destination.AuditLogsServicegainsExportChunk; tests cover multi-chunk assembly, retries, checksum/header validation, overwrite semantics, and finalize edge cases.Reviewed by Cursor Bugbot for commit 0cda746. Bugbot is set up for automated code reviews on this repo. Configure here.