Files
Charon/docs/features/audit-logging.md
GitHub Actions 3169b05156 fix: skip incomplete system log viewer tests
- Marked 12 tests as skip pending feature implementation
- Features tracked in GitHub issue #686 (system log viewer feature completion)
- Tests cover sorting by timestamp/level/method/URI/status, pagination controls, filtering by text/level, download functionality
- Unblocks Phase 2 at 91.7% pass rate to proceed to Phase 3 security enforcement validation
- TODO comments in code reference GitHub #686 for feature completion tracking
- Tests skipped: Pagination (3), Search/Filter (2), Download (2), Sorting (1), Log Display (4)
2026-02-09 21:55:55 +00:00

638 lines
19 KiB
Markdown

# 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 |
## Filtering and Search
### 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
### Search
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:**
```json
{
"name": "Cloudflare Production",
"type": "cloudflare",
"is_default": true
}
```
**Update Event Example:**
```json
{
"changed_fields": ["credentials", "is_default"],
"old_values": {
"is_default": false
},
"new_values": {
"is_default": true
}
}
```
**Test Event Example:**
```json
{
"test_result": "success",
"response_time_ms": 342
}
```
**Decrypt Event Example:**
```json
{
"purpose": "certificate_issuance",
"success": true
}
```
### Finding Related Events
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 **Settings****DNS 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:
```bash
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:**
```http
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:**
```bash
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:**
```json
{
"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:**
```http
GET /api/v1/audit-logs/:uuid
```
**Parameters:**
- `uuid` (string, required): Event UUID
**Example Request:**
```bash
curl -X GET "https://charon.example.com/api/v1/audit-logs/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer YOUR_TOKEN"
```
**Response:**
```json
{
"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:**
```http
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:**
```bash
curl -X GET "https://charon.example.com/api/v1/dns-providers/3/audit-logs?page=1&limit=50" \
-H "Authorization: Bearer YOUR_TOKEN"
```
**Response:**
```json
{
"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:
```bash
# 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:**
```bash
AUDIT_LOG_RETENTION_DAYS=90 # Default: 90 days
```
**Docker Compose:**
```yaml
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:**
```bash
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)
## Related Features
- [DNS Challenge Support](./dns-challenge.md) - Configure DNS providers for automated certificates
- [Security Features](./security.md) - WAF, access control, and security notifications
- [Notifications](./notifications.md) - Get alerts for security events
## Support
For questions or issues with audit logging:
1. Check the [Troubleshooting](#troubleshooting) section above
2. Review the [GitHub Issues](https://github.com/Wikid82/charon/issues) for known problems
3. Open a new issue with the `audit-logging` label
4. Join the [Discord community](https://discord.gg/charon) for real-time support
---
**Last Updated:** January 3, 2026
**Feature Version:** v1.2.0
**Documentation Version:** 1.0