Files
Charon/docs/features/audit-logging.md
akanealw eec8c28fb3
Some checks are pending
Go Benchmark / Performance Regression Check (push) Waiting to run
Cerberus Integration / Cerberus Security Stack Integration (push) Waiting to run
Upload Coverage to Codecov / Backend Codecov Upload (push) Waiting to run
Upload Coverage to Codecov / Frontend Codecov Upload (push) Waiting to run
CodeQL - Analyze / CodeQL analysis (go) (push) Waiting to run
CodeQL - Analyze / CodeQL analysis (javascript-typescript) (push) Waiting to run
CrowdSec Integration / CrowdSec Bouncer Integration (push) Waiting to run
Docker Build, Publish & Test / build-and-push (push) Waiting to run
Docker Build, Publish & Test / Security Scan PR Image (push) Blocked by required conditions
Quality Checks / Auth Route Protection Contract (push) Waiting to run
Quality Checks / Codecov Trigger/Comment Parity Guard (push) Waiting to run
Quality Checks / Backend (Go) (push) Waiting to run
Quality Checks / Frontend (React) (push) Waiting to run
Rate Limit integration / Rate Limiting Integration (push) Waiting to run
Security Scan (PR) / Trivy Binary Scan (push) Waiting to run
Supply Chain Verification (PR) / Verify Supply Chain (push) Waiting to run
WAF integration / Coraza WAF Integration (push) Waiting to run
changed perms
2026-04-22 18:19:14 +00:00

19 KiB
Executable File

Audit Logging

Charon's audit logging system provides comprehensive tracking of all DNS provider credential operations, giving you complete visibility into who accessed, modified, or used sensitive credentials.

Overview

Audit logging automatically records security-sensitive operations for compliance, security monitoring, and troubleshooting. Every action involving DNS provider credentials is tracked with full context including:

  • Who: User ID or system actor
  • What: Specific action performed (create, update, delete, test, decrypt)
  • When: Precise timestamp
  • Where: IP address and user agent
  • Why: Full event context and metadata

Why Audit Logging Matters

  • Security Monitoring: Detect unauthorized access or suspicious patterns
  • Compliance: Meet SOC 2, GDPR, HIPAA, and PCI-DSS requirements for audit trails
  • Troubleshooting: Diagnose certificate issuance failures retrospectively
  • Accountability: Track all credential operations with full attribution

Accessing Audit Logs

Navigation

  1. Navigate to Security in the main menu
  2. Click Audit Logs in the submenu
  3. The audit log table displays recent events with pagination

UI Overview

The audit log interface consists of:

  • Data Table: Lists all audit events with key information
  • Filter Bar: Refine results by date, category, actor, action, or resource
  • Search Box: Full-text search across event details
  • Details Modal: View complete event information with related events
  • Export Button: Download audit logs as CSV for external analysis

Understanding Audit Events

Event Categories

All audit events are categorized for easy filtering:

Category Description Example Events
dns_provider DNS provider credential operations Create, update, delete, test credentials
certificate Certificate lifecycle events Issuance, renewal, failure
system System-level operations Automated credential decryption

Event Actions

Charon logs the following DNS provider operations:

Action When It's Logged Details Captured
dns_provider_create New DNS provider added Provider name, type, is_default flag
dns_provider_update Provider settings changed Changed fields, old values, new values
dns_provider_delete Provider removed Provider name, type, whether credentials existed
credential_test Credentials tested via API Provider name, test result, error message
credential_decrypt Caddy reads credentials for cert issuance Provider name, purpose (certificate_issuance)
certificate_issued Certificate successfully issued Domain, provider used, success/failure status

Date Range Filter

Filter events by time period:

  1. Click the Date Range dropdown
  2. Select a preset (Last 24 Hours, Last 7 Days, Last 30 Days, Last 90 Days)
  3. Or select Custom Range and pick specific start and end dates
  4. Results update automatically

Category Filter

Filter by event category:

  1. Click the Category dropdown
  2. Select one or more categories (dns_provider, certificate, system)
  3. Only events matching selected categories will be displayed

Actor Filter

Filter by who performed the action:

  1. Click the Actor dropdown
  2. Select a user from the list (shows both username and user ID)
  3. Select System to see automated operations
  4. View only events from the selected actor

Action Filter

Filter by specific operation type:

  1. Click the Action dropdown
  2. Select one or more actions (create, update, delete, test, decrypt)
  3. Results show only the selected action types

Resource Filter

Filter by specific DNS provider:

  1. Click the Resource dropdown
  2. Select a DNS provider from the list
  3. View only events related to that provider

