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
- Navigate to Security in the main menu
- Click Audit Logs in the submenu
- 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 |
Filtering and Search
Date Range Filter
Filter events by time period:
- Click the Date Range dropdown
- Select a preset (Last 24 Hours, Last 7 Days, Last 30 Days, Last 90 Days)
- Or select Custom Range and pick specific start and end dates
- Results update automatically
Category Filter
Filter by event category:
- Click the Category dropdown
- Select one or more categories (dns_provider, certificate, system)
- Only events matching selected categories will be displayed
Actor Filter
Filter by who performed the action:
- Click the Actor dropdown
- Select a user from the list (shows both username and user ID)
- Select System to see automated operations
- View only events from the selected actor
Action Filter
Filter by specific operation type:
- Click the Action dropdown
- Select one or more actions (create, update, delete, test, decrypt)
- Results show only the selected action types
Resource Filter
Filter by specific DNS provider:
- Click the Resource dropdown
- Select a DNS provider from the list
- View only events related to that provider
Search
Perform free-text search across all event details:
- Enter search terms in the Search box
- Press Enter or click the search icon
- 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
- Click any row in the audit log table
- 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
}
Finding Related Events
- In the details modal, note the Resource UUID
- Click View Related Events to see all events for this resource
- 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:
- Apply desired filters to narrow down events
- Click the Export CSV button
- 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:
- User
admin@example.comlogs in from192.168.1.100 - Navigates to DNS Providers page
- Clicks "Add DNS Provider"
- 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:
- User tests existing provider credentials
- 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:
- Caddy detects new host requires SSL certificate
- Caddy decrypts DNS provider credentials
- ACME DNS-01 challenge completes successfully
- 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:
- User updates default provider setting
- 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:
- User deletes unused DNS provider
- 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
- Navigate to Settings → DNS Providers
- Click on any DNS provider to open the edit form
- Click the View Audit History button
- 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, andactorensure 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:
- Check filters: Clear all filters and search to see all events
- Check date range: Expand date range to "Last 90 Days"
- Check retention policy: Event may have been automatically deleted
- Check application logs: Look for "audit channel full" or "Failed to write audit log" messages
Slow Query Performance
If audit log pages load slowly:
- Narrow date range: Searching 90 days of logs is slower than 7 days
- Use specific filters: Filter by category, actor, or action before searching
- Check database indexes: Ensure indexes on
security_auditstable are present - 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 numberlimit(int, default: 50, max: 100): Results per pageactor(string): Filter by actor (user ID or "system")action(string): Filter by action typeevent_category(string): Filter by category (dns_provider, certificate, etc.)resource_uuid(string): Filter by resource UUIDstart_date(RFC3339): Start of date rangeend_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 numberlimit(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
- Regular Reviews: Schedule weekly or monthly reviews of audit logs to spot anomalies
- Alert on Patterns: Set up alerts for suspicious patterns (e.g., bulk deletions, off-hours access)
- Export for Compliance: Regularly export logs for compliance archival before they're auto-deleted
- Filter Before Export: Use filters to export only relevant events for specific audits
- Document Procedures: Create runbooks for investigating common security scenarios
- Integrate with SIEM: Export logs to your SIEM tool for centralized security monitoring
- 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)
Related Features
- DNS Challenge Support - Configure DNS providers for automated certificates
- Security Features - WAF, access control, and security notifications
- Notifications - Get alerts for security events
Support
For questions or issues with audit logging:
- Check the Troubleshooting section above
- Review the GitHub Issues for known problems
- Open a new issue with the
audit-logginglabel - Join the Discord community for real-time support
Last Updated: January 3, 2026 Feature Version: v1.2.0 Documentation Version: 1.0