AUD-06: audit-log-verdrahtung-in-sicherheitsrelevante-core-handler
Supply-Chain-Scan (Go) / govulncheck (push) Canceled after 0s

Schliesst die in QA-05 gefundene Luecke: der zentrale Audit-Log (AUD-01/02)
existierte und war getestet, wurde aber von keinem Produktions-Handler
befuellt. Additive WithAudit(...)-Methode je Store (Konvention aus
lockout.Store.WithPolicy uebernommen, audit==nil bleibt gueltig, kein
Verhaltensbruch fuer bestehende Aufrufer):

- internal/policy.Store.Grant/Revoke -> policy.grant/policy.revoke
- internal/tenant.Registry (Suspend/Reactivate/ScheduleDeletion/
  CancelDeletion via transition) -> tenant.transition
- internal/lockout.Store.RecordFailure/Unlock -> auth.login_failed/
  auth.account_locked/auth.account_unlocked
- internal/kek.Store.RotateTenantKEK/RotateMasterKey -> kek.tenant_rotated/
  kek.master_rotated

Neues Testpaket internal/audit/wiring_test.go: fuer jeden der vier Bereiche
eine reale Aktion ausgefuehrt und per direkter audit_events-Abfrage
nachgewiesen (derselbe Nachweisstil wie der QA-05-Stichprobenabgleich, der
die Luecke fand). Alle bestehenden Tests der vier Pakete bleiben gruen.
51/51 Pakete gruen auf 192.168.1.131.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
This commit is contained in:
sysops
2026-08-29 17:24:26 +02:00
co-authored by Claude Sonnet 5
parent d8d5aaf3bc
commit 4de9310213
7 changed files with 447 additions and 6 deletions
+30 -2
View File
@@ -11,6 +11,7 @@ import (
"github.com/jackc/pgx/v5/pgxpool"
"gitea.perlbach24.de/scripte/nexarch/internal/audit"
"gitea.perlbach24.de/scripte/nexarch/internal/rbac"
)
@@ -33,13 +34,22 @@ type RuleChange struct {
// Datenbank — es gibt keinen hartcodierten Go-Fallback, ein Regelwechsel
// wirkt sich ohne Codeaenderung sofort aus (Akzeptanzkriterium 2 / 3).
type Store struct {
pool *pgxpool.Pool
pool *pgxpool.Pool
audit *audit.Log
}
func NewStore(pool *pgxpool.Pool) *Store {
return &Store{pool: pool}
}
// WithAudit liefert einen Store, der jede Regelaenderung zusaetzlich im
// zentralen, unveraenderlichen Audit-Log (AUD-01/AUD-02) protokolliert
// (AUD-06) — rein additiv, aendert nichts am Verhalten ohne gesetzten
// Audit-Log (log == nil bleibt gueltig, z.B. in bestehenden Tests).
func (s *Store) WithAudit(log *audit.Log) *Store {
return &Store{pool: s.pool, audit: log}
}
// IsAllowed prueft, ob role das Recht permission besitzt. Default-Deny:
// existiert keine passende Regel, ist der Zugriff verboten
// (Akzeptanzkriterium 2 / Pruefung 2) — es gibt keinen impliziten
@@ -97,7 +107,25 @@ func (s *Store) change(ctx context.Context, role rbac.Role, perm rbac.Permission
return fmt.Errorf("historie schreiben: %w", err)
}
return tx.Commit(ctx)
if err := tx.Commit(ctx); err != nil {
return err
}
// Audit-Log-Eintrag NACH dem Commit (AUD-06): die Regelaenderung selbst
// ist bereits dauerhaft, ein Fehler beim Audit-Log darf die eigentliche
// Aktion nicht rueckgaengig machen oder blockieren — nur protokolliert,
// nicht scharf gemacht (dasselbe Prinzip wie bei den anderen hier
// verdrahteten Stellen).
if s.audit != nil {
_ = s.audit.Record(ctx, audit.Event{
TenantSlug: audit.SystemTenant,
Actor: actor,
Action: "policy." + action,
Target: fmt.Sprintf("%s:%s", role, perm),
})
}
return nil
}
// History liefert die vollstaendige, versionierte Aenderungshistorie einer