Audit log
Every action — login, magic-link hit, file download/upload, package create/revoke/delete, admin operations — is recorded with timestamp, IP, user-agent, and a JSON details blob.
Where to find it
Admin → Settings → Audit log. Or visit /admin/audit directly. Filter by action, paginate, see the full timeline.
Action names
| Action | Source |
|---|---|
login_success | Successful sign-in |
login_fail | Bad password |
self_pw_change | User changed own password |
password_reset_request | Forgot-password email requested |
password_reset_complete | Password reset via emailed link |
admin_create_pkg | Package created via web UI |
admin_add_file | File added to package via web UI |
admin_revoke | Package link revoked |
admin_delete_pkg | Package permanently deleted |
admin_create_user / admin_disable_user / admin_reset_pw | User management |
api_create_pkg / api_add_file / api_revoke / api_delete_pkg | REST API operations |
token_view | Recipient opened the magic-link landing page |
file_download | Recipient downloaded a file |
file_upload_start / file_upload_complete | Inbound upload from recipient |
token_invalid / token_expired / token_revoked | Failed magic-link access (410) |
setup_complete | First-run wizard completed |
What's recorded per row
| Column | Notes |
|---|---|
ts | UTC timestamp (millisecond precision) |
action | One of the names above |
user_id | NULL for magic-link hits (no internal user) |
package_id | NULL for non-package events; preserved after package delete via SET NULL |
ip | Client IP from X-Forwarded-For (when uvicorn trusts the proxy) |
user_agent | For public-route hits only |
details_json | Event-specific extras: {"file_id":"...","size":12345} etc. |
Retention & pruning
No automatic retention policy yet. The table grows linearly with use. For high-volume installations:
- Set up a daily/weekly cron to prune rows older than N days
- Or stream to your SIEM via webhook + drop locally
-- example: keep last 365 days
DELETE FROM access_log WHERE ts < datetime('now', '-365 days');
Exporting
From SQLite:
sqlite3 /data/app.db -header -csv \
"SELECT * FROM access_log WHERE ts > date('now','-30 days')" \
> audit-30d.csv
Or via the REST API (admin-scope token):
curl -H "Authorization: Bearer $TOKEN" \
"https://files.example.com/api/v1/admin/audit?limit=500&action=file_download" | jq
(Note: admin-audit API endpoint is on the roadmap; currently audit is web-UI only.)