Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.crewship.ai/llms.txt

Use this file to discover all available pages before exploring further.

Audit Log

Crewship maintains an append-only audit log that records every mutation in the system. The audit log provides a complete trail for security review, compliance, and debugging.

What Is Audited

The audit_logs table currently captures these mutations. Other entities (crews, missions, credentials) emit journal events but do not yet have WriteAuditLog calls wired into their handlers:
CategoryActionsSource
Agentscreate, update, deleteinternal/api/agents_create.go, agents_update.go, agents_query.go
Backupsbackup.create, backup.restore, backup.unlock, backup.rotate, backup.delete, backup.downloadinternal/api/backup.go, backup_admin.go
Keeper security decisions are tracked separately in the keeper_requests table (see below), not in audit_logs.

Keeper Decision Auditing

Keeper security decisions are stored in the keeper_requests table with detailed fields:
FieldDescription
intentThe agent’s stated reason for access
request_typeaccess (credential read via /keeper/request) or execute (command run via /keeper/execute)
commandShell command (for execute requests)
decisionALLOW, DENY, or ESCALATE
reasonLLM-generated explanation
risk_scoreNumeric risk assessment (1-10)
ollama_promptFull prompt sent to the Keeper LLM
ollama_raw_responseRaw LLM response for review

Audit Log Table Structure

CREATE TABLE audit_logs (
  id          TEXT PRIMARY KEY,
  workspace_id TEXT NOT NULL,
  user_id     TEXT,
  action      TEXT NOT NULL,
  entity_type TEXT NOT NULL,
  entity_id   TEXT,
  metadata    TEXT,          -- JSON object
  ip_address  TEXT,
  user_agent  TEXT,
  created_at  TEXT NOT NULL   -- ISO 8601
);
ColumnTypeDescription
idTEXTRandom hex ID (32 chars)
workspace_idTEXTWorkspace the action occurred in
user_idTEXTUser who performed the action (null for system actions)
actionTEXTAction type — CRUD verbs (create, update, delete) for agent mutations, backup.* for backup lifecycle events
entity_typeTEXTEntity type (AGENT, CREW, MISSION, etc.)
entity_idTEXTID of the affected entity
metadataTEXTJSON object with action-specific details
ip_addressTEXTClient IP address
user_agentTEXTClient user agent string
created_atTEXTISO 8601 timestamp
The audit log is append-only. There is no API or mechanism to delete or modify audit log entries. This ensures an immutable record for security review.

Querying the Audit Log

GET /api/v1/audit

Required role: OWNER or ADMIN (manage permission)

Query Parameters

ParameterTypeDefaultDescription
pageinteger1Page number (1-based)
limitinteger50Entries per page (1-100)
actionstringFilter by action (e.g., create, delete)
entity_typestringFilter by entity type (e.g., AGENT, CREW)
entity_idstringFilter by specific entity ID
user_idstringFilter by user who performed the action
date_fromstringISO 8601 start date
date_tostringISO 8601 end date

Response

{
  "data": [
    {
      "id": "a1b2c3d4...",
      "workspace_id": "ws-uuid",
      "user_id": "user-uuid",
      "action": "create",
      "entity_type": "AGENT",
      "entity_id": "agent-uuid",
      "metadata": "{\"name\":\"Viktor\",\"role\":\"AGENT\"}",
      "ip_address": "192.168.1.100",
      "user_agent": "Mozilla/5.0...",
      "created_at": "2025-01-15T10:30:00Z",
      "user_email": "alice@example.com",
      "user_name": "Alice Chen"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 234,
    "total_pages": 5
  }
}
The response includes user_email and user_name joined from the users table for convenience.

Pagination

The audit log uses offset-based pagination:
  • Default limit: 50 entries per page
  • Maximum limit: 100 entries per page
  • Minimum limit: 1 entry per page
  • Pages are 1-based (page 1 is the first page)

Example Queries

GET /api/v1/audit?action=delete&entity_type=AGENT

How Audit Entries Are Written

Audit entries are written synchronously during mutation handlers using the WriteAuditLog function (defined at internal/api/internal_handler.go:51):
func WriteAuditLog(
    ctx context.Context,
    db *sql.DB,
    j journal.Emitter,
    action, entityType, entityID, userID, workspaceID string,
    metadata map[string]interface{},
)
Typical call site:
WriteAuditLog(r.Context(), h.db, h.journal, "create", "AGENT", agentID, userID, workspaceID, map[string]interface{}{
    "name": agent.Name,
    "role": agent.Role,
})
The function generates a random hex ID, writes the row in the same request context, and — when j is non-nil — dual-emits a typed audit.entity_* entry into the unified Crew Journal. If the write fails, a warning is logged but the original operation is not rolled back — the audit log is best-effort to avoid blocking user operations.

What’s Next

Admin API

Keeper audit log endpoint and workspace administration.

RBAC

Role-based access control that determines who can view audit logs.