I was running into this same problem recently... and while I feel like this should be easier, it got the job done for me, to get all imports of all roles. I'll walk you through the development (I'm on 7.2.9.1), and then give one that you should be able to just drop in and use yourself...
Let's call our current search string S
Initially set S to the following:
| rest /services/authorization/roles splunk_server=local f=imported_roles f=title
| fields title imported_roles | rename imported_roles -> imported
| eval delta=coalesce(mvcount(imported),0)
| fillnull value=NIL imported
This sets up our base state, where title is the name of each role, imported is the set of roles that we currently know each role imports, NIL if a role imports no roles (this is important so we keep these roles as we iterate...), and delta is the number of imported roles that we previously didn't know about.
Now we iterate:
First we check our ending condition:
S | stats sum(delta)
If the number returned here is 0, then we are finished and the current state of S will give us all roles with all imports for our current installation (see below). If this sum is >0 we iterate and update the value of S as follows:
S | fields - delta
| mvexpand imported
| appendpipe [ where imported!="NIL" | eval imported1=imported,imported=title,title=null()]
| eventstats values(imported1) as imported1 by imported
| stats values(imported*) as imported* by title
| eval imported1=mvdedup(mvappend(imported,imported1)),delta=mvcount(imported1)-mvcount(imported),imported=imported1
| fields - imported1
What we do here is we get rid of the delta from the previous iteration, we expand our list to be one pair of role -> imported role each, we duplicate our results to also have the full set of imported role -> next imported role (for those that have an imported role), we use eventstats to gather up the next imported roles for each imported role, and we use stats to gather up for each role, all the known imported roles, and the next imported roles. Now that we're back to one result, we merge our found next imports into our known imports, and calculate the number that we didd not know about previously.
Repeat the loop!
At the end, you could clean up the now all 0s delta field by updating S to be:
S | fields - delta
but otherwise you now have a lookup of role -> all other roles, and can use standard search / where terms on it...
So a fun aspect about this, each iteration is idempotent as soon as we know all imported roles for each role, and each loop we gather information about double the number of layers of imports deep... (assuming I'm correctly remembering some of my algorithmic principles...)
So, getting rid of the delta tracking, and running this together... this search should find the full import stack for all roles in your environment, provided that no role has more than 256 layers of imported roles deep... (e.g. a imports b which imports c and so on for more than 256 times...) this search will get you the full mapping of role -> all imported roles)... and if you need up to 512, copy and tack on to the end another | mvexpand ... fields line:
| rest /services/authorization/roles splunk_server=local f=imported_roles f=title | fields title imported_roles | rename imported_roles -> imported | fillnull value=NIL imported
| mvexpand imported | appendpipe [where imported!="NIL" | eval imported1=imported,imported=title,title=null()] | eventstats values(imported1) as imported1 by imported | stats values(imported*) as imported* by title | eval imported=mvdedup(mvappend(imported,imported1)) | fields - imported1
| mvexpand imported | appendpipe [where imported!="NIL" | eval imported1=imported,imported=title,title=null()] | eventstats values(imported1) as imported1 by imported | stats values(imported*) as imported* by title | eval imported=mvdedup(mvappend(imported,imported1)) | fields - imported1
| mvexpand imported | appendpipe [where imported!="NIL" | eval imported1=imported,imported=title,title=null()] | eventstats values(imported1) as imported1 by imported | stats values(imported*) as imported* by title | eval imported=mvdedup(mvappend(imported,imported1)) | fields - imported1
| mvexpand imported | appendpipe [where imported!="NIL" | eval imported1=imported,imported=title,title=null()] | eventstats values(imported1) as imported1 by imported | stats values(imported*) as imported* by title | eval imported=mvdedup(mvappend(imported,imported1)) | fields - imported1
| mvexpand imported | appendpipe [where imported!="NIL" | eval imported1=imported,imported=title,title=null()] | eventstats values(imported1) as imported1 by imported | stats values(imported*) as imported* by title | eval imported=mvdedup(mvappend(imported,imported1)) | fields - imported1
| mvexpand imported | appendpipe [where imported!="NIL" | eval imported1=imported,imported=title,title=null()] | eventstats values(imported1) as imported1 by imported | stats values(imported*) as imported* by title | eval imported=mvdedup(mvappend(imported,imported1)) | fields - imported1
| mvexpand imported | appendpipe [where imported!="NIL" | eval imported1=imported,imported=title,title=null()] | eventstats values(imported1) as imported1 by imported | stats values(imported*) as imported* by title | eval imported=mvdedup(mvappend(imported,imported1)) | fields - imported1
| mvexpand imported | appendpipe [where imported!="NIL" | eval imported1=imported,imported=title,title=null()] | eventstats values(imported1) as imported1 by imported | stats values(imported*) as imported* by title | eval imported=mvdedup(mvappend(imported,imported1)) | fields - imported1
Hopefully this helps you too?
... View more