Audit Logs¶
Audit logs provide a comprehensive record of all actions performed within your Escape organization. Essential for security monitoring, compliance reporting, and incident investigation.
Examples using date -d require GNU date. On macOS, use BSD date's -v option instead; for example, date -u -v-24H +%Y-%m-%dT%H:%M:%SZ gives the timestamp 24 hours ago.
Overview¶
Audit logs support the following event types (availability may depend on the triggering workflow):
- User authentication events (login)
- Scan lifecycle events (created, finished, canceled, updated)
- Profile and asset updates (including bulk operations)
- Issue status updates (individual and bulk)
- Workflow rule updates (created, updated, deleted)
- Integration updates (created, updated, deleted)
- Private location management
- Report generation and delivery
- Access control events (roles, permissions, user invitations)
Audit logs are critical for:
- Compliance: SOC 2, ISO 27001, PCI DSS, HIPAA
- Security Monitoring: Detect unauthorized access or suspicious activities
- Incident Response: Investigate security events and track changes
- Accountability: Track who did what and when
Listing Audit Logs¶
View organization activity history with flexible filtering.
Aliases: ls, logs, audits
Filtering Options¶
| Flag | Short | Description | Format |
|---|---|---|---|
--date-from |
-f |
Start date | RFC3339 (for example 2025-01-01T00:00:00Z) |
--date-to |
-t |
End date | RFC3339 |
--event-type |
-e |
Event type | Event type string |
--actor |
-a |
Filter by actor | User ID or email |
--search |
-s |
Free-text search | Any string |
--limit |
Limit result count | Integer (for example 10, 100) |
Default Time Range: Last 12 hours
Basic Examples¶
# List recent audit logs (last 12 hours)
escape-cli audit list
# List last 24 hours
escape-cli audit list --date-from $(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ)
# List specific date range
escape-cli audit list \
--date-from 2025-01-01T00:00:00Z \
--date-to 2025-01-31T23:59:59Z
# List today's logs
escape-cli audit list \
--date-from $(date -u +%Y-%m-%dT00:00:00Z)
# Limit results to 10 entries
escape-cli audit list --limit 10
# Combine filtering with limit
escape-cli audit list \
--event-type scan.created \
--limit 5
Filtering by Event Type¶
# Scan events
escape-cli audit list --event-type scan.created
escape-cli audit list --event-type scan.finished
escape-cli audit list --event-type scan.canceled
# User authentication events
escape-cli audit list --event-type user.authenticated
escape-cli audit list --event-type user.logged-out
# Configuration changes
escape-cli audit list --event-type profile.updated
escape-cli audit list --event-type asset.created
Filtering by Actor¶
# Filter by specific user
escape-cli audit list --actor user@example.com
# Filter by user ID
escape-cli audit list --actor 00000000-0000-0000-0000-000000000000
Free-Text Search¶
# Search across all log fields
escape-cli audit list --search "production"
escape-cli audit list --search "failed"
escape-cli audit list --search "critical"
Output Format¶
Table Format (Default)¶
Example Output:
DATE ACTION ACTOR ACTOR EMAIL TITLE
2025-10-15T10:30:00Z scan.created john-doe john@example.com Started scan on Production API
2025-10-15T10:15:00Z profile.updated jane-smith jane@example.com Updated profile configuration
2025-10-15T10:00:00Z user.authenticated admin-user admin@example.com User authenticated via API key
JSON Format¶
Example Output:
[
{
"id": "00000000-0000-0000-0000-000000000000",
"date": "2025-10-15T10:30:00Z",
"action": "scan.created",
"actor": "john-doe",
"actorEmail": "john@example.com",
"title": "Started scan on Production API"
}
]
Common Event Types¶
Scan Events¶
| Event Type | Description |
|---|---|
scan.scheduled |
Scan scheduled for execution |
scan.created |
Scan created and started |
scan.finished |
Scan completed |
scan.canceled |
Scan was canceled |
scan.updated |
Scan status changed (for example ignored/unignored) |
Profile Events¶
| Event Type | Description |
|---|---|
profile.created |
New profile created |
profile.updated |
Profile configuration changed |
profile.deleted |
Profile removed |
profiles.bulk.updated |
Multiple profiles updated in bulk |
Asset Events¶
| Event Type | Description |
|---|---|
asset.created |
New asset added |
asset.updated |
Asset metadata changed |
asset.deleted |
Asset removed |
assets.updated |
Multiple assets updated in bulk |
assets.multiple.creation.requested |
Bulk asset creation scheduled |
assets.deletion-scheduled |
Asset deletion scheduled |
Issue Events¶
| Event Type | Description |
|---|---|
issue.updated |
Issue status or properties changed |
issues.updated |
Multiple issues updated in bulk |
Workflow Events¶
| Event Type | Description |
|---|---|
workflow.created |
New workflow rule created |
workflow.updated |
Workflow rule configuration changed |
workflow.deleted |
Workflow rule removed |
User Events¶
| Event Type | Description |
|---|---|
user.authenticated |
User logged in |
user.logged-out |
User logged out |
user.confirmed |
User account confirmed |
user.deactivated |
User account deactivated |
user.invited |
User invited |
users.invited |
Multiple users invited |
Private Location Events¶
| Event Type | Description |
|---|---|
proxy.created |
New private location created |
proxy.updated |
Location configuration changed |
proxy.deleted |
Private location removed |
Integration Events¶
| Event Type | Description |
|---|---|
integration.created |
New integration added |
integration.updated |
Integration changed |
integration.deleted |
Integration removed |
Reporting Events¶
| Event Type | Description |
|---|---|
reporting.generation.requested |
Report generation requested |
reporting.email.requested |
Report email delivery requested |
Compliance Reporting¶
Generate Monthly Report¶
#!/bin/bash
# Generate compliance report for the month
MONTH="2025-01"
START_DATE="${MONTH}-01T00:00:00Z"
END_DATE="${MONTH}-31T23:59:59Z"
escape-cli audit list \
--date-from "$START_DATE" \
--date-to "$END_DATE" \
-o json > "audit-report-${MONTH}.json"
echo "Audit report generated: audit-report-${MONTH}.json"
# Generate summary
jq 'group_by(.action) | map({action: .[0].action, count: length})' \
"audit-report-${MONTH}.json" > "audit-summary-${MONTH}.json"
echo "Summary generated: audit-summary-${MONTH}.json"
Generate User Activity Report¶
#!/bin/bash
# Track all actions by a specific user
USER_EMAIL="user@example.com"
START_DATE="2025-01-01T00:00:00Z"
escape-cli audit list \
--actor "$USER_EMAIL" \
--date-from "$START_DATE" \
-o json > "user-activity-${USER_EMAIL}.json"
# Count actions by type
jq 'group_by(.action) | map({action: .[0].action, count: length})' \
"user-activity-${USER_EMAIL}.json"
Export for SIEM Integration¶
#!/bin/bash
# Export audit logs to SIEM (Splunk, ELK)
# Get last hour of logs
ONE_HOUR_AGO=$(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ)
escape-cli audit list \
--date-from "$ONE_HOUR_AGO" \
-o json | \
jq -c '.[]' | \
while read -r log; do
# Send to SIEM endpoint
curl -X POST https://siem.example.com/api/logs \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SIEM_TOKEN" \
-d "$log"
done
Security Monitoring¶
Monitor User Logouts¶
# Track user logout events
escape-cli audit list --event-type user.logged-out -o json | \
jq -r '.[] | "\(.date) - \(.actorEmail) - Logged out"'
Track Configuration Changes¶
# Monitor all configuration changes
escape-cli audit list \
--date-from $(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ) \
-o json | \
jq '.[] | select(.action | contains("updated") or contains("created") or contains("deleted"))'
Alert on Suspicious Activity¶
#!/bin/bash
# Alert on multiple canceled scans
CANCELED_SCANS=$(escape-cli audit list \
--event-type scan.canceled \
--date-from $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ) \
-o json | jq 'length')
if [ "$CANCELED_SCANS" -gt 5 ]; then
echo "ALERT: $CANCELED_SCANS canceled scans in the last hour"
# Send alert (email, Slack, PagerDuty)
fi
Data Analysis¶
Count Events by Type¶
escape-cli audit list \
--date-from 2025-01-01T00:00:00Z \
-o json | \
jq 'group_by(.action) | map({action: .[0].action, count: length}) | sort_by(.count) | reverse'
Example Output:
[
{"action": "scan.finished", "count": 450},
{"action": "scan.created", "count": 450},
{"action": "issue.updated", "count": 123},
{"action": "profile.updated", "count": 45},
{"action": "user.authenticated", "count": 38}
]
Most Active Users¶
escape-cli audit list \
--date-from 2025-01-01T00:00:00Z \
-o json | \
jq 'group_by(.actorEmail) | map({user: .[0].actorEmail, actions: length}) | sort_by(.actions) | reverse | .[0:10]'
Activity Timeline¶
# Get hourly activity distribution
escape-cli audit list \
--date-from $(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ) \
-o json | \
jq -r '.[] | .date' | \
cut -d'T' -f2 | \
cut -d':' -f1 | \
sort | uniq -c | \
awk '{print $2":00 - " $1 " events"}'
Continuous Monitoring¶
Real-Time Log Monitoring¶
#!/bin/bash
# Monitor audit logs in real-time (poll every 30 seconds)
LAST_CHECK=$(date -u +%Y-%m-%dT%H:%M:%SZ)
while true; do
sleep 30
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
NEW_LOGS=$(escape-cli audit list \
--date-from "$LAST_CHECK" \
--date-to "$NOW" \
-o json)
if [ "$(echo "$NEW_LOGS" | jq 'length')" -gt 0 ]; then
echo "=== New Activity ==="
echo "$NEW_LOGS" | jq -r '.[] | "\(.date) [\(.action)] \(.actorEmail) - \(.title)"'
fi
LAST_CHECK=$NOW
done
Scheduled Reports¶
#!/bin/bash
# Daily audit report (run via cron)
DATE=$(date -u -d 'yesterday' +%Y-%m-%d)
REPORT_FILE="audit-daily-${DATE}.json"
escape-cli audit list \
--date-from "${DATE}T00:00:00Z" \
--date-to "${DATE}T23:59:59Z" \
-o json > "$REPORT_FILE"
# Generate summary
TOTAL=$(jq 'length' "$REPORT_FILE")
SCANS=$(jq '[.[] | select(.action | contains("scan"))] | length' "$REPORT_FILE")
ISSUES=$(jq '[.[] | select(.action | contains("issue"))] | length' "$REPORT_FILE")
cat > "daily-summary-${DATE}.txt" <<EOF
Audit Log Summary for $DATE
============================
Total Events: $TOTAL
Scan Events: $SCANS
Issue Events: $ISSUES
Full report: $REPORT_FILE
EOF
# Email or send to monitoring system
cat "daily-summary-${DATE}.txt"
Best Practices¶
Retention and Archiving¶
- Export audit logs regularly for long-term storage
- Maintain at least 90 days of audit history for compliance
- Archive logs to secure, immutable storage (S3, Azure Blob)
- Implement log rotation and cleanup policies
Access Control¶
- Restrict audit log access to authorized personnel
- Use dedicated service accounts for automated log collection
- Enable multi-factor authentication for audit log access
- Regularly review who has access to audit logs
Monitoring and Alerting¶
- Set up alerts for critical events (failed scans, configuration changes)
- Monitor for unusual patterns or anomalies
- Integrate with SIEM systems for centralized monitoring
- Create dashboards for real-time visibility
Compliance¶
- Document audit log review procedures
- Schedule regular audit log reviews
- Maintain evidence of log reviews for auditors
- Ensure audit logs can't be tampered with
Integration Examples¶
Splunk Integration¶
#!/bin/bash
# Send audit logs to Splunk
escape-cli audit list \
--date-from $(date -u -d '5 minutes ago' +%Y-%m-%dT%H:%M:%SZ) \
-o json | \
jq -c '.[]' | \
while read -r event; do
curl https://splunk.example.com:8088/services/collector/event \
-H "Authorization: Splunk $SPLUNK_TOKEN" \
-d "{\"event\": $event, \"sourcetype\": \"escape:audit\"}"
done
Elasticsearch Integration¶
#!/bin/bash
# Send audit logs to Elasticsearch
escape-cli audit list \
--date-from $(date -u -d '5 minutes ago' +%Y-%m-%dT%H:%M:%SZ) \
-o json | \
jq -c '.[]' | \
while read -r event; do
curl -X POST "http://elasticsearch.example.com:9200/escape-audit/_doc" \
-H "Content-Type: application/json" \
-d "$event"
done
Slack Notifications¶
#!/bin/bash
# Send critical events to Slack
escape-cli audit list \
--event-type scan.canceled \
--date-from $(date -u -d '10 minutes ago' +%Y-%m-%dT%H:%M:%SZ) \
-o json | \
jq -c '.[]' | \
while read -r event; do
MESSAGE=$(echo "$event" | jq -r '"\(.date): \(.title)"')
curl -X POST "$SLACK_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d "{\"text\": \":warning: Scan Canceled Alert\n${MESSAGE}\"}"
done
Troubleshooting¶
No Logs Returned¶
If no audit logs are returned:
- Check date range (default is last 12 hours)
- Verify you have permission to view audit logs
- Ensure the organization has activity in the specified timeframe
- Try removing filters to see all logs
Incomplete Log Data¶
If log entries are missing information:
- Some fields may be null for certain event types
- Use JSON output to see all available fields
- Check API permissions for your account
Performance Issues¶
For large date ranges:
- Break queries into smaller time chunks
- Use specific event-type filters when possible
- Export to JSON and process locally for complex analysis
- Consider using pagination for very large result sets
Next Steps¶
- Events Management - View scan execution logs
- Scan Problems - Troubleshoot scan failures
- Issues Management - Track security findings
- CI/CD Integration - Automate security workflows