Emits the request-level audit record to structured logs (scraped by the existing alloy/loki substrate) and surfaces security events at warn level. Placeholder behind the AuditSink interface — the classification- aware loki+buffer+reconcile sink (confidential fails closed, internal degrades) lands in #54 and replaces this without touching callers. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
42 lines
1.2 KiB
Go
42 lines
1.2 KiB
Go
package audit_test
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"log/slog"
|
|
"testing"
|
|
|
|
"github.com/mathiasbq/hyperguild/ingestion/internal/audit"
|
|
"github.com/mathiasbq/hyperguild/ingestion/internal/capture"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestSlogSinkRecordsEntryAndSecurityEvents(t *testing.T) {
|
|
var buf bytes.Buffer
|
|
sink := audit.NewSlogSink(slog.New(slog.NewTextHandler(&buf, nil)))
|
|
|
|
err := sink.Record(context.Background(), capture.AuditEntry{
|
|
Principal: "koala-cli",
|
|
Harness: "claude-code",
|
|
EffectiveClassification: "confidential",
|
|
Items: []string{"insight:wiki/a/facts/x.md"},
|
|
SecurityEvents: []string{"asserted-vs-derived origin mismatch"},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
out := buf.String()
|
|
assert.Contains(t, out, "capture audit")
|
|
assert.Contains(t, out, "koala-cli")
|
|
assert.Contains(t, out, "confidential")
|
|
assert.Contains(t, out, "capture security event")
|
|
assert.Contains(t, out, "asserted-vs-derived origin mismatch")
|
|
}
|
|
|
|
func TestSlogSinkNilLoggerDefaults(t *testing.T) {
|
|
// nil logger must not panic.
|
|
require.NotPanics(t, func() {
|
|
_ = audit.NewSlogSink(nil).Record(context.Background(), capture.AuditEntry{})
|
|
})
|
|
}
|