audit

package
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 27, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package audit provides tamper-proof logging with cryptographic verification.

Index

Constants

View Source
const BundleVersion = 1

BundleVersion is the current proof bundle format version.

View Source
const FirstSequence uint64 = 1

FirstSequence is the sequence number of the first entry in a log. Sequences are 1-indexed to distinguish "no previous entry" (seq=0) from the first entry.

Variables

View Source
var ErrNotFound = errors.New("entry not found")

ErrNotFound is returned when an entry doesn't exist.

Functions

func VerifySignature

func VerifySignature(publicKey, message, signature []byte) bool

VerifySignature verifies a signature using only the public key. This is useful for third-party verification without the private key.

Types

type Attestation

type Attestation struct {
	Sequence  uint64    `json:"seq"`        // Entry sequence at checkpoint
	RootHash  string    `json:"root_hash"`  // Hash of last entry at this point
	Timestamp time.Time `json:"timestamp"`  // When attestation was created
	Signature []byte    `json:"signature"`  // Ed25519 signature of root hash
	PublicKey []byte    `json:"public_key"` // Signer's public key
}

Attestation represents a signed checkpoint of the hash chain.

func (*Attestation) Verify

func (a *Attestation) Verify() bool

Verify checks if the attestation signature is valid.

type Auditor

type Auditor struct {
	// contains filtered or unexported fields
}

Auditor verifies the integrity of a run's audit logs.

func NewAuditor

func NewAuditor(dbPath string) (*Auditor, error)

NewAuditor creates an auditor for the given database path.

func (*Auditor) Close

func (a *Auditor) Close() error

Close closes the auditor's store.

func (*Auditor) Verify

func (a *Auditor) Verify() (*Result, error)

Verify performs a full integrity verification.

type Collector

type Collector struct {
	// contains filtered or unexported fields
}

Collector receives log messages and stores them with hash chaining.

func NewCollector

func NewCollector(store *Store) *Collector

NewCollector creates a new log collector.

func (*Collector) StartTCP

func (c *Collector) StartTCP(authToken string) (string, error)

StartTCP starts the collector listening on TCP with token authentication. Returns the port number the server is listening on.

func (*Collector) StartUnix

func (c *Collector) StartUnix(socketPath string) error

StartUnix starts the collector listening on a Unix socket.

func (*Collector) Stop

func (c *Collector) Stop() error

Stop stops the collector and waits for all connections to close.

type CollectorMessage

type CollectorMessage struct {
	Type string `json:"type"`
	Data any    `json:"data"`
}

CollectorMessage is the wire format for log messages from agents.

type ConsoleData

type ConsoleData struct {
	Line string `json:"line"`
}

ConsoleData holds console log entry data.

type ContainerData

type ContainerData struct {
	Action     string `json:"action"`               // "created", "started", "stopped"
	Privileged bool   `json:"privileged,omitempty"` // true if container runs in privileged mode
	Reason     string `json:"reason,omitempty"`     // e.g., "docker:dind" for why privileged

	// BuildKit sidecar info (dind mode only)
	BuildKitEnabled     bool   `json:"buildkit_enabled,omitempty"`
	BuildKitContainerID string `json:"buildkit_container_id,omitempty"`
	BuildKitNetworkID   string `json:"buildkit_network_id,omitempty"`
}

ContainerData holds container lifecycle entry data.

type CredentialData

type CredentialData struct {
	Name   string `json:"name"`   // e.g., "github"
	Action string `json:"action"` // e.g., "injected", "used", "revoked"
	Host   string `json:"host"`   // e.g., "api.github.com"
}

CredentialData holds credential usage entry data.

type DeviceData added in v0.8.0

type DeviceData struct {
	Name       string `json:"name"`
	Path       string `json:"path,omitempty"`
	VID        string `json:"vid,omitempty"`
	PID        string `json:"pid,omitempty"`
	Serial     string `json:"serial,omitempty"`
	Action     string `json:"action"` // attach, detach, error, conflict
	Detail     string `json:"detail,omitempty"`
	TxBytes    int64  `json:"tx_bytes,omitempty"`
	RxBytes    int64  `json:"rx_bytes,omitempty"`
	RecordMode string `json:"record_mode,omitempty"` // "full" when payloads were captured
}

DeviceData describes a serial device event.

The device's USB identity is recorded on every entry so an audit trail shows which physical device was reached, not just the name the config gave it.

type Entry

type Entry struct {
	Sequence  uint64    `json:"seq"`
	Timestamp time.Time `json:"ts"`
	Type      EntryType `json:"type"`
	PrevHash  string    `json:"prev"`
	// Data must be JSON-serializable. Non-serializable values (e.g., channels,
	// functions, cycles) will marshal as null, which may cause hash collisions.
	Data any    `json:"data"`
	Hash string `json:"hash"`
	// contains filtered or unexported fields
}

Entry represents a single hash-chained log entry.

func NewEntry

func NewEntry(seq uint64, prevHash string, entryType EntryType, data any) *Entry

NewEntry creates a new entry with computed hash.

func (*Entry) UnmarshalJSON

func (e *Entry) UnmarshalJSON(data []byte) error

UnmarshalJSON implements custom JSON unmarshaling to set dataJSON. This ensures hash verification works after JSON round-trips.

func (*Entry) Verify

func (e *Entry) Verify() bool

Verify checks if the entry's hash is valid.

type EntryType

type EntryType string

EntryType identifies the kind of log entry.

const (
	EntryConsole    EntryType = "console"
	EntryNetwork    EntryType = "network"
	EntryCredential EntryType = "credential"
	EntrySecret     EntryType = "secret"
	EntrySSH        EntryType = "ssh"
	EntryContainer  EntryType = "container"
	EntryExec       EntryType = "exec"
	EntryDevice     EntryType = "device"
)
const EntryPolicy EntryType = "policy"

EntryPolicy is the entry type for Keep policy evaluation decisions.

type ExecData added in v0.4.0

type ExecData struct {
	Command  []string `json:"command"`
	HasStdin bool     `json:"has_stdin"`
	ExitCode int      `json:"exit_code"`
}

ExecData holds exec command entry data.

type NetworkData

type NetworkData struct {
	Method         string `json:"method"`
	URL            string `json:"url"`
	StatusCode     int    `json:"status_code"`
	DurationMs     int64  `json:"duration_ms"`
	CredentialUsed string `json:"credential_used,omitempty"`
	Error          string `json:"error,omitempty"`
}

NetworkData holds network request entry data.

type PolicyDecisionData added in v0.5.0

type PolicyDecisionData struct {
	Scope     string `json:"scope"`
	Operation string `json:"operation"`
	Decision  string `json:"decision"`
	Rule      string `json:"rule,omitempty"`
	Message   string `json:"message,omitempty"`
}

PolicyDecisionData holds Keep policy evaluation entry data.

type ProofBundle

type ProofBundle struct {
	Version      int            `json:"version"`
	CreatedAt    time.Time      `json:"created_at"`
	LastHash     string         `json:"last_hash"`
	Entries      []*Entry       `json:"entries"`
	Attestations []*Attestation `json:"attestations,omitempty"`
	RekorProofs  []*RekorProof  `json:"rekor_proofs,omitempty"`
}

ProofBundle is a portable, self-contained audit log proof. It contains everything needed to verify an audit log without access to the original database.

func (*ProofBundle) Verify

func (b *ProofBundle) Verify() *Result

Verify performs a full integrity verification on the proof bundle. This works offline without access to the original database.

type RekorClient

type RekorClient struct {
	// contains filtered or unexported fields
}

RekorClient wraps the Sigstore Rekor client for transparency log operations.

func NewRekorClient

func NewRekorClient(url string) (*RekorClient, error)

NewRekorClient creates a new Rekor client. If url is empty, uses the default Sigstore instance.

func (*RekorClient) URL

func (c *RekorClient) URL() string

URL returns the Rekor instance URL.

func (*RekorClient) Upload

func (c *RekorClient) Upload(ctx context.Context, hash []byte, signature []byte, publicKey []byte) (*RekorProof, error)

Upload submits a signed hash to Rekor and returns the inclusion proof. This is the core operation for external attestation.

type RekorProof

type RekorProof struct {
	LogIndex  int64     `json:"log_index"`
	LogID     string    `json:"log_id"`
	TreeSize  int64     `json:"tree_size"`
	RootHash  string    `json:"root_hash"`
	Hashes    []string  `json:"hashes"`
	Timestamp time.Time `json:"timestamp"`
	EntryUUID string    `json:"entry_uuid"`
}

RekorProof contains the inclusion proof from Rekor.

type Result

type Result struct {
	Valid              bool   `json:"valid"`
	HashChainValid     bool   `json:"hash_chain_valid"`
	AttestationsValid  bool   `json:"attestations_valid"`
	RekorProofsPresent bool   `json:"rekor_proofs_present"` // Presence only; verification requires network
	EntryCount         uint64 `json:"entry_count"`
	AttestationCount   int    `json:"attestation_count"`
	RekorProofCount    int    `json:"rekor_proof_count"`
	Error              string `json:"error,omitempty"`
}

Result contains the results of verifying a run's integrity.

type SSHData

type SSHData struct {
	Action      string `json:"action"`                // "list", "sign_allowed", "sign_denied"
	Host        string `json:"host,omitempty"`        // target host (for sign operations)
	Fingerprint string `json:"fingerprint,omitempty"` // key fingerprint (for sign operations)
	Error       string `json:"error,omitempty"`       // error message (for denied operations)
}

SSHData holds SSH agent operation entry data.

type SecretData

type SecretData struct {
	Name    string `json:"name"`    // env var name, e.g., "OPENAI_API_KEY"
	Backend string `json:"backend"` // e.g., "1password", "ssm"

}

SecretData holds secret resolution entry data.

type Signer

type Signer struct {
	// contains filtered or unexported fields
}

Signer handles Ed25519 signing for audit logs.

func NewSigner

func NewSigner(keyPath string) (*Signer, error)

NewSigner creates or loads an Ed25519 keypair. If keyPath exists, loads the existing key. Otherwise generates a new one.

func (*Signer) PublicKey

func (s *Signer) PublicKey() []byte

PublicKey returns the public key bytes.

func (*Signer) Sign

func (s *Signer) Sign(message []byte) []byte

Sign signs a message and returns the signature.

func (*Signer) Verify

func (s *Signer) Verify(message, signature []byte) bool

Verify checks if a signature is valid for the message.

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store provides tamper-proof log storage using SQLite.

func OpenStore

func OpenStore(path string) (*Store, error)

OpenStore opens or creates a log store at the given path.

func (*Store) Append

func (s *Store) Append(entryType EntryType, data any) (*Entry, error)

Append adds a new entry to the store, returning the created entry.

func (*Store) AppendConsole

func (s *Store) AppendConsole(line string) (*Entry, error)

AppendConsole adds a console log entry.

func (*Store) AppendContainer

func (s *Store) AppendContainer(data ContainerData) (*Entry, error)

AppendContainer adds a container lifecycle entry.

func (*Store) AppendCredential

func (s *Store) AppendCredential(data CredentialData) (*Entry, error)

AppendCredential adds a credential usage entry.

func (*Store) AppendDevice added in v0.8.0

func (s *Store) AppendDevice(data DeviceData) (*Entry, error)

AppendDevice appends a serial device entry.

func (*Store) AppendExec added in v0.4.0

func (s *Store) AppendExec(data ExecData) (*Entry, error)

AppendExec adds an exec command entry.

func (*Store) AppendNetwork

func (s *Store) AppendNetwork(data NetworkData) (*Entry, error)

AppendNetwork adds a network request entry.

func (*Store) AppendPolicy added in v0.5.0

func (s *Store) AppendPolicy(data PolicyDecisionData) (*Entry, error)

AppendPolicy adds a policy decision entry.

func (*Store) AppendPolicyEntry added in v0.5.0

func (s *Store) AppendPolicyEntry(scope, operation, decision, rule, message string) error

AppendPolicyEntry is a convenience method for logging policy decisions.

func (*Store) AppendSSH

func (s *Store) AppendSSH(data SSHData) (*Entry, error)

AppendSSH adds an SSH agent operation entry.

func (*Store) AppendSecret

func (s *Store) AppendSecret(data SecretData) (*Entry, error)

AppendSecret adds a secret resolution entry.

func (*Store) Close

func (s *Store) Close() error

Close closes the database connection.

func (*Store) Count

func (s *Store) Count() (uint64, error)

Count returns the total number of entries.

func (*Store) Export

func (s *Store) Export() (*ProofBundle, error)

Export creates a portable proof bundle from the store.

func (*Store) Get

func (s *Store) Get(seq uint64) (*Entry, error)

Get retrieves an entry by sequence number.

func (*Store) LastHash

func (s *Store) LastHash() string

LastHash returns the hash of the most recent entry.

func (*Store) LoadAttestations

func (s *Store) LoadAttestations() ([]*Attestation, error)

LoadAttestations returns all attestations in the store.

func (*Store) LoadRekorProofs

func (s *Store) LoadRekorProofs() (map[uint64]*RekorProof, error)

LoadRekorProofs returns all Rekor proofs in the store.

func (*Store) Range

func (s *Store) Range(startSeq, endSeq uint64) ([]*Entry, error)

Range retrieves entries from startSeq to endSeq (inclusive).

func (*Store) SaveAttestation

func (s *Store) SaveAttestation(att *Attestation) error

SaveAttestation saves an attestation to the store.

func (*Store) SaveRekorProof

func (s *Store) SaveRekorProof(seq uint64, proof *RekorProof) error

SaveRekorProof saves a Rekor inclusion proof for an entry.

func (*Store) VerifyChain

func (s *Store) VerifyChain() (*VerifyResult, error)

VerifyChain verifies the integrity of the entire hash chain.

type VerifyResult

type VerifyResult struct {
	Valid           bool
	EntryCount      uint64
	FirstInvalidSeq uint64
	Error           string
}

VerifyResult contains the result of chain verification.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL