Splunk Search

Extracting Value from and Event

bill
Engager

Hello,

I am looking to add a particular value to an existing search of Okta data. The problem is I don't know how to extract the value which is on the same level as other values. The value I am looking for is "Workflows Administrator". The existing search is:

index=okta "debugContext.debugData.privilegeGranted"="*" | rename actor.displayName as "Actor", targetUserDisplayName as "Target Name", targetUserAlternateId as "Target ID", description as "Action", debugContext.debugData.privilegeGranted as "Role(s)" | eval Time = strftime(_time, "%Y-%d-%m %H:%M:%S") | fields - _time | table Time, Actor, Action, "Target Name", "Target ID", Action, "Role(s)"

and sample data is

{ [-]
   actor: { [+]
   }
   authenticationContext: { [+]
   }
   client: { [+]
   }
   debugContext: { [-]
     debugData: { [-]
       privilegeGranted: Application administrator (all), User administrator (all), Help Desk administrator (all)
     }
   }
   device: null
   displayMessage: Grant user privilege
   eventType: user.account.privilege.grant
   legacyEventType: core.user.admin_privilege.granted
   outcome: { [-]
     reason: null
     result: SUCCESS
   }
   published: 2025-05-08T19:30:54.612Z
   request: { [-]
     ipChain: [ [+]
     ]
   }
   securityContext: { [-]
     asNumber: null
     asOrg: null
     domain: null
     isProxy: null
     isp: null
   }
   severity: INFO
   target: [ [-]
     { [-]
       alternateId: jdoe@company.com
       detailEntry: null
       displayName: John Doe
       id: 00umfyv9jwzVvafI71t7
       type: User
     }
     { [-]
       alternateId: unknown
       detailEntry: null
       displayName: Custom role binding added
       id: CUSTOM_ROLE_BINDING_ADDED
       type: CUSTOM_ROLE_BINDING_ADDED
     }
     { [-]
       alternateId: /api/v1/iam/roles/WORKFLOWS_ADMIN
       detailEntry: null
       displayName: Workflows Administrator
       id: WORKFLOWS_ADMIN
       type: CUSTOM_ROLE
     }
     { [-]
       alternateId: /api/v1/iam/resource-sets/WORKFLOWS_IAM_POLICY
       detailEntry: null
       displayName: Workflows Resource Set
       id: WORKFLOWS_IAM_POLICY
       type: RESOURCE_SET
     }
   ]
   transaction: { [+]
   }
   uuid: 2c42-11f0-a9fe
   version: 0
}

 Any help is appreciated. Thank you!

Labels (1)
0 Karma
1 Solution

yuanliu
SplunkTrust
SplunkTrust

Before anything, let me first say that when you post JSON event sample, always use "Show raw text" before copying.  This helps others help you.  Secondly, as @bowesmana says, it is really unclear what you are asking.  You already know the value "Workflows Administrator".  Do you mean to search for this value and display other related key-value pairs?  Or do you mean there are other possible values from the 3rd array element of target[] that you want to know how to reach that correct array element?

If former, you need to specify which key-value pairs in that element are of interest.  If latter, there are many ways, including a method that does not do "extracting" because Splunk by default has done that for you.  But before doing that, you need to use Splunk's flattened-structure notation, not invented names like targetUserDisplayName. (Splunk's notation is target{}.displayName for this one.)

Anyway, assuming the latter, @bowesmana already showed you several ways.  Here I first present a formulae approach to reach every JSON array node in SPL: spath + mvexpand.  But before I show any code, you need to perform the most critical task:  to understand how that element is different from other elements in the same array, all of them having a key displayName.  In order to make this determination, you need to carefully study the data.  The differentiating factor among those elements is the JSON key type in that array.  So, you would be looking for the element whose type is CUSTOM_ROLE.

index=okta "debugContext.debugData.privilegeGranted"="*"
| fields - target{}.*
| spath path=target{}
| mvexpand target{}
| spath input=target{}
| where type == "CUSTOM_ROLE"
| rename actor.displayName as "Actor", displayName as "Target Name",
  alternateId as "Target ID", description as "Action",
  debugContext.debugData.privilegeGranted as "Role(s)"
| table Time, Actor, Action, "Target Name", "Target ID", Action, "Role(s)"

With this approach, you can handle any JSON array.

If you don't want to (re)extract everything in the array - there are occasions when mvexpand can be too expensive, here is a quirky method that can do the same thing: capture the value of target{}.displayName and target{}.alternateId corresponding to target{}.type of CUSTOM_ROLE.

index=okta "debugContext.debugData.privilegeGranted"="*"
| eval type_index = mvfind('target{}.type', "CUSTOM_ROLE")
| eval "Target Name" = mvindex('target{}.displayName', type_index)
| eval "Target ID" = mvindex('target{}.alternateId', type_index)
| rename actor.displayName as "Actor", description as "Action",
  debugContext.debugData.privilegeGranted as "Role(s)"
| table Time, Actor, Action, "Target Name", "Target ID", Action, "Role(s)"

View solution in original post

bill
Engager

Thank you @livehybrid @yuanliu and @bowesmana! This is my first real post here, so I appreciate you bearing with me as I may not have provided a complete picture.

@yuanliu 's answer provided a clear example of how I can use mvfind and mvindex to extract the correct data. The only thing I had to add was a \b word boundary to the mvfind regex, so it wouldn't hit the earlier partial match. Here is the query:

index=okta "debugContext.debugData.privilegeGranted"="*"
| eval type_index = mvfind('target{}.type', "CUSTOM_ROLE\b")
| eval "Target Name" = mvindex('target{}.displayName', type_index)
| eval "Target ID" = mvindex('target{}.alternateId', type_index)
| rename actor.displayName as "Actor", description as "Action",
  debugContext.debugData.privilegeGranted as "Role(s)"
| table Time, Actor, Action, "Target Name", "Target ID", Action, "Role(s)"
0 Karma

livehybrid
Super Champion

Hi @bill 

If you're looking to see if the user is a Workflows Administrator then the following should work:

| eval isAdmin=IF(typeof(mvfind('target{}.displayName', "Workflows Administrator"))=="Number","Yes","No")

🌟 Did this answer help you? If so, please consider:

  • Adding karma to show it was useful
  • Marking it as the solution if it resolved your issue
  • Commenting if you need any clarification

Your feedback encourages the volunteers in this community to continue contributing

yuanliu
SplunkTrust
SplunkTrust

Before anything, let me first say that when you post JSON event sample, always use "Show raw text" before copying.  This helps others help you.  Secondly, as @bowesmana says, it is really unclear what you are asking.  You already know the value "Workflows Administrator".  Do you mean to search for this value and display other related key-value pairs?  Or do you mean there are other possible values from the 3rd array element of target[] that you want to know how to reach that correct array element?

If former, you need to specify which key-value pairs in that element are of interest.  If latter, there are many ways, including a method that does not do "extracting" because Splunk by default has done that for you.  But before doing that, you need to use Splunk's flattened-structure notation, not invented names like targetUserDisplayName. (Splunk's notation is target{}.displayName for this one.)

Anyway, assuming the latter, @bowesmana already showed you several ways.  Here I first present a formulae approach to reach every JSON array node in SPL: spath + mvexpand.  But before I show any code, you need to perform the most critical task:  to understand how that element is different from other elements in the same array, all of them having a key displayName.  In order to make this determination, you need to carefully study the data.  The differentiating factor among those elements is the JSON key type in that array.  So, you would be looking for the element whose type is CUSTOM_ROLE.

index=okta "debugContext.debugData.privilegeGranted"="*"
| fields - target{}.*
| spath path=target{}
| mvexpand target{}
| spath input=target{}
| where type == "CUSTOM_ROLE"
| rename actor.displayName as "Actor", displayName as "Target Name",
  alternateId as "Target ID", description as "Action",
  debugContext.debugData.privilegeGranted as "Role(s)"
| table Time, Actor, Action, "Target Name", "Target ID", Action, "Role(s)"

With this approach, you can handle any JSON array.

If you don't want to (re)extract everything in the array - there are occasions when mvexpand can be too expensive, here is a quirky method that can do the same thing: capture the value of target{}.displayName and target{}.alternateId corresponding to target{}.type of CUSTOM_ROLE.

index=okta "debugContext.debugData.privilegeGranted"="*"
| eval type_index = mvfind('target{}.type', "CUSTOM_ROLE")
| eval "Target Name" = mvindex('target{}.displayName', type_index)
| eval "Target ID" = mvindex('target{}.alternateId', type_index)
| rename actor.displayName as "Actor", description as "Action",
  debugContext.debugData.privilegeGranted as "Role(s)"
| table Time, Actor, Action, "Target Name", "Target ID", Action, "Role(s)"

bowesmana
SplunkTrust
SplunkTrust

Not totally sure I understand, but if you're trying to get the 3rd array element of target which corresponds to the Workflow admin, then this little snippet will get the JSON for that array element

| eval workflow_admin=spath(_raw, "target{}")
| eval workflow_admin=mvmap(workflow_admin, if(tostring(spath('workflow_admin', "displayName"))="Workflows Administrator", 'workflow_admin', null()))

There are probably a number of ways of getting at the JSON, but this works.

Here's another way

| eval workflow_admin=json_array_to_mv(json_extract(_raw, "target{}"))
| eval workflow_admin=mvmap(workflow_admin, if(tostring(spath('workflow_admin', "displayName"))="Workflows Administrator", 'workflow_admin', null()))

Once you have workflow_admin, you can manipulate/extract the fields as needed 

Get Updates on the Splunk Community!

.conf25 Registration is OPEN!

Ready. Set. Splunk! Your favorite Splunk user event is back and better than ever. Get ready for more technical ...

Detecting Cross-Channel Fraud with Splunk

This article is the final installment in our three-part series exploring fraud detection techniques using ...

Splunk at Cisco Live 2025: Learning, Innovation, and a Little Bit of Mr. Brightside

Pack your bags (and maybe your dancing shoes)—Cisco Live is heading to San Diego, June 8–12, 2025, and Splunk ...