Perform free-text search across all event details:

  1. Enter search terms in the Search box
  2. Press Enter or click the search icon
  3. Results include events where the search term appears in:
    • Provider name
    • Event details JSON
    • IP addresses
    • User agents

Clearing Filters

  • Click the Clear Filters button to reset all filters
  • Filters persist while navigating within the audit log page
  • Filters reset when you leave and return to the page

Viewing Event Details

Opening the Details Modal

  1. Click any row in the audit log table
  2. Or click the View Details button on the right side of a row

Details Modal Contents

The details modal displays:

  • Event UUID: Unique identifier for the event
  • Timestamp: Exact date and time (ISO 8601 format)
  • Actor: User ID or "system" for automated operations
  • Action: Operation performed
  • Category: Event category (dns_provider, certificate, etc.)
  • Resource: DNS provider name and UUID
  • IP Address: Client IP that initiated the operation
  • User Agent: Browser or API client information
  • Full Details: Complete JSON payload with all event metadata

Understanding the Details JSON

The details field contains a JSON object with event-specific information:

Create Event Example:

{
  "name": "Cloudflare Production",
  "type": "cloudflare",
  "is_default": true
}

Update Event Example:

{
  "changed_fields": ["credentials", "is_default"],
  "old_values": {
    "is_default": false
  },
  "new_values": {
    "is_default": true
  }
}

Test Event Example:

{
  "test_result": "success",
  "response_time_ms": 342
}

Decrypt Event Example:

{
  "purpose": "certificate_issuance",
  "success": true
}
  1. In the details modal, note the Resource UUID
  2. Click View Related Events to see all events for this resource
  3. Or manually filter by Resource UUID using the filter bar

Exporting Audit Logs

CSV Export

Export audit logs for external analysis, compliance reporting, or archival:

  1. Apply desired filters to narrow down events
  2. Click the Export CSV button
  3. A CSV file downloads with the following columns:
    • Timestamp
    • Actor
    • Action
    • Event Category
    • Resource ID
    • Resource UUID
    • IP Address
    • User Agent
    • Details

Export Use Cases

  • Compliance Reports: Generate quarterly audit reports for SOC 2
  • Security Analysis: Import into SIEM tools for threat detection
  • Forensics: Investigate security incidents with complete audit trail
  • Backup: Archive audit logs beyond the retention period

Export Limitations

  • Exports are limited to 10,000 events per download
  • For larger exports, use date range filters to split into multiple files
  • Exports respect all active filters (date, category, actor, etc.)

Event Scenarios

Scenario 1: New DNS Provider Setup

Timeline:

  1. User admin@example.com logs in from 192.168.1.100
  2. Navigates to DNS Providers page
  3. Clicks "Add DNS Provider"
  4. Fills in Cloudflare credentials and clicks Save

Audit Log Entries:

2026-01-03 14:23:45 | user:5 | dns_provider_create | dns_provider | {"name":"Cloudflare Prod","type":"cloudflare","is_default":true}

Scenario 2: Credential Testing

Timeline:

  1. User tests existing provider credentials
  2. API validation succeeds

Audit Log Entries:

2026-01-03 14:25:12 | user:5 | credential_test | dns_provider | {"test_result":"success","response_time_ms":342}

Scenario 3: Certificate Issuance

Timeline:

  1. Caddy detects new host requires SSL certificate
  2. Caddy decrypts DNS provider credentials
  3. ACME DNS-01 challenge completes successfully
  4. Certificate issued

Audit Log Entries:

2026-01-03 14:30:00 | system | credential_decrypt | dns_provider | {"purpose":"certificate_issuance","success":true}
2026-01-03 14:30:45 | system | certificate_issued | certificate | {"domain":"app.example.com","provider":"cloudflare","result":"success"}

Scenario 4: Provider Update

Timeline:

  1. User updates default provider setting
  2. API saves changes

Audit Log Entries:

2026-01-03 15:00:22 | user:5 | dns_provider_update | dns_provider | {"changed_fields":["is_default"],"old_values":{"is_default":false},"new_values":{"is_default":true}}

Scenario 5: Provider Deletion

Timeline:

  1. User deletes unused DNS provider
  2. Credentials are securely wiped

Audit Log Entries:

2026-01-03 16:45:33 | user:5 | dns_provider_delete | dns_provider | {"name":"Old Provider","type":"route53","had_credentials":true}

Viewing Provider-Specific Audit History

From DNS Provider Page

  1. Navigate to SettingsDNS Providers
  2. Click on any DNS provider to open the edit form
  3. Click the View Audit History button
  4. See all audit events for this specific provider

API Endpoint

You can also retrieve provider-specific audit logs via API:

GET /api/v1/dns-providers/:id/audit-logs?page=1&limit=50

Troubleshooting

Common Questions

Q: Why don't I see audit logs from before today?

A: Audit logging was introduced in Charon v1.2.0. Only events after the feature was enabled are logged. Previous operations are not retroactively logged.

Q: How long are audit logs kept?

A: By default, audit logs are retained for 90 days. After 90 days, logs are automatically deleted to prevent unbounded database growth. Administrators can configure the retention period via environment variable AUDIT_LOG_RETENTION_DAYS.

Q: Can audit logs be modified or deleted?

A: No. Audit logs are immutable and append-only. Only the automatic cleanup job (based on retention policy) can delete logs. This ensures audit trail integrity for compliance purposes.

Q: What happens if audit logging fails?

A: Audit logging is non-blocking and asynchronous. If the audit log channel is full or the database is temporarily unavailable, the event is dropped but the primary operation (e.g., creating a DNS provider) succeeds. Dropped events are logged to the application log for monitoring.

Q: Do audit logs include credential values?

A: No. Audit logs never include actual credential values (API keys, tokens, passwords). Only metadata about the operation is logged (provider name, type, whether credentials were present).

Q: Can I see who viewed credentials?

A: Credentials are never "viewed" directly. The only access logged is when credentials are decrypted for certificate issuance (logged as credential_decrypt with actor "system").

Performance Impact

Audit logging is designed for minimal performance impact:

  • Asynchronous Writes: Audit events are written via a buffered channel and background goroutine
  • Non-Blocking: Failed audit writes do not block API operations
  • Indexed Queries: Database indexes on created_at, event_category, resource_uuid, and actor ensure fast filtering
  • Automatic Cleanup: Old logs are periodically deleted to prevent database bloat

Typical Impact:

  • API request latency: +0.1ms (sending to channel)
  • Database writes: Batched in background, no user-facing impact
  • Storage: ~500 bytes per event, ~1.5 GB per year at 100 events/day

Missing Events

If you expect to see an event but don't:

  1. Check filters: Clear all filters and search to see all events
  2. Check date range: Expand date range to "Last 90 Days"
  3. Check retention policy: Event may have been automatically deleted
  4. Check application logs: Look for "audit channel full" or "Failed to write audit log" messages

Slow Query Performance

If audit log pages load slowly:

  1. Narrow date range: Searching 90 days of logs is slower than 7 days
  2. Use specific filters: Filter by category, actor, or action before searching
  3. Check database indexes: Ensure indexes on security_audits table are present
  4. Consider archival: Export and delete old logs if database is very large

API Reference

List Audit Logs

Retrieve audit logs with pagination and filtering.

Endpoint:

GET /api/v1/audit-logs

Query Parameters:

  • page (int, default: 1): Page number
  • limit (int, default: 50, max: 100): Results per page
  • actor (string): Filter by actor (user ID or "system")
  • action (string): Filter by action type
  • event_category (string): Filter by category (dns_provider, certificate, etc.)
  • resource_uuid (string): Filter by resource UUID
  • start_date (RFC3339): Start of date range
  • end_date (RFC3339): End of date range

Example Request:

curl -X GET "https://charon.example.com/api/v1/audit-logs?page=1&limit=50&event_category=dns_provider&start_date=2026-01-01T00:00:00Z" \
  -H "Authorization: Bearer YOUR_TOKEN"

Response:

