feat(audit): emit user-management and file-lifecycle events#62
Merged
Conversation
routes/users.rs and routes/files.rs were the largest remaining gap in the
production audit chain: user CRUD, role mutations, password changes, and
every file upload/scan/download path produced zero durable chain entries.
Tracing-only events don't satisfy NIST 800-53 AU-2 for high-sensitivity
admin operations or CUI access.
routes/users.rs:
forge.user.created create_user success
forge.user.deleted delete_user success
forge.user.updated update_user success (roles/display_name)
forge.user.active_toggled update_user success (active flag)
forge.access.denied every Cedar role-rank guard deny
auth.password.changed change_password success (built-in kind)
forge.user.password_changed change_password success (carries actor +
self-service flag — the built-in kind
only carries the target)
routes/files.rs:
forge.file.upload_minted mint_upload_url success
forge.file.uploaded confirm_upload success
forge.file.scan_complete scan_complete success (Warning severity
when quarantined; Notice when clean)
forge.file.downloaded download_file success
A small `audit_user` / `audit_file` helper centralises actor / target /
metadata shape; `FileTarget` packs the schema/entity/field triple so the
audit_file signature stays under clippy's too_many_arguments ceiling.
Second of four PRs from the production-audit gap review. Follows
#61 (auth audit events + last_login). C and D coming next.
3 tasks
3 tasks
rrrodzilla
added a commit
that referenced
this pull request
May 26, 2026
Release rolling up the production-audit gap PRs (#61, #62, #63, #64). BREAKING (pre-1.0 minor): schema-forge-backend 0.11 → 0.12 AuthStore trait gains required `record_login(username, at)` method. Downstream impls must add it. schema-forge-acton 0.30 → 0.31 DynAuthStore trait gains required `record_login` shim. `access::filter_entity_fields` now returns `Vec<String>` (dropped field names) instead of `()`. Callers binding the return value must update.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
forge.user.*events for every user-management mutation (create / delete / update / role change / active toggle) andforge.access.deniedfor every Cedar role-rank guard deny inroutes/users.rs.auth.password.changedaudit kind plus aforge.user.password_changedcustom event (carries actor +self_serviceflag so admin resets and self-service rotations are distinguishable in the chain).forge.file.{upload_minted,uploaded,scan_complete,downloaded}for the four file-lifecycle paths inroutes/files.rs. Quarantined scan outcomes get Warning severity so the chain is easy to triage during an incident.audit_user/audit_filehelper per module to keep emission shape consistent and stay under clippy'stoo_many_argumentsceiling (FileTargetpacks schema/entity/field).Second of four PRs from the production-audit gap review. Follows #61 (
last_login+ auth audit events). #C and #D coming next.Test plan
cargo nextest run --workspace --features schema-forge-acton/surrealdb— 1680 passedcargo clippy --workspace --features schema-forge-acton/surrealdb --all-targets— clean