GJSON Paths

GJSON is Monad’s path syntax for UI-based transforms. When you can’t use jq (trial accounts or simpler needs), GJSON provides powerful field access for native transforms.

Why GJSON?

  • UI transforms use GJSON paths to specify field locations

  • Trial accounts have limited jq access - GJSON works

  • Simpler syntax for basic field operations

  • Performance - compiled path evaluation

Basic Syntax

Dot Notation

user.name           → "jdoe"
endpoint.ip         → "10.50.1.100"
ise.policy_set      → "Wired_802.1X_Closed"

Nested Access

// Input
{
  "user": {
    "identity": {
      "name": "jdoe",
      "domain": "CHLA"
    }
  }
}
user.identity.name    → "jdoe"
user.identity.domain  → "CHLA"

Array Access

By Index

// Input
{
  "endpoints": [
    {"ip": "10.0.0.1", "status": "active"},
    {"ip": "10.0.0.2", "status": "inactive"}
  ]
}
endpoints.0.ip        → "10.0.0.1"
endpoints.1.status    → "inactive"
endpoints.#           → 2 (array length)

By Query

# First active endpoint
endpoints.#(status=="active").ip  → "10.0.0.1"

# All active endpoints
endpoints.#(status=="active")#.ip → ["10.0.0.1"]

Query Operators

Operator Meaning Example

==

Equals

#(status=="active")

!=

Not equals

#(status!="inactive")

<

Less than

#(port<1024)

Less than or equal

#(severity⇐3)

>

Greater than

#(bytes>1000000)

>=

Greater than or equal

#(count>=10)

%

Pattern match (like)

#(name%"admin*")

!%

Not pattern match

#(name!%"test*")

Wildcards

# All values at depth 1
*.name                → All name fields

# Recursive search
..ip                  → All ip fields at any depth

ISE Log Paths

RADIUS Authentication

{
  "timestamp": "2026-03-15T14:30:45Z",
  "severity": "high",
  "event_type": "auth_failure",
  "user": {
    "name": "jdoe",
    "domain": "CHLA"
  },
  "endpoint": {
    "mac": "AA:BB:CC:DD:EE:FF",
    "ip": "10.50.10.100"
  },
  "ise": {
    "policy_set": "Wired_802.1X_Closed",
    "authorization_profile": "DENY_ACCESS",
    "auth_result": "FAILED",
    "failure_reason": "Certificate validation failed"
  }
}

Paths:

Path Returns

severity

"high"

event_type

"auth_failure"

user.name

"jdoe"

endpoint.mac

"AA:BB:CC:DD:EE:FF"

ise.auth_result

"FAILED"

ise.failure_reason

"Certificate validation failed"

TACACS Command Accounting

{
  "timestamp": "2026-03-15T14:35:00Z",
  "event_type": "command_accounting",
  "user": {
    "name": "admin",
    "privilege_level": 15
  },
  "device": {
    "hostname": "switch-core-01",
    "ip": "10.50.1.10"
  },
  "tacacs": {
    "command": "show running-config",
    "arguments": [],
    "elapsed_time": 2.5
  }
}

Paths:

Path Returns

user.privilege_level

15

device.hostname

"switch-core-01"

tacacs.command

"show running-config"

FTD Firewall Paths

{
  "timestamp": "2026-03-15T14:40:00Z",
  "action": "deny",
  "src": {
    "ip": "192.168.1.50",
    "port": 45678,
    "zone": "inside"
  },
  "dst": {
    "ip": "8.8.8.8",
    "port": 443,
    "zone": "outside"
  },
  "protocol": "tcp",
  "rule": {
    "name": "Block_Malicious",
    "id": "rule-123"
  },
  "threat": {
    "signature": "ET TROJAN C2 Beacon",
    "severity": "critical"
  }
}

Paths:

Path Returns

action

"deny"

src.ip

"192.168.1.50"

dst.port

443

rule.name

"Block_Malicious"

threat.signature

"ET TROJAN C2 Beacon"

threat.severity

"critical"

Using GJSON in UI Transforms

drop_record_where_value_eq

Field Value

Key

severity

Value

info

Uses GJSON path severity to access the field.

rename_key

Field Value

Old Key

src.ip

New Key

source.ip

create_key_value_if_key_value

Field Value

Condition Key

ise.auth_result

Condition Value

FAILED

New Key

mitre_technique

New Value

T1078

UI Transform Workflow (CHLA Example)

Step 1: Filter Info Logs

Transform Type

drop_record_where_value_eq

Key

severity

Value

info

Impact: Drops ~50% of ISE logs

Step 2: Drop Successful Auths

Transform Type

drop_record_where_value_eq

Key

ise.auth_result

Value

PASSED

Impact: Drops ~60% of remaining RADIUS logs

Step 3: Tag for Sentinel

Transform Type

add

Key

destination

Value

sentinel

Step 4: Add MITRE Tag

Transform Type

create_key_value_if_key_value

Condition Key

event_type

Condition Value

auth_failure

New Key

mitre_technique

New Value

T1078

Step 5: Normalize Field Names

Transform Type

rename_key

Old Key

ise.auth_result

New Key

authentication.status

GJSON vs jq

Feature GJSON jq

Availability

UI transforms, all accounts

jq transform, may be limited

Complexity

Field access, simple queries

Full JSON transformation

Conditionals

Query operators in paths

if-then-else, case

Learning Curve

Lower

Higher

Use Case

Simple field operations

Complex routing logic

When to use GJSON: - Simple field renames, drops, conditionals - Trial account limitations - Quick transforms without jq

When to use jq: - Complex routing with multiple conditions - OCSF normalization - MITRE tagging with lookup tables

Debugging Paths

Test in Pipeline Logs

  1. Create test pipeline with HTTP input

  2. Send sample JSON

  3. View logs to see parsed fields

  4. Verify paths work as expected

Test with jq

# GJSON path: user.identity.name
# Equivalent jq: .user.identity.name

echo '{"user":{"identity":{"name":"jdoe"}}}' | jq '.user.identity.name'

Common Issues

Issue Symptom Fix

Missing field

Transform doesn’t apply

Verify path with sample log

Array without index

Wrong value returned

Use .0 for first or #(query) for search

Case sensitivity

No match

GJSON is case-sensitive

Key Takeaways

  1. GJSON for UI transforms - Specify field locations

  2. Dot notation for nesting - user.identity.name

  3. Array access with index or query - .0 or #(status=="active")

  4. Query operators - ==, !=, <, >, %

  5. Use jq for complex logic - GJSON for simple operations

  6. Test paths with sample data - Before deploying

Next Module

Routing Patterns - CHLA-specific patterns for Sentinel/S3 routing.