HelloJohn / docs
Audit Logs

Exporting Audit Logs

Export HelloJohn audit logs to CSV, JSON, or forward to SIEM systems for compliance and security monitoring.

Exporting Audit Logs

Export audit logs for compliance reporting, offline analysis, or ingestion into SIEM and log management systems.

CSV export

Via the dashboard

  1. Go to Settings → Audit Logs
  2. Apply filters (date range, event type, etc.)
  3. Click Export → CSV

The CSV download includes all matching records up to 100,000 rows.

Via the API

GET /v1/audit-logs/export?format=csv&from=2024-01-01T00:00:00Z&to=2024-01-31T23:59:59Z
Authorization: Bearer <admin_api_key>
Accept: text/csv

The response is a streaming CSV download.

curl "https://auth.yourdomain.com/v1/audit-logs/export\
?format=csv\
&from=2024-01-01T00:00:00Z\
&to=2024-01-31T23:59:59Z" \
  -H "Authorization: Bearer <admin_api_key>" \
  -o audit_logs_january.csv

CSV columns:

id,type,actor_id,actor_email,actor_type,resource_id,resource_type,
tenant_id,organization_id,ip_address,country,result,created_at,metadata

JSON export

GET /v1/audit-logs/export?format=json&from=2024-01-01T00:00:00Z
Authorization: Bearer <admin_api_key>
Accept: application/ndjson

The response is NDJSON (Newline Delimited JSON) — one JSON object per line, suitable for streaming large exports.

curl "https://auth.yourdomain.com/v1/audit-logs/export?format=ndjson" \
  -H "Authorization: Bearer <admin_api_key>" \
  -o audit_logs.ndjson

Automated exports (scheduled)

Schedule a nightly export to S3 or another storage backend:

// scripts/export-audit-logs.ts
import { createHelloJohnAdminClient } from '@hellojohn/node';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';

const hj = createHelloJohnAdminClient({ secretKey: process.env.HJ_SECRET_KEY! });
const s3 = new S3Client({ region: 'us-east-1' });

const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
yesterday.setHours(0, 0, 0, 0);

const today = new Date();
today.setHours(0, 0, 0, 0);

// Fetch all logs for yesterday
const logs: string[] = [];
let cursor: string | undefined;

do {
  const page = await hj.auditLogs.list({
    from: yesterday.toISOString(),
    to: today.toISOString(),
    limit: 200,
    cursor,
  });
  logs.push(...page.data.map(e => JSON.stringify(e)));
  cursor = page.meta.cursor;
} while (cursor);

// Upload to S3
const dateStr = yesterday.toISOString().split('T')[0];
await s3.send(new PutObjectCommand({
  Bucket: 'your-compliance-bucket',
  Key: `hellojohn-audit-logs/${dateStr}.ndjson`,
  Body: logs.join('\n'),
  ContentType: 'application/x-ndjson',
  ServerSideEncryption: 'AES256',
}));

console.log(`Exported ${logs.length} audit log entries for ${dateStr}`);

SIEM forwarding

Datadog (Cloud Enterprise)

Configure in the HelloJohn dashboard under Settings → Integrations → Datadog:

POST /v1/integrations/datadog
{
  "api_key": "dd-api-key",
  "site": "datadoghq.com",
  "service": "hellojohn",
  "source": "hellojohn-audit"
}

HelloJohn streams audit events to Datadog Logs in real time using the Datadog Logs Ingestion API.

Splunk (Cloud Enterprise)

POST /v1/integrations/splunk
{
  "hec_url": "https://splunk.yourdomain.com:8088",
  "hec_token": "splunk-hec-token",
  "index": "hellojohn",
  "sourcetype": "_json"
}

Generic SIEM via webhook

Any SIEM with an HTTP endpoint can receive audit events via webhooks:

# Register a webhook for all audit events
POST /v1/webhooks
{
  "name": "SIEM Audit Forward",
  "url": "https://your-siem.com/api/ingest",
  "events": ["audit.*"],
  "secret": "hmac-secret",
  "headers": {
    "X-Source": "hellojohn",
    "X-Environment": "production"
  }
}

HelloJohn will POST each audit event as it occurs with HMAC-SHA256 signature verification. See Webhook Verification for payload format.

Self-hosted: direct database access

On self-hosted deployments, connect your log shipper directly to PostgreSQL. Example with Logstash:

# logstash.conf
input {
  jdbc {
    jdbc_connection_string => "jdbc:postgresql://localhost:5432/hellojohn"
    jdbc_user => "hellojohn_readonly"
    jdbc_password => "${DB_PASSWORD}"
    jdbc_driver_class => "org.postgresql.Driver"
    schedule => "* * * * *"   # every minute
    statement => "SELECT * FROM audit_logs WHERE created_at > :sql_last_value ORDER BY created_at ASC"
    use_column_value => true
    tracking_column => "created_at"
    tracking_column_type => "timestamp"
  }
}

output {
  elasticsearch {
    hosts => ["https://elastic:9200"]
    index => "hellojohn-audit-%{+YYYY.MM.dd}"
  }
}

Retention and compliance

Self-hosted

Audit logs are stored indefinitely in your PostgreSQL database. Implement your own retention policy:

-- Delete audit logs older than 7 years (adjust to your compliance requirement)
DELETE FROM audit_logs
WHERE created_at < NOW() - INTERVAL '7 years';

Run this in a scheduled job (e.g., pg_cron or a cron task).

Cloud

PlanDefault retentionMaximum
Free7 days7 days
Pro90 days90 days
Enterprise1 yearUnlimited (custom)

Contact support@hellojohn.dev for extended retention on Enterprise.

Immutability

Audit logs are append-only. Even administrators cannot modify or delete individual audit log entries through the API or dashboard. On self-hosted deployments, immutability depends on restricting direct database access — the hellojohn database user does not have DELETE permission on the audit_logs table by default.

For compliance scenarios requiring cryptographic non-repudiation, contact us about our Enterprise audit log signing feature which adds a hash chain to each entry.

On this page