ATHELOS
Reference

Database

Schema reference — tables, relations, and conventions.

Database

ATHELOS uses PostgreSQL 16 with the pgvector extension. This page is a reference for the schema.

Conventions

  • Primary keys — UUIDs, generated at insert time
  • Timestamps — timestamptz, always UTC
  • Money — integer cents, never floats
  • Soft delete — some tables use a status field instead of hard delete
  • Foreign keys — enforced with ON DELETE CASCADE where appropriate
  • Indexes — every foreign key is indexed; some tables have composite indexes for query patterns

Extensions

Installed automatically during migration:

ExtensionPurpose
uuid-osspUUID generation
pgcryptoEncryption functions
vectorpgvector for embeddings
pg_trgmTrigram matching for fuzzy search

Verify:

docker exec soc_postgres psql -U soc -d soc_solo -c "\\dx"

Table groups

The schema is organized into eight groups:

  1. Auth and system — users, sessions, audit log, settings
  2. Knowledge base — articles, tags, embeddings
  3. Playbooks — structured metadata, executions
  4. Engagements — clients, contacts, scope, findings, evidence, time
  5. Reports — templates, report instances, finding selections
  6. Business — contracts, rate cards, invoices, deliveries
  7. Toolbox — tools, wordlists, payloads, labs, infrastructure
  8. Learning — certifications, labs, notes

Auth and system

users

The owner account. Single-row in normal operation.

ColumnTypeNotes
iduuidPrimary key
emailtextUnique
nametextDisplay name
password_hashtextArgon2id hash
roletextDefault owner
totp_secrettextEncrypted TOTP secret
totp_enabledbooleanWhether TOTP is active
totp_enrolled_attimestamptzWhen TOTP was enabled
webauthn_enabledbooleanWhether WebAuthn is active
created_attimestamptz—

sessions

Active login sessions.

ColumnTypeNotes
idtextPrimary key
user_iduuidFK to users
expires_attimestamptz—

audit_log

Append-only record of every write operation.

ColumnTypeNotes
iduuidPrimary key
user_iduuidFK to users, nullable
actiontexte.g. finding.create
entitytexte.g. finding
entity_idtextThe affected row
metajsonbAdditional context
iptextSource IP if available
created_attimestamptz—

app_settings

Key-value store for application-wide settings.

ColumnTypeNotes
keytextPrimary key
valuejsonb—
updated_attimestamptz—

Knowledge base

kb_articles

Every knowledge base article.

ColumnTypeNotes
iduuidPrimary key
slugtextUnique, URL-friendly
titletext—
summarytextShort description
bodytextMarkdown
categorytexte.g. methodology
pinnedbooleanFeatured at top
created_attimestamptz—
updated_attimestamptz—

kb_tags

Tag definitions.

kb_article_tags

Many-to-many join.

kb_article_embeddings

Vector embeddings for semantic search.

ColumnTypeNotes
article_iduuidPK, FK to kb_articles
modeltextEmbedding model name
dimensionsintegerVector size (768)
content_hashtextSHA-256 for idempotency
embeddingvector(768)pgvector type
updated_attimestamptz—

Playbooks

kb_playbook_meta

Structured metadata for playbook articles.

ColumnTypeNotes
article_iduuidPK, FK to kb_articles
frameworktextFramework name
versiontext—
estimated_hoursinteger—
difficultytext—
phasesjsonbArray of phase objects
toolsjsonbArray of tool names
evidence_templatesjsonbEvidence examples
attck_techniquesjsonbATT&CK IDs
referencesjsonbReference links

engagement_playbooks

A playbook instance loaded onto an engagement.

engagement_tasks

Individual tasks within a loaded playbook.

task_findings / task_evidence

Attachments linking tasks to findings and evidence.

Engagements

clients

Client records with CRM fields.

