Audit Quick Start
Get tamper-evident logging running in under five minutes.
Go
Install
bash
go get github.com/openparallax/openparallaxCreate a Log, Append Entries, Verify
go
package main
import (
"fmt"
"log"
"github.com/openparallax/openparallax/audit"
)
func main() {
// Create or open an audit log. If the file already exists,
// the logger recovers the last hash to continue the chain.
logger, err := audit.NewLogger("./audit.jsonl")
if err != nil {
log.Fatal(err)
}
defer logger.Close()
// Log a proposed action.
err = logger.Log(audit.Entry{
EventType: audit.ActionProposed,
ActionType: "write_file",
SessionID: "session-001",
Details: `{"path":"/workspace/main.go","content":"package main"}`,
})
if err != nil {
log.Fatal(err)
}
// Log the execution result.
err = logger.Log(audit.Entry{
EventType: audit.ActionExecuted,
ActionType: "write_file",
SessionID: "session-001",
Details: `{"path":"/workspace/main.go","bytes_written":27}`,
})
if err != nil {
log.Fatal(err)
}
// Log a blocked action.
err = logger.Log(audit.Entry{
EventType: audit.ActionBlocked,
ActionType: "run_command",
SessionID: "session-001",
Details: `{"command":"rm -rf /","reason":"denied by policy"}`,
})
if err != nil {
log.Fatal(err)
}
// Close the logger to flush.
logger.Close()
// Verify the hash chain.
if err := audit.VerifyIntegrity("./audit.jsonl"); err != nil {
fmt.Printf("INTEGRITY VIOLATION: %s\n", err)
} else {
fmt.Println("Audit log integrity verified.")
}
}Query Entries
go
// Read the 10 most recent entries for a specific session.
entries, err := audit.ReadEntries("./audit.jsonl", audit.Query{
SessionID: "session-001",
Limit: 10,
})
if err != nil {
log.Fatal(err)
}
for _, e := range entries {
fmt.Printf("[%d] %s: %s\n", e.EventType, e.ActionType, e.DetailsJSON)
}Filter by Event Type
go
// Read only blocked actions.
blocked, err := audit.ReadEntries("./audit.jsonl", audit.Query{
EventType: audit.ActionBlocked,
Limit: 50,
})Python
Install
bash
pip install openparallax-auditBasic Usage
python
from openparallax_audit import AuditLogger, EventType
# Create or open an audit log.
logger = AuditLogger("./audit.jsonl")
# Log events.
logger.log(
event_type=EventType.ACTION_PROPOSED,
action_type="write_file",
session_id="session-001",
details={"path": "/workspace/main.go"},
)
logger.log(
event_type=EventType.ACTION_EXECUTED,
action_type="write_file",
session_id="session-001",
details={"path": "/workspace/main.go", "bytes_written": 27},
)
logger.close()
# Verify the chain.
from openparallax_audit import verify_integrity
result = verify_integrity("./audit.jsonl")
if result.valid:
print("Audit log integrity verified.")
else:
print(f"INTEGRITY VIOLATION at line {result.line}: {result.error}")Query Entries
python
from openparallax_audit import read_entries, Query
entries = read_entries("./audit.jsonl", Query(
session_id="session-001",
limit=10,
))
for entry in entries:
print(f"[{entry.event_type}] {entry.action_type}: {entry.details}")Node.js
Install
bash
npm install @openparallax/auditBasic Usage
typescript
import { AuditLogger, EventType, verifyIntegrity } from '@openparallax/audit';
// Create or open an audit log.
const logger = new AuditLogger('./audit.jsonl');
// Log events.
await logger.log({
eventType: EventType.ACTION_PROPOSED,
actionType: 'write_file',
sessionId: 'session-001',
details: { path: '/workspace/main.go' },
});
await logger.log({
eventType: EventType.ACTION_EXECUTED,
actionType: 'write_file',
sessionId: 'session-001',
details: { path: '/workspace/main.go', bytesWritten: 27 },
});
await logger.close();
// Verify the chain.
const result = await verifyIntegrity('./audit.jsonl');
if (result.valid) {
console.log('Audit log integrity verified.');
} else {
console.error(`INTEGRITY VIOLATION at line ${result.line}: ${result.error}`);
}Query Entries
typescript
import { readEntries } from '@openparallax/audit';
const entries = await readEntries('./audit.jsonl', {
sessionId: 'session-001',
limit: 10,
});
for (const entry of entries) {
console.log(`[${entry.eventType}] ${entry.actionType}: ${JSON.stringify(entry.details)}`);
}