Documentation
¶
Index ¶
- Constants
- func AuditFilesInRange(dir, since, until string) ([]string, error)
- func ComputeHash(prevHash string, eventJSON []byte) string
- func DebugEnabled() bool
- func IsEnabled() bool
- func LatestAuditFile(dir string) (string, error)
- func RedactEventJSON(evt Event, level RedactLevel) ([]byte, error)
- func VerifyFile(path string) (valid bool, brokenAt int, err error)
- type Actor
- type Chain
- type DateRotatingWriter
- type Event
- type FileSink
- type HTTPForwarder
- type NopSink
- type RedactLevel
- type Sink
Constants ¶
const ( EnvAudit = "DWS_AUDIT" EnvAuditDir = "DWS_AUDIT_DIR" EnvRetentionDays = "DWS_AUDIT_RETENTION_DAYS" EnvForwardURL = "DWS_AUDIT_FORWARD_URL" EnvForwardToken = "DWS_AUDIT_FORWARD_TOKEN" EnvForwardRedact = "DWS_AUDIT_FORWARD_REDACT" EnvAuditDebug = "DWS_AUDIT_DEBUG" )
Variables ¶
This section is empty.
Functions ¶
func AuditFilesInRange ¶
func ComputeHash ¶
func DebugEnabled ¶
func DebugEnabled() bool
DebugEnabled reports whether audit-subsystem diagnostics should be surfaced to stderr. Failures are always eligible for the structured log; this gates the noisier stderr channel.
func LatestAuditFile ¶
func RedactEventJSON ¶
func RedactEventJSON(evt Event, level RedactLevel) ([]byte, error)
Types ¶
type Chain ¶
type Chain struct{}
Chain computes the L1 sha256 tamper-evidence chain. It is deliberately stateless: every seal derives prev_hash from the last record already present in the current day's file rather than from an in-memory or sidecar cursor.
This makes the chain correct in two cases the previous global-sidecar design broke:
- cross-date: each day rotates to a fresh file whose first record chains from "", so every file is independently verifiable by VerifyFile.
- cross-process: because the caller holds an exclusive inter-process lock on the file while sealing, the tail read reflects records written by any other dws process, so concurrent writers cannot fork the chain.
func NewChain ¶
NewChain keeps the historical constructor signature. The directory argument is no longer needed because prev_hash is derived from the target file.
func (*Chain) SealFromFile ¶
SealFromFile reads the hash of the last record in f (the current day's audit file) and returns the prev_hash / hash pair for the event whose hash-free body is provided. The caller must hold the file lock.
type DateRotatingWriter ¶
type DateRotatingWriter struct {
// contains filtered or unexported fields
}
func NewDateRotatingWriter ¶
func NewDateRotatingWriter(dir string, retentionDays int) (*DateRotatingWriter, error)
func (*DateRotatingWriter) Close ¶
func (w *DateRotatingWriter) Close() error
func (*DateRotatingWriter) Dir ¶
func (w *DateRotatingWriter) Dir() string
type Event ¶
type Event struct {
Timestamp time.Time `json:"ts"`
ExecutionID string `json:"execution_id"`
AgentID string `json:"agent_id,omitempty"`
Actor Actor `json:"actor"`
Product string `json:"product"`
Command string `json:"command"`
Endpoint string `json:"endpoint"`
ParamsSummary string `json:"params_summary,omitempty"`
Result string `json:"result"`
ErrCategory string `json:"error_category,omitempty"`
ErrReason string `json:"error_reason,omitempty"`
DurationMs int64 `json:"duration_ms"`
CLIVersion string `json:"cli_version"`
OS string `json:"os"`
Arch string `json:"arch"`
PrevHash string `json:"prev_hash"`
Hash string `json:"hash"`
}
func RedactEvent ¶
func RedactEvent(evt Event, level RedactLevel) Event
type FileSink ¶
type FileSink struct {
// contains filtered or unexported fields
}
func NewFileSink ¶
func NewFileSink(writer *DateRotatingWriter, chain *Chain, forwarder *HTTPForwarder) *FileSink
type HTTPForwarder ¶
type HTTPForwarder struct {
// contains filtered or unexported fields
}
func NewHTTPForwarder ¶
func NewHTTPForwarder(url, token string, redact RedactLevel, report func(string, ...any)) *HTTPForwarder
func (*HTTPForwarder) Close ¶
func (f *HTTPForwarder) Close(ctx context.Context) error
Close waits for in-flight forwards to finish, bounded by ctx (and, if ctx has no deadline, by a small internal timeout) so shutdown never blocks forever.
func (*HTTPForwarder) Forward ¶
func (f *HTTPForwarder) Forward(evt Event)
Forward dispatches the event asynchronously while tracking the goroutine so Close can wait for delivery instead of the CLI dropping it on exit.
type RedactLevel ¶
type RedactLevel string
const ( RedactNone RedactLevel = "none" RedactHashed RedactLevel = "hashed" RedactMinimal RedactLevel = "minimal" )
type Sink ¶
func BuildSink ¶
BuildSink constructs the audit sink for configDir. It returns an error when the audit subsystem is enabled but cannot initialize (e.g. the log directory is not writable) so the caller can surface the failure instead of silently degrading. report receives non-fatal forwarder diagnostics; it may be nil.