audit

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Feb 11, 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 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"
)

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 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) AppendNetwork

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

AppendNetwork adds a network request entry.

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