Add audit log entry for kubeconfig download events#262
Conversation
The audit log captured "created" and "revoked" grant events but did NOT log
when a user downloads/decrypts a kubeconfig (GET /grants/{id}/download). This
is the most security-relevant action and should be recorded.
Added an AuditLog entry with action="downloaded" in get_grant() when the
download succeeds, including the cluster name in the details field.
Fixes #254
Signed-off-by: Saffron <263493777+itsmiso-ai@users.noreply.github.com>
There was a problem hiding this comment.
AI Automated Review
Full PR review.
Analysis engine: MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic) — escalated (fast_low_confidence)
Recommendation: Approve
This PR directly addresses issue PR 254 by adding audit log entries for kubeconfig download events in the API. The implementation is clean, follows existing patterns, and includes adequate test coverage.
Change-by-Change Findings
1. kubetix-api/kubetix_api/grants/__init__.py (+10 lines)
Adds an AuditLog entry with action="downloaded" inside the get_grant() function, immediately after the kubeconfig is decrypted and before returning the response. The entry records:
user_id— the requesting usergrant_id— the grant being downloadedaction—"downloaded"(consistent with existing"created"and"revoked"action strings)details— descriptive message including the cluster name
Pattern consistency: The implementation mirrors the audit-logging style used by create_grant() (lines 104–111) and revoke_grant() (lines 174–180): construct the AuditLog, db.add(), then db.commit(). The tool harness confirmed this is the established pattern across the codebase.
Placement rationale: The audit write happens after successful decryption, which is the correct gate — only successful downloads are logged. This is analogous to how revoke_grant() commits the audit after revoking, not before.
2. tests/unit/test_api_audit_log.py (+34 lines)
test_audit_log_contains_grant_download: Creates a grant, callsGET /grants/{id}/download, then asserts at least one log entry withaction="downloaded"exists and that the cluster name appears indetails.test_full_lifecycle_audit_trail: Extended to call the download endpoint and assert"downloaded"is present in the audit trail alongside"created"and"revoked", withgrant_idconsistency verified.
Standards Compliance
| Convention | Status |
|---|---|
| Audit action strings are lowercase verbs | ✅ "downloaded" |
Audit logs use db.add() + db.commit() pattern |
✅ Verified against create_grant() and revoke_grant() |
| AuditLog fields: user_id, grant_id, action, details | ✅ All four fields populated |
| Test coverage for new behavior | ✅ Dedicated test + lifecycle integration |
| No credentials hardcoded | ✅ None introduced |
Linked Issue Fit
Issue PR 254 acceptance criteria: "Add an audit log entry with action='downloaded' when GET /grants/{id}/download succeeds."
This PR satisfies the acceptance criteria exactly. The linked issue's evidence (that get_grant() decrypts without logging) is resolved by the new AuditLog write at lines 140–148.
Tool Harness Findings
The tool harness verified the audit-logging pattern across the codebase (db.commit() appears at 24 locations including the new line 148 in grants/__init__.py). The implementation is consistent with established conventions.
CI Check Results
All 9 CI checks passed: e2e-tests, legacy-test, security, lint, test, helm-check, directory-check, frontend-build, build-and-publish.
Unknowns / Needs Verification
None. The implementation is straightforward, the pattern is well-established in the codebase, and CI confirms correctness.
What
Adds an audit log entry in
kubetix_api/grants/__init__.py::get_grant()whenever a user successfully downloads (decrypts) a kubeconfig, and adds tests covering this new behavior.Why
Issue #254 requires that every kubeconfig download be recorded in the audit log s…
Fixes #254
Opened by foreman on review GO (workload wl-misospace-kubetix-254).