Repository navigation
v0.7.0 — RBAC and Audit Log
Release Notes — v0.7.0
Released: 2026-05-20
Overview
v0.7.0 adds role-based access control and a full audit trail, making AutoFlowOps suitable for small teams where different members need different levels of access and where a history of sensitive operations is required for accountability.
What's New
Role-Based Access Control
Three roles are now enforced server-side on every endpoint:
| Role | Who it's for |
|---|---|
admin |
Full access — user management, audit logs, all configuration |
operator |
Day-to-day work — create/run jobs, manage webhooks, ack alerts, test channels, generate reports |
viewer |
Read-only visibility into all domain data |
Role checks use FastAPI dependency injection (require_admin, require_operator) applied per-endpoint. The frontend reflects these boundaries through AdminRoute (blocks non-admins from /users and /audit-logs) and computed isAdmin/isOperator booleans in AuthContext.
User Management
Admins can now manage all user accounts through the UI or API:
- List users —
GET /api/users - Create user —
POST /api/users(sets email, name, password, role) - Update user —
PATCH /api/users/{id}(role, active status, name) - Reset password —
POST /api/users/{id}/reset-password - Delete user —
DELETE /api/users/{id}
Self-protection: the API refuses to deactivate or delete the last active admin account.
The Users page in the frontend provides all of the above through a table with inline controls.
Audit Log
Every sensitive action now produces an audit record in the audit_logs database table. Each record captures:
- Who performed the action (
user_id, nullable for failed logins) - What was done (
action— e.g.job.create,auth.login_failure) - What resource was affected (
resource_type,resource_id) - Whether it succeeded (
status) - Where the request came from (
ip_address,user_agent) - Additional context (
metadata) — with sensitive fields replaced by"[redacted]"
Admins can view and filter the log at GET /api/audit-logs (filters: user_id, action, resource_type, status, since, until, limit) or through the Audit Logs page in the frontend.
Audit Coverage
The following actions are logged automatically:
auth.login_success/auth.login_failurejob.create/job.update/job.delete/job.runwebhook.create/webhook.update/webhook.delete/webhook.reprocessalert.acknowledge/alert.resolvenotification_channel.create/.update/.delete/.activate/.deactivate/.testnotification_template.create/.update/.deleteescalation_policy.create/.update/.delete/.add_step/.delete_stepreport.generateuser.create/user.update/user.delete/user.reset_password
Last Login Tracking
The users table now records last_login_at, updated on every successful login. This is visible in the Users page.
Frontend Changes
- Users page (
/users) — admin-only; user table with name, email, role selector, status badge, last login, created date; inline password reset form; activate/deactivate; delete - Audit Logs page (
/audit-logs) — admin-only; filter controls for action, resource type, status and date range; paginated log table showing timestamp, actor, action, resource, status and IP - Sidebar — Users and Audit Logs navigation items visible only to admins; role label shown in the footer for the signed-in user
AdminRoute— route guard that redirects non-authenticated users to/loginand authenticated non-admins to/
Test Coverage
| Suite | Tests | Status |
|---|---|---|
| RBAC tests (backend) | 20 | Passing |
| Audit log tests (backend) | 5 | Passing |
| User management tests (backend) | 9 | Passing |
| UsersPage tests (frontend) | 4 | Passing |
| AuditLogsPage tests (frontend) | 4 | Passing |
| Total backend | 209 | Passing |
| Total frontend | 65 | Passing |
Migration Notes
New table: audit_logs
The audit_logs table is created automatically by Base.metadata.create_all on backend startup. No manual step is required for fresh deployments.
New column: users.last_login_at
create_all does not add columns to existing tables. If upgrading an existing deployment without Alembic:
ALTER TABLE users ADD COLUMN last_login_at TIMESTAMPTZ;Run this against your PostgreSQL database before starting the new backend version.
Default role change
New users created via POST /api/users default to "viewer". If your deployment previously relied on the internal "user" role string, update any references to use "viewer".
Upgrade Steps
- Pull the new image or rebuild:
docker compose build - If upgrading an existing database, run the
ALTER TABLEstatement above. - Start services:
docker compose up -d - Log in as admin, verify the Users and Audit Logs pages are accessible.
- Create an
operatoraccount for day-to-day work if desired. - Verify audit log entries appear after performing a sensitive action.
Known Limitations
- The audit log is append-only by convention. Direct database access bypasses the trail.
last_login_atrequires a manualALTER TABLEon existing deployments (see above).- JWT tokens issued before this upgrade remain valid until expiry; no token invalidation is performed during upgrade.