mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-20 06:00:06 +08:00
Apply the official OCSF ai_operation profile (introduced in v1.8.0) to ApiActivity [6003] events when the inference proxy routes a model call through inference.local. Attaches an ai_model object (name, ai_provider) and puts token counts and latency in unmapped fields. ApiActivity [6003] is the schema-correct class for the ai_operation profile in v1.8.0 (HttpActivity only gets it in v1.9.0). In Splunk CIM, ApiActivity maps to the "Change" data model, naturally separating inference events from regular HTTP proxy traffic. Changes: - Add AiModel object and ai_model field on BaseEventData - Add ApiActivityEvent struct and ApiActivityBuilder - Add emit_ai_inference in proxy.rs using ApiActivity with ai_operation - Vendor OCSF v1.8.0 schemas including api_activity class, ai_model object, and ai_operation profile definitions - Bump OCSF_VERSION to 1.8.0 - Update schema validation to skip profile-gated required fields Shorthand: API:INFERENCE [INFO] claude-3-haiku via anthropic 701ms [POST /v1/messages] Splunk/SIEM backward compatibility (v1.1/v1.3 CIM mapping) is tracked separately in #2662 as a configurable serialization concern. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
199 lines
5.8 KiB
Plaintext
199 lines
5.8 KiB
Plaintext
---
|
|
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
title: "OCSF JSON Export"
|
|
sidebar-title: "OCSF JSON Export"
|
|
description: "How to enable full OCSF JSON logging for SIEM integration, compliance, and structured analysis."
|
|
keywords: "Generative AI, Cybersecurity, OCSF, JSON, SIEM, Compliance, Observability"
|
|
---
|
|
|
|
The [shorthand log format](/observability/logging) is optimized for humans and agents reading logs in real time. For machine consumption, compliance archival, or SIEM integration, you can enable full OCSF JSON export. This writes every OCSF event as a complete JSON record in JSONL format, one JSON object per line.
|
|
|
|
## Enable JSON Export
|
|
|
|
Use the `ocsf_json_enabled` setting to toggle JSON export. The setting can be applied globally, for all sandboxes, or per-sandbox.
|
|
|
|
Global:
|
|
|
|
```shell
|
|
openshell settings set --global --key ocsf_json_enabled --value true
|
|
```
|
|
|
|
Per-sandbox:
|
|
|
|
```shell
|
|
openshell settings set my-sandbox --key ocsf_json_enabled --value true
|
|
```
|
|
|
|
The setting takes effect on the next poll cycle, by default every 10 seconds. No sandbox restart is required.
|
|
|
|
To disable:
|
|
|
|
```shell
|
|
openshell settings set --global --key ocsf_json_enabled --value false
|
|
```
|
|
|
|
## Output Location
|
|
|
|
When enabled, OCSF JSON records are written to `/var/log/openshell-ocsf.YYYY-MM-DD.log` inside the sandbox. The file rotates daily and retains the 3 most recent files, matching the main log file rotation.
|
|
|
|
## JSON Record Structure
|
|
|
|
Each line is a complete OCSF v1.8.0 JSON object. Here is an example of a network connection event:
|
|
|
|
```json
|
|
{
|
|
"class_uid": 4001,
|
|
"class_name": "Network Activity",
|
|
"category_uid": 4,
|
|
"category_name": "Network Activity",
|
|
"activity_id": 1,
|
|
"activity_name": "Open",
|
|
"severity_id": 1,
|
|
"severity": "Informational",
|
|
"status_id": 1,
|
|
"status": "Success",
|
|
"time": 1775014138811,
|
|
"message": "CONNECT allowed api.github.com:443",
|
|
"metadata": {
|
|
"product": {
|
|
"name": "OpenShell Sandbox Supervisor",
|
|
"vendor_name": "NVIDIA",
|
|
"version": "0.3.0"
|
|
},
|
|
"version": "1.8.0"
|
|
},
|
|
"action_id": 1,
|
|
"action": "Allowed",
|
|
"disposition_id": 1,
|
|
"disposition": "Allowed",
|
|
"dst_endpoint": {
|
|
"domain": "api.github.com",
|
|
"port": 443
|
|
},
|
|
"src_endpoint": {
|
|
"ip": "10.42.0.31",
|
|
"port": 37494
|
|
},
|
|
"actor": {
|
|
"process": {
|
|
"name": "/usr/bin/curl",
|
|
"pid": 57
|
|
}
|
|
},
|
|
"firewall_rule": {
|
|
"name": "github_api",
|
|
"type": "opa"
|
|
}
|
|
}
|
|
```
|
|
|
|
And a denied connection:
|
|
|
|
```json
|
|
{
|
|
"class_uid": 4001,
|
|
"class_name": "Network Activity",
|
|
"activity_id": 1,
|
|
"activity_name": "Open",
|
|
"severity_id": 3,
|
|
"severity": "Medium",
|
|
"status_id": 2,
|
|
"status": "Failure",
|
|
"action_id": 2,
|
|
"action": "Denied",
|
|
"disposition_id": 2,
|
|
"disposition": "Blocked",
|
|
"status_detail": "no matching policy",
|
|
"message": "CONNECT denied httpbin.org:443",
|
|
"dst_endpoint": {
|
|
"domain": "httpbin.org",
|
|
"port": 443
|
|
},
|
|
"actor": {
|
|
"process": {
|
|
"name": "/usr/bin/curl",
|
|
"pid": 63
|
|
}
|
|
},
|
|
"firewall_rule": {
|
|
"name": "-",
|
|
"type": "opa"
|
|
}
|
|
}
|
|
```
|
|
|
|
<Note>
|
|
The JSON examples above are formatted for readability. The actual JSONL file contains one JSON object per line with no whitespace formatting.
|
|
</Note>
|
|
|
|
## OCSF Event Classes in JSON
|
|
|
|
The `class_uid` field identifies the event type:
|
|
|
|
| `class_uid` | Class | Shorthand prefix |
|
|
|---|---|---|
|
|
| 4001 | Network Activity | `NET:` |
|
|
| 4002 | HTTP Activity | `HTTP:` |
|
|
| 4007 | SSH Activity | `SSH:` |
|
|
| 1007 | Process Activity | `PROC:` |
|
|
| 2004 | Detection Finding | `FINDING:` |
|
|
| 5019 | Device Config State Change | `CONFIG:` |
|
|
| 6002 | Application Lifecycle | `LIFECYCLE:` |
|
|
| 6003 | API Activity | `API:INFERENCE` |
|
|
|
|
### API Activity [6003] — AI Inference
|
|
|
|
When the inference proxy routes a model call through `inference.local`, an API Activity event is emitted with the `ai_operation` profile:
|
|
|
|
```json
|
|
{
|
|
"class_uid": 6003,
|
|
"class_name": "API Activity",
|
|
"activity_id": 99,
|
|
"activity_name": "Other",
|
|
"api": { "operation": "POST /v1/messages" },
|
|
"actor": { "process": { "name": "openshell-supervisor", "pid": 1 } },
|
|
"src_endpoint": { "ip": "127.0.0.1", "port": 3128 },
|
|
"ai_model": { "name": "claude-haiku-4-5-20251001", "ai_provider": "https://api.anthropic.com/v1" },
|
|
"metadata": { "version": "1.8.0", "profiles": ["container", "host", "ai_operation"] },
|
|
"status": "Success",
|
|
"unmapped": { "latency_ms": 701 }
|
|
}
|
|
```
|
|
|
|
The shorthand log renders this as:
|
|
|
|
```text
|
|
OCSF API:INFERENCE [INFO] Success claude-haiku-4-5-20251001 via https://api.anthropic.com/v1 701ms [POST /v1/messages]
|
|
```
|
|
|
|
## Integration with External Tools
|
|
|
|
The JSONL file can be shipped to any tool that accepts OCSF-formatted data:
|
|
|
|
| Tool | Integration Path |
|
|
|---|---|
|
|
| Splunk | Use the [Splunk OCSF Add-on](https://splunkbase.splunk.com/app/6943) to ingest OCSF JSONL files. |
|
|
| Amazon Security Lake | OCSF is the native schema for Security Lake. |
|
|
| Elastic | Use Filebeat to ship JSONL files with the OCSF field mappings. |
|
|
| Custom pipelines | Parse the JSONL file with `jq`, Python, or any JSON-capable tool. |
|
|
|
|
Example with `jq` to extract all denied connections:
|
|
|
|
```shell
|
|
cat /var/log/openshell-ocsf.2026-04-01.log | \
|
|
jq -c 'select(.action == "Denied")'
|
|
```
|
|
|
|
## Relationship to Shorthand Logs
|
|
|
|
The shorthand format in `openshell.YYYY-MM-DD.log` and the JSON format in `openshell-ocsf.YYYY-MM-DD.log` are derived from the same OCSF events. The shorthand is a human-readable projection; the JSON is the complete record. Both are generated at the same time from the same event data.
|
|
|
|
The shorthand log is always active. The JSON export is opt-in through `ocsf_json_enabled`.
|
|
|
|
## Next Steps
|
|
|
|
- Learn how to [read the shorthand format](/observability/logging) for real-time monitoring.
|
|
- Refer to the [OCSF specification](https://schema.ocsf.io/) for the full schema reference.
|