ColumnTypeNotes
iduuidPrimary key
nametext—
contact_nametext—
contact_emailtext—
statustextlead / qualified / proposal / negotiation / client / lost
addresstext—
tax_idtext—
billing_emailtext—
currencytextISO 4217
payment_terms_daysinteger—
sourcetextHow you found them
tagsjsonbArray of tags
expected_value_centsinteger—
websitetext—
industrytext—

client_contacts

Multiple contacts per client.

client_interactions

Chronological log of touchpoints.

engagements

The core engagement record.

ColumnTypeNotes
iduuidPrimary key
client_iduuidFK to clients
nametext—
typetextpentest / forensics / IR / etc.
statustextscoping / recon / exploitation / reporting / closed
start_datedate—
end_datedate—

scope_items

In-scope and out-of-scope targets.

findings

Every finding.

ColumnTypeNotes
iduuidPrimary key
engagement_iduuidFK to engagements
titletext—
severitytextcritical / high / medium / low / info
statustextopen / confirmed / false_positive / retested
cvss_scorenumeric0.0 to 10.0
cvss_vectortext—
descriptiontext—
impacttext—
remediationtext—
referencestext—
affected_assetsjsonbArray of scope item IDs

finding_tags

ATT&CK and custom tags per finding.

evidence

Evidence files attached to findings.

ColumnTypeNotes
iduuidPrimary key
finding_iduuidFK to findings
filenametext—
sizeintegerBytes
mimetypetext—
sha256textFile hash
storage_pathtextObject storage key
uploaded_attimestamptz—

time_entries

Billable and non-billable time.

Reports

reports

Report instances.

ColumnTypeNotes
iduuidPrimary key
engagement_iduuidFK to engagements
titletext—
versionintegerv1, v2, ...
statustextdraft / in_review / delivered
template_slugtext—
template_kindtext—
sectionsjsonbSection content
letterheadjsonbCover page data
executive_summarytext—
overviewtext—
methodologytext—
delivered_attimestamptz—

report_findings

Which findings appear in a report and in what order.

report_templates

The seven templates that ship with ATHELOS.

Business

contracts

Signed contracts.

contract_templates

Reusable templates (MSA, SoW, NDA).

rate_cards

Billing rates.

engagement_estimates

Scoping calculator output per engagement.

invoices

ColumnTypeNotes
iduuidPrimary key
client_iduuidFK to clients
engagement_iduuidFK to engagements, nullable
invoice_numbertextUnique
issue_datedate—
due_datedate—
statustextdraft / sent / paid / overdue / cancelled
subtotal_centsinteger—
tax_centsinteger—
total_centsinteger—
paid_attimestamptz—

invoice_items

Line items with integer cents.

client_deliveries

Signed delivery links for reports.

ColumnTypeNotes
iduuidPrimary key
report_iduuidFK to reports
client_iduuidFK to clients
token_hashtextSHA-256 of raw token, unique
token_prefixtextFirst 8 chars for UI
kindtextreport / finding-summary / retest-request
expires_attimestamptz—
revoked_attimestamptz—
view_countinteger—
last_viewed_attimestamptz—
last_viewed_iptext—

Toolbox

tools

Tool catalog.

wordlists

Path and metadata only — files aren't uploaded.

payloads

Payload library.

labs

Lab environments.

infrastructure

Servers, VPS, domains. credentials_ref points to a password manager, never the secret itself.

Learning

certifications

Cert paths and status.

learning_labs

Lab progress.

learning_lab_notes

Inline notes on labs.

Querying the database

Open a shell:

docker exec -it soc_postgres psql -U soc -d soc_solo

Common queries:

-- List all tables
\\dt

-- Describe a table
\\d findings

-- Count findings by severity
SELECT severity, COUNT(*) FROM findings GROUP BY severity;

-- Recent audit entries
SELECT action, entity, created_at FROM audit_log
ORDER BY created_at DESC LIMIT 20;

Migrations

Migrations live in packages/db/drizzle/. Each migration is a numbered SQL file.

Run pending migrations:

cd packages/db
pnpm drizzle-kit migrate

Generate a new migration after schema changes:

cd packages/db
pnpm drizzle-kit generate

Where to go next