-
Notifications
You must be signed in to change notification settings - Fork 2
Audit Logging
Weylon Solis edited this page Mar 18, 2026
·
1 revision
ForceHound's audit logging produces a JSONL file recording every HTTP request made during collection. The schema is aligned with OCSF API Activity (class_uid 6003) for native SIEM ingestion.
forcehound ... --audit-log 3 -o output.jsonOutput: forcehound_audit_<timestamp>.jsonl
| Level | Per-entry content | Use case |
|---|---|---|
| 1 | Timestamp, operation, target, status code | Quick activity ledger — grep/jq-friendly |
| 2 | Level 1 + duration, HTTP headers, error detail | Operational debugging |
| 3 | Level 2 + full request body + full response body | Forensic reconstruction |
Each level includes everything from lower levels.
Every log starts with a Session Start event and ends with a Session End event:
{"class_uid":6003,"activity_name":"Session Start","metadata":{"product":{"name":"ForceHound"},"log_level":3},...}
{"class_uid":6003,"activity_id":2,"activity_name":"Read","api":{"operation":"query_all","request":{"uid":"1"}},...}
{"class_uid":6003,"activity_id":2,"activity_name":"Read","api":{"operation":"query_all","request":{"uid":"2"}},...}
...
{"class_uid":6003,"activity_name":"Session End","duration":12345,"unmapped":{"total_entries":42,"total_requests":41},...}| ForceHound action | activity_id | activity_name |
|---|---|---|
| SOQL SELECT, getObjectInfo, getItems, getRecordWithFields | 2 | Read |
| createRecord | 1 | Create |
| updateRecord | 3 | Update |
| deleteRecord | 4 | Delete |
| Session lifecycle | 99 | Other |
| Field | Description |
|---|---|
class_uid |
Always 6003 (OCSF API Activity) |
class_name |
Always "API Activity" |
time |
ISO 8601 timestamp |
api.operation |
Operation name (e.g., query_all, getObjectInfo, createRecord) |
api.request.uid |
Sequential request number (1, 2, 3, ...) |
status_id |
1 = Success, 2 = Failure |
status_code |
HTTP status code as string |
duration |
Request duration in milliseconds (Level 2+) |
http_request |
HTTP method, URL, headers (Level 2+) |
http_request.body |
Full request body (Level 3 only) |
raw_data |
Full response body (Level 3 only) |
message |
Human-readable summary line |
The JSONL format is natively supported by:
- Splunk — JSON sourcetype, auto-extracts fields, maps to CIM
- Elastic/ELK — Filebeat JSON input, maps to ECS
- Microsoft Sentinel — Log Analytics JSON ingestion, maps to ASIM
- AWS Security Lake — Native OCSF support
- CrowdStrike, Datadog, Google SecOps — All support OCSF/JSONL
# Count operations by type
jq -s 'map(.api.operation // empty) | group_by(.) | map({(.[0]): length}) | add' audit.jsonl
# Find all failed requests
jq 'select(.status_id == 2)' audit.jsonl
# Find all create operations
jq 'select(.api.operation == "createRecord")' audit.jsonl
# Extract request durations
jq 'select(.duration) | {operation: .api.operation, duration: .duration}' audit.jsonlLevel 3 logs contain session IDs in HTTP headers. The Session Start event includes a credential_warning field in unmapped to flag this. Treat Level 3 audit logs as credential artifacts.