Documentation
¶
Overview ¶
Package audit manages the registry audit log ring buffer and optional external export (Splunk HEC, syslog/CEF, plain JSON).
Fan-out from the server's audit() helper to the ring buffer and exporter is async: server.audit() publishes an "audit.entry" event on the shared events.Bus; Store.Subscribe starts a background goroutine that consumes those events and writes them here. This removes the direct coupling between the server's hot request path and the audit I/O.
Index ¶
- func RedactMap(m map[string]interface{}) map[string]interface{}
- type AuditExporter
- type AuditWAL
- type Entry
- type SplunkHECEvent
- type Store
- func (st *Store) Append(e Entry)
- func (st *Store) Close()
- func (st *Store) ExporterConfig() *wire.BlueprintAuditExport
- func (st *Store) ExporterStats() (exported, dropped uint64)
- func (st *Store) FilteredEntries(filterNetID uint16, limit int) []map[string]interface{}
- func (st *Store) HandleGetAuditExport(_ map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) RestoreLog(entries []Entry)
- func (st *Store) SetExporter(cfg *wire.BlueprintAuditExport)
- func (st *Store) SetStorePath(p string)
- func (st *Store) Snapshot() []Entry
- func (st *Store) Subscribe(bus events.Bus)
- func (st *Store) VerifyIntegrity() int
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func RedactMap ¶ added in v0.2.4
RedactMap returns a shallow copy of m with any values whose keys match redactKey replaced by "<redacted>". Nil-safe (returns nil).
PILOT-314: the DLQ read API (HandleGetWebhookDLQ) returns event Details verbatim. If audit redaction wasn't exhaustive, the DLQ becomes a credential-disclosure surface for anyone holding the admin token. RedactMap allows callers outside package audit to apply the same redaction rules on retrieval.
Types ¶
type AuditExporter ¶
type AuditExporter struct {
// contains filtered or unexported fields
}
AuditExporter sends audit events to an external system in the configured format (Splunk HEC, syslog/CEF, or plain JSON). It runs asynchronously with a buffered channel, just like registryWebhook.
func NewAuditExporter ¶
func NewAuditExporter(cfg *wire.BlueprintAuditExport) *AuditExporter
NewAuditExporter creates and starts a new AuditExporter for the given config. It is exported so that the server package shim (audit_export.go) can delegate to it without the sub-package re-implementing the constructor.
func NewAuditExporterWithWAL ¶ added in v0.2.4
func NewAuditExporterWithWAL(cfg *wire.BlueprintAuditExport, walPath string) *AuditExporter
NewAuditExporterWithWAL creates and starts a new AuditExporter with an on-disk write-ahead log at walPath. Use empty walPath to disable the WAL.
func (*AuditExporter) Close ¶
func (ae *AuditExporter) Close()
Close signals the background goroutine to stop and waits for it to drain. After a clean drain, the WAL is truncated — all pending entries have been sent to the external system.
func (*AuditExporter) Export ¶
func (ae *AuditExporter) Export(entry *Entry)
Export queues an audit entry for export. The entry is persisted to the write-ahead log before entering the channel. Non-blocking; drops if the channel buffer is full, but the WAL copy survives a crash restart.
func (*AuditExporter) Stats ¶
func (ae *AuditExporter) Stats() (exported, dropped uint64)
Stats returns export statistics.
type AuditWAL ¶ added in v0.2.4
type AuditWAL struct {
// contains filtered or unexported fields
}
AuditWAL persists audit entries to disk in JSON-lines format before they enter the export channel. On clean shutdown the WAL is truncated; on crash restart all entries are replayed for re-export.
func NewAuditWAL ¶ added in v0.2.4
NewAuditWAL opens or creates the WAL file at path. Returns nil when path is empty (no persistence configured).
func (*AuditWAL) Append ¶ added in v0.2.4
Append writes an audit entry as a JSON line to the WAL and fsyncs.
type Entry ¶
type Entry struct {
Timestamp string `json:"timestamp"`
Action string `json:"action"`
NetworkID uint16 `json:"network_id,omitempty"`
NodeID uint32 `json:"node_id,omitempty"`
Details string `json:"details,omitempty"`
// Hash-chain fields for tamper-evidence.
// PrevHash is the SHA-256 hex digest of the previous entry
// (empty for the genesis entry). Hash is the SHA-256 hex
// digest of this entry encompassing PrevHash, Timestamp,
// Action, NetworkID, NodeID, and Details.
PrevHash string `json:"prev_hash,omitempty"`
Hash string `json:"hash,omitempty"`
}
Entry records a single audit event. The JSON tags match the on-wire format used by handleGetAuditLog and the snapshot serialiser.
type SplunkHECEvent ¶
type SplunkHECEvent struct {
Time int64 `json:"time"`
Host string `json:"host,omitempty"`
Source string `json:"source,omitempty"`
SourceType string `json:"sourcetype,omitempty"`
Index string `json:"index,omitempty"`
Event map[string]interface{} `json:"event"`
}
SplunkHECEvent is the Splunk HTTP Event Collector event format.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store holds the in-memory audit ring buffer and the optional external export adapter. All exported methods are safe for concurrent use.
func (*Store) Append ¶
Append directly inserts an entry into the ring buffer and forwards it to the exporter (if configured). It is used by the snapshot restore path which bypasses the bus (no need to publish historical entries).
Each entry is linked to its predecessor via a SHA-256 hash chain, providing tamper-evident integrity. The genesis entry has an empty PrevHash.
func (*Store) Close ¶
func (st *Store) Close()
Close stops the bus subscriber goroutine and drains/closes the exporter.
func (*Store) ExporterConfig ¶
func (st *Store) ExporterConfig() *wire.BlueprintAuditExport
ExporterConfig returns the active export configuration (nil = disabled).
func (*Store) ExporterStats ¶
ExporterStats returns (exported, dropped) counters from the active exporter.
func (*Store) FilteredEntries ¶
FilteredEntries returns audit entries newest-first, filtered by netID (0 = all) and limited to at most limit entries.
func (*Store) HandleGetAuditExport ¶
HandleGetAuditExport builds the response map for a "get_audit_export" protocol request. adminCheck must be called by the caller before invoking this method (the server wraps this in handleGetAuditExport which first calls requireAdminToken).
func (*Store) RestoreLog ¶
RestoreLog replaces the ring buffer with the provided slice (used during snapshot restore on startup). If the entries already carry a valid hash chain it is preserved; otherwise the chain is rebuilt from scratch.
func (*Store) SetExporter ¶
func (st *Store) SetExporter(cfg *wire.BlueprintAuditExport)
SetExporter replaces the current exporter with a new one built from cfg. The old exporter (if any) is drained and closed. Pass nil cfg to disable. If storePath was previously set via SetStorePath, the new exporter gets a write-ahead log at "{storePath}.audit-export-wal".
func (*Store) SetStorePath ¶ added in v0.2.4
SetStorePath records the registry snapshot file path so the audit exporter can derive its WAL path ({storePath}.audit-export-wal). Call once during server init, before SetExporter.
func (*Store) Subscribe ¶
Subscribe starts a background goroutine that reads "audit.entry" events from the bus and forwards each one to the configured exporter. Ring-buffer writes are synchronous (via Append); this goroutine handles only async exporter fan-out. Call it once after constructing the Store.
func (*Store) VerifyIntegrity ¶ added in v0.2.4
VerifyIntegrity walks the hash chain from the oldest entry to the newest. It returns the index of the first entry whose hash does not match, or -1 when the chain is fully intact.