7.3 KiB
Runtime Evidence Schema Reference
Overview
Runtime evidence is serialized as NDJSON (Newline-Delimited JSON), with one event per line. The schema ensures deterministic output for reproducible evidence chains.
Schema Location
- JSON Schema:
docs/schemas/runtime-evidence-v1.json - C# Models:
src/Signals/__Libraries/StellaOps.Signals.Ebpf/Schema/
Common Fields
Every evidence record includes these base fields:
| Field | Type | Required | Description |
|---|---|---|---|
ts_ns |
integer | Yes | Nanoseconds since system boot |
src |
string | Yes | Event source identifier |
pid |
integer | Yes | Process ID |
tid |
integer | No | Thread ID (if available) |
cgroup_id |
integer | Yes | Kernel cgroup ID |
container_id |
string | No | Container ID (enriched) |
image_digest |
string | No | Image digest (enriched) |
comm |
string | No | Process command name (max 16 chars) |
event |
object | Yes | Type-specific event data |
Event Types
File Access (file_access)
Captured from sys_enter_openat tracepoint.
{
"ts_ns": 1234567890123456789,
"src": "tracepoint:syscalls:sys_enter_openat",
"pid": 1234,
"cgroup_id": 5678,
"container_id": "abc123def456",
"image_digest": "sha256:...",
"comm": "nginx",
"event": {
"type": "file_access",
"path": "/etc/nginx/nginx.conf",
"flags": 0,
"mode": 0,
"access": "read"
}
}
| Field | Type | Description |
|---|---|---|
path |
string | File path (max 256 chars) |
flags |
integer | Open flags (O_RDONLY, O_WRONLY, etc.) |
mode |
integer | File mode (for creation) |
access |
string | Derived access type: read, write, read_write |
Process Execution (process_exec)
Captured from sched_process_exec tracepoint.
{
"ts_ns": 1234567890123456789,
"src": "tracepoint:sched:sched_process_exec",
"pid": 1234,
"cgroup_id": 5678,
"container_id": "abc123def456",
"image_digest": "sha256:...",
"comm": "python3",
"event": {
"type": "process_exec",
"filename": "/usr/bin/python3",
"ppid": 1000,
"argv": ["python3", "script.py", "--config", "/etc/app.conf"]
}
}
| Field | Type | Description |
|---|---|---|
filename |
string | Executed binary path |
ppid |
integer | Parent process ID |
argv |
string[] | Command arguments (limited to first 4) |
TCP State Change (tcp_state)
Captured from inet_sock_set_state tracepoint.
{
"ts_ns": 1234567890123456789,
"src": "tracepoint:sock:inet_sock_set_state",
"pid": 1234,
"cgroup_id": 5678,
"container_id": "abc123def456",
"image_digest": "sha256:...",
"comm": "curl",
"event": {
"type": "tcp_state",
"family": "ipv4",
"old_state": "SYN_SENT",
"new_state": "ESTABLISHED",
"src_addr": "10.0.0.5",
"src_port": 45678,
"dst_addr": "93.184.216.34",
"dst_port": 443
}
}
| Field | Type | Description |
|---|---|---|
family |
string | Address family: ipv4 or ipv6 |
old_state |
string | Previous TCP state |
new_state |
string | New TCP state |
src_addr |
string | Source IP address |
src_port |
integer | Source port |
dst_addr |
string | Destination IP address |
dst_port |
integer | Destination port |
TCP States: CLOSED, LISTEN, SYN_SENT, SYN_RECV, ESTABLISHED, FIN_WAIT1, FIN_WAIT2, CLOSE_WAIT, CLOSING, LAST_ACK, TIME_WAIT
Network Operation (network_op)
Captured from libc connect/accept uprobes.
{
"ts_ns": 1234567890123456789,
"src": "uprobe:libc.so.6:connect",
"pid": 1234,
"cgroup_id": 5678,
"container_id": "abc123def456",
"image_digest": "sha256:...",
"comm": "app",
"event": {
"type": "network_op",
"operation": "connect",
"family": "ipv4",
"addr": "10.0.1.100",
"port": 5432,
"result": 0
}
}
| Field | Type | Description |
|---|---|---|
operation |
string | connect or accept |
family |
string | Address family |
addr |
string | Remote address |
port |
integer | Remote port |
result |
integer | Return value (0 = success) |
SSL Operation (ssl_op)
Captured from OpenSSL SSL_read/SSL_write uprobes.
{
"ts_ns": 1234567890123456789,
"src": "uprobe:libssl.so.3:SSL_write",
"pid": 1234,
"cgroup_id": 5678,
"container_id": "abc123def456",
"image_digest": "sha256:...",
"comm": "nginx",
"event": {
"type": "ssl_op",
"operation": "write",
"requested_bytes": 1024,
"actual_bytes": 1024,
"ssl_ptr": 140234567890
}
}
| Field | Type | Description |
|---|---|---|
operation |
string | read or write |
requested_bytes |
integer | Bytes requested |
actual_bytes |
integer | Bytes actually transferred |
ssl_ptr |
integer | SSL context pointer (for correlation) |
Symbol Call (symbol_call)
Captured from function uprobes.
{
"ts_ns": 1234567890123456789,
"src": "uprobe:app:vulnerable_parse_json",
"pid": 1234,
"cgroup_id": 5678,
"container_id": "abc123def456",
"image_digest": "sha256:...",
"comm": "app",
"event": {
"type": "symbol_call",
"symbol": "vulnerable_parse_json",
"library": "/usr/lib/libapp.so",
"offset": 4096,
"address": 140234571986
}
}
| Field | Type | Description |
|---|---|---|
symbol |
string | Function symbol name |
library |
string | Library/binary path |
offset |
integer | Offset within library |
address |
integer | Runtime address |
Determinism Requirements
For byte-identical output across runs:
- Field Ordering: All JSON keys sorted alphabetically
- Number Format: Integers as-is, no floating point variance
- String Encoding: UTF-8 with NFC normalization
- Null Handling: Null fields omitted (not
"field": null) - Whitespace: No trailing whitespace, single newline per record
Chunk Metadata
Each evidence chunk includes metadata in its DSSE attestation:
{
"predicateType": "stella.ops/runtime-evidence@v1",
"predicate": {
"chunk_id": "sha256:abc123...",
"chunk_sequence": 42,
"previous_chunk_id": "sha256:def456...",
"event_count": 150000,
"time_range": {
"start": "2026-01-27T10:00:00Z",
"end": "2026-01-27T11:00:00Z"
},
"collector_version": "1.0.0",
"kernel_version": "5.15.0-generic",
"compression": null,
"host_id": "node-01.cluster.local",
"container_ids": ["abc123", "def456"]
}
}
Validation
Evidence can be validated against the JSON Schema:
# Validate single file
stella evidence validate evidence-chunk-001.ndjson
# Validate and show statistics
stella evidence validate --stats evidence-chunk-001.ndjson
Migration from v0 Schemas
If using earlier per-language schemas, migrate to v1 unified schema:
- Update field names to snake_case
- Wrap type-specific fields in
eventobject - Add
srcfield with probe identifier - Ensure
ts_nsuses nanoseconds since boot
Example migration:
// v0 (old)
{"timestamp": 1234567890, "type": "file", "path": "/etc/config"}
// v1 (new)
{"ts_ns": 1234567890000000000, "src": "tracepoint:syscalls:sys_enter_openat", "pid": 1234, "cgroup_id": 5678, "event": {"type": "file_access", "path": "/etc/config", "flags": 0, "mode": 0, "access": "read"}}