Files
orca/internal/engine/audit.go
T
Jon Chery b25e074e1d feat(P04): audit log + persistence hardening
Implements Phase 4 of v0.1 Foundation:
- internal/store/migrations/0003_audit_log.sql: audit_log table with indexes
- internal/store/audit_repo.go: AuditRepo (Append + List)
- internal/store/audit_repo_test.go: 2 tests for audit persistence
- internal/engine/audit.go: Audit wrapper that persists to SQLite AND logs via slog
- internal/cli/audit.go: orca audit list command (text + JSON)
- Registry now records every join/leave/forget with actor/action/resource/result

Verified: audit entries persist across restarts, JSON output includes metadata,
node operations emit audit records. All tests pass with -race.

---ci---
project: orca
phase: 4
milestone: v0.1
status: execute
req_covered:
  - REQ-005
  - REQ-006
  - REQ-008
  - REQ-017
  - REQ-018
---/ci---
2026-06-03 12:48:31 +00:00

53 lines
1.2 KiB
Go

package engine
import (
"context"
"log/slog"
"git.cloudinit.dev/coreci/orca/internal/store"
)
// Audit wraps a slog.Logger and persists structured audit entries to SQLite.
type Audit struct {
repo *store.AuditRepo
log *slog.Logger
}
func NewAudit(repo *store.AuditRepo, log *slog.Logger) *Audit {
if log == nil {
log = slog.Default()
}
return &Audit{repo: repo, log: log}
}
func (a *Audit) Record(ctx context.Context, actor, action, resource, result string, err error, meta map[string]any) {
entry := &store.AuditEntry{
Actor: actor,
Action: action,
Resource: resource,
Result: result,
Metadata: meta,
}
if err != nil {
entry.Error = err.Error()
}
if persistErr := a.repo.Append(ctx, entry); persistErr != nil {
a.log.Error("audit persist failed",
slog.String("action", action),
slog.String("resource", resource),
slog.String("error", persistErr.Error()))
}
attrs := []any{
slog.String("actor", actor),
slog.String("action", action),
slog.String("resource", resource),
slog.String("result", result),
}
if err != nil {
attrs = append(attrs, slog.String("error", err.Error()))
a.log.Warn("audit", attrs...)
} else {
a.log.Info("audit", attrs...)
}
}