Documentation
¶
Overview ¶
Package audit provides append-only tamper-evident audit chain storage. It depends only on store.Store and has no keeper or bbolt import.
Index ¶
- Constants
- Variables
- func KeyFingerprint(key []byte) string
- type Event
- type Store
- func (a *Store) Append(scheme, namespace string, event *Event) error
- func (a *Store) Init() error
- func (a *Store) LastChecksum(scheme, namespace string) string
- func (a *Store) LoadChain(scheme, namespace string) ([]*Event, error)
- func (a *Store) Prune(scheme, namespace string, olderThan time.Duration, keepLastN int) error
- func (a *Store) VerifyIntegrity(scheme, namespace string) error
Constants ¶
const EventTypeKeyRotationCheckpoint = "key_rotation_checkpoint"
EventTypeKeyRotationCheckpoint marks a key-rotation boundary in the chain. Events before the checkpoint are verified with the old signing key; events after are verified with the new signing key. History is never rewritten — the checkpoint is the trust bridge.
Variables ¶
var ErrChainBroken = errors.New("audit chain integrity check failed")
ErrChainBroken is returned when audit chain integrity verification fails.
Functions ¶
func KeyFingerprint ¶
KeyFingerprint returns a short proof-of-possession token for key. Used in checkpoint events to prove the old and new keys without revealing them.
Types ¶
type Event ¶
type Event struct {
ID string `json:"id"`
BucketID string `json:"bucket_id"`
Scheme string `json:"scheme"`
Namespace string `json:"namespace"`
Seq int64 `json:"seq"`
EventType string `json:"event_type"`
Details []byte `json:"details"`
Timestamp time.Time `json:"timestamp"`
PrevChecksum string `json:"prev_checksum"`
Checksum string `json:"checksum"`
HMAC string `json:"hmac,omitempty"`
}
Event is an append-only audit record with chain integrity.
The chain is secured at two levels:
Checksum — SHA256 over prevChecksum, ID, BucketID, Scheme, Namespace, Details, EventType, and Timestamp. Detects content modification and cross-bucket transplantation. Seq is excluded so it can be assigned inside the write transaction after the caller has computed the hash.
HMAC — HMAC-SHA256 over all fields including Seq. Provides authentication: only a holder of the signing key can produce a valid HMAC. When no signing key is configured the HMAC field is empty and VerifyIntegrity skips HMAC checking.
func (*Event) ComputeChecksum ¶
ComputeChecksum returns SHA256(prevChecksum | ID | BucketID | Scheme | Namespace | Details | EventType | Timestamp). Seq is intentionally excluded — it is assigned by Append inside the transaction after the caller computes the checksum.
func (*Event) ComputeHMAC ¶
ComputeHMAC returns HMAC-SHA256 over all event fields using key. Returns "" when key is empty — callers interpret that as "no signing key".
func (*Event) VerifyChecksum ¶
VerifyChecksum returns true when e.Checksum matches the computed value.
func (*Event) VerifyHMAC ¶
VerifyHMAC returns true when the event's HMAC is valid for key. Returns true unconditionally when key or e.HMAC is empty.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store handles audit event persistence.
func New ¶
New creates an audit Store. Pass a non-nil signingKey to enable HMAC signing of every appended event and HMAC verification in VerifyIntegrity. Pass nil to disable signing.
func (*Store) Append ¶
Append writes event to the chain for scheme/namespace. Seq is assigned atomically inside the write transaction.
func (*Store) LastChecksum ¶
LastChecksum returns the checksum of the most recently appended event, or "" if no events exist for this scheme/namespace.
func (*Store) LoadChain ¶
LoadChain returns all events for scheme/namespace ordered by Seq ascending.
func (*Store) Prune ¶
Prune removes events from the chain, always trimming the oldest end so the surviving events form a contiguous tail. The chain index is rewritten after deletion so LastChecksum remains consistent with stored data.
olderThan: events with Timestamp older than time.Now()-olderThan are candidates for deletion. Pass 0 to make all events candidates. keepLastN: always preserve the most recent keepLastN events by Seq.
func (*Store) VerifyIntegrity ¶
VerifyIntegrity checks the entire chain for scheme/namespace.
At key-rotation checkpoint events the active verification key switches to the new epoch key. This preserves the chain's tamper-evidence across key rotations without rewriting any historical events.