{
  "audit_logs": [
    {
      "id": 1,
      "uuid": "550e8400-e29b-41d4-a716-446655440000",
      "actor": "user:5",
      "action": "dns_provider_create",
      "event_category": "dns_provider",
      "resource_id": 3,
      "resource_uuid": "660e8400-e29b-41d4-a716-446655440001",
      "details": "{\"name\":\"Cloudflare\",\"type\":\"cloudflare\",\"is_default\":true}",
      "ip_address": "192.168.1.100",
      "user_agent": "Mozilla/5.0 (X11; Linux x86_64) Chrome/120.0",
      "created_at": "2026-01-03T14:23:45Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 1,
    "total_pages": 1
  }
}

Get Single Audit Event

Retrieve complete details for a specific audit event.

Endpoint:

GET /api/v1/audit-logs/:uuid

Parameters:

  • uuid (string, required): Event UUID

Example Request:

curl -X GET "https://charon.example.com/api/v1/audit-logs/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_TOKEN"

Response:

{
  "id": 1,
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "actor": "user:5",
  "action": "dns_provider_create",
  "event_category": "dns_provider",
  "resource_id": 3,
  "resource_uuid": "660e8400-e29b-41d4-a716-446655440001",
  "details": "{\"name\":\"Cloudflare\",\"type\":\"cloudflare\",\"is_default\":true}",
  "ip_address": "192.168.1.100",
  "user_agent": "Mozilla/5.0 (X11; Linux x86_64) Chrome/120.0",
  "created_at": "2026-01-03T14:23:45Z"
}

Get Provider Audit History

Retrieve all audit events for a specific DNS provider.

Endpoint:

GET /api/v1/dns-providers/:id/audit-logs

Parameters:

  • id (int, required): DNS provider ID

Query Parameters:

  • page (int, default: 1): Page number
  • limit (int, default: 50, max: 100): Results per page

Example Request:

curl -X GET "https://charon.example.com/api/v1/dns-providers/3/audit-logs?page=1&limit=50" \
  -H "Authorization: Bearer YOUR_TOKEN"

Response:

{
  "audit_logs": [
    {
      "id": 3,
      "uuid": "770e8400-e29b-41d4-a716-446655440002",
      "actor": "user:5",
      "action": "dns_provider_update",
      "event_category": "dns_provider",
      "resource_id": 3,
      "resource_uuid": "660e8400-e29b-41d4-a716-446655440001",
      "details": "{\"changed_fields\":[\"is_default\"],\"new_values\":{\"is_default\":true}}",
      "ip_address": "192.168.1.100",
      "user_agent": "Mozilla/5.0 (X11; Linux x86_64) Chrome/120.0",
      "created_at": "2026-01-03T15:00:22Z"
    },
    {
      "id": 1,
      "uuid": "550e8400-e29b-41d4-a716-446655440000",
      "actor": "user:5",
      "action": "dns_provider_create",
      "event_category": "dns_provider",
      "resource_id": 3,
      "resource_uuid": "660e8400-e29b-41d4-a716-446655440001",
      "details": "{\"name\":\"Cloudflare\",\"type\":\"cloudflare\",\"is_default\":true}",
      "ip_address": "192.168.1.100",
      "user_agent": "Mozilla/5.0 (X11; Linux x86_64) Chrome/120.0",
      "created_at": "2026-01-03T14:23:45Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 2,
    "total_pages": 1
  }
}

Authentication

All audit log API endpoints require authentication. Include a valid session cookie or Bearer token:

# Cookie-based auth (from browser)
Cookie: session=YOUR_SESSION_TOKEN

# Bearer token auth (from API client)
Authorization: Bearer YOUR_API_TOKEN

Error Responses

Status Code Error Description
400 Invalid parameter Invalid page/limit or malformed date
401 Unauthorized Missing or invalid authentication
404 Not found Audit event UUID does not exist
500 Server error Database error or service unavailable

Configuration

Retention Period

Configure how long audit logs are retained before automatic deletion:

Environment Variable:

AUDIT_LOG_RETENTION_DAYS=90  # Default: 90 days

Docker Compose:

services:
  charon:
    environment:
      - AUDIT_LOG_RETENTION_DAYS=180  # 6 months

Channel Buffer Size

Configure the size of the audit log channel buffer (advanced):

Environment Variable:

AUDIT_LOG_CHANNEL_SIZE=1000  # Default: 1000 events

Increase if you see "audit channel full" errors in application logs during high-load periods.

Best Practices

  1. Regular Reviews: Schedule weekly or monthly reviews of audit logs to spot anomalies
  2. Alert on Patterns: Set up alerts for suspicious patterns (e.g., bulk deletions, off-hours access)
  3. Export for Compliance: Regularly export logs for compliance archival before they're auto-deleted
  4. Filter Before Export: Use filters to export only relevant events for specific audits
  5. Document Procedures: Create runbooks for investigating common security scenarios
  6. Integrate with SIEM: Export logs to your SIEM tool for centralized security monitoring
  7. Test Retention Policy: Verify the retention period meets your compliance requirements

Security Considerations

  • Immutable Logs: Audit logs cannot be modified or deleted by users (only auto-cleanup)
  • No Credential Leakage: Actual credential values are never logged
  • Complete Attribution: Every event includes actor, IP, and user agent for full traceability
  • Secure Storage: Audit logs are stored in the same encrypted database as other sensitive data
  • Access Control: Audit log viewing requires authentication (no anonymous access)

Support

For questions or issues with audit logging:

  1. Check the Troubleshooting section above
  2. Review the GitHub Issues for known problems
  3. Open a new issue with the audit-logging label
  4. Join the Discord community for real-time support

Last Updated: January 3, 2026 Feature Version: v1.2.0 Documentation Version: 1.0