Fix ECDH zeroization, add audit logging, and remediate high findings
- Fix #61: handleRotateKey and handleDeleteUser now zeroize stored privBytes instead of calling Bytes() (which returns a copy). New state populates privBytes; old references nil'd for GC. - Add audit logging subsystem (internal/audit) with structured event recording for cryptographic operations. - Add audit log engine spec (engines/auditlog.md). - Add ValidateName checks across all engines for path traversal (#48). - Update AUDIT.md: all High findings resolved (0 open). - Add REMEDIATION.md with detailed remediation tracking. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -51,7 +51,7 @@ func runInit(cmd *cobra.Command, args []string) error {
|
||||
|
||||
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
|
||||
b := barrier.NewAESGCMBarrier(database)
|
||||
sealMgr := seal.NewManager(database, b, logger)
|
||||
sealMgr := seal.NewManager(database, b, nil, logger)
|
||||
if err := sealMgr.CheckInitialized(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/signal"
|
||||
@@ -10,6 +11,7 @@ import (
|
||||
mcias "git.wntrmute.dev/kyle/mcias/clients/go"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/audit"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/auth"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/barrier"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/config"
|
||||
@@ -59,8 +61,14 @@ func runServer(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create audit logger.
|
||||
auditLog, err := createAuditLogger(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := barrier.NewAESGCMBarrier(database)
|
||||
sealMgr := seal.NewManager(database, b, logger)
|
||||
sealMgr := seal.NewManager(database, b, auditLog, logger)
|
||||
|
||||
if err := sealMgr.CheckInitialized(); err != nil {
|
||||
return err
|
||||
@@ -81,8 +89,8 @@ func runServer(cmd *cobra.Command, args []string) error {
|
||||
engineRegistry.RegisterFactory(engine.EngineTypeTransit, transit.NewTransitEngine)
|
||||
engineRegistry.RegisterFactory(engine.EngineTypeUser, user.NewUserEngine)
|
||||
|
||||
srv := server.New(cfg, sealMgr, authenticator, policyEngine, engineRegistry, logger, version)
|
||||
grpcSrv := grpcserver.New(cfg, sealMgr, authenticator, policyEngine, engineRegistry, logger)
|
||||
srv := server.New(cfg, sealMgr, authenticator, policyEngine, engineRegistry, auditLog, logger, version)
|
||||
grpcSrv := grpcserver.New(cfg, sealMgr, authenticator, policyEngine, engineRegistry, auditLog, logger)
|
||||
|
||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
@@ -106,3 +114,26 @@ func runServer(cmd *cobra.Command, args []string) error {
|
||||
grpcSrv.Shutdown()
|
||||
return srv.Shutdown(context.Background())
|
||||
}
|
||||
|
||||
func createAuditLogger(cfg *config.Config) (*audit.Logger, error) {
|
||||
switch cfg.Audit.Mode {
|
||||
case "":
|
||||
return nil, nil // disabled
|
||||
case "stdout":
|
||||
h := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
|
||||
Level: audit.LevelAudit,
|
||||
})
|
||||
return audit.New(h), nil
|
||||
case "file":
|
||||
f, err := os.OpenFile(cfg.Audit.Path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("audit: open log file %s: %w", cfg.Audit.Path, err)
|
||||
}
|
||||
h := slog.NewJSONHandler(f, &slog.HandlerOptions{
|
||||
Level: audit.LevelAudit,
|
||||
})
|
||||
return audit.New(h), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("audit: unknown mode %q", cfg.Audit.Mode)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user