Add audit log feature for recording all actions

Adds audit logging that records all authorized actions performed by
users and API keys. The audit log is automatically populated whenever
the authorizer approves an action, and is queryable via GraphQL, MCP,
and CLI interfaces. Permission checks are excluded via a dry-run flag
to avoid phantom entries on page loads.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
Bryan Frimin
2026-03-20 15:42:11 +01:00
parent 000347b1f9
commit 7b320916af
34 changed files with 2546 additions and 13 deletions

View File

@@ -2110,3 +2110,79 @@ func (s OrganizationService) DeleteSCIMBridge(ctx context.Context, organizationI
return nil
}
func (s *OrganizationService) GetAuditLogEntry(
ctx context.Context,
id gid.GID,
) (*coredata.AuditLogEntry, error) {
var (
scope = coredata.NewScopeFromObjectID(id)
entry = &coredata.AuditLogEntry{}
)
err := s.pg.WithConn(
ctx,
func(conn pg.Conn) error {
return entry.LoadByID(ctx, conn, scope, id)
},
)
if err != nil {
return nil, fmt.Errorf("cannot load audit log entry: %w", err)
}
return entry, nil
}
func (s *OrganizationService) ListAuditLogEntries(
ctx context.Context,
organizationID gid.GID,
cursor *page.Cursor[coredata.AuditLogEntryOrderField],
filter *coredata.AuditLogEntryFilter,
) (*page.Page[*coredata.AuditLogEntry, coredata.AuditLogEntryOrderField], error) {
var (
scope = coredata.NewScopeFromObjectID(organizationID)
entries = coredata.AuditLogEntries{}
)
err := s.pg.WithConn(
ctx,
func(conn pg.Conn) error {
if err := entries.LoadAllByOrganizationID(ctx, conn, scope, organizationID, cursor, filter); err != nil {
return fmt.Errorf("cannot load audit log entries: %w", err)
}
return nil
},
)
if err != nil {
return nil, err
}
return page.NewPage(entries, cursor), nil
}
func (s *OrganizationService) CountAuditLogEntries(
ctx context.Context,
organizationID gid.GID,
filter *coredata.AuditLogEntryFilter,
) (int, error) {
var (
scope = coredata.NewScopeFromObjectID(organizationID)
count int
)
err := s.pg.WithConn(
ctx,
func(conn pg.Conn) (err error) {
entries := coredata.AuditLogEntries{}
count, err = entries.CountByOrganizationID(ctx, conn, scope, organizationID, filter)
if err != nil {
return fmt.Errorf("cannot count audit log entries: %w", err)
}
return nil
},
)
return count, err
}