Aggregate only specific accounts in workday source

Reposting since there were no correct solution that i got on my last post.

Hi All,

In Workday source want to aggregate only test users starting with the first name prefixed “Test” e.g. First Name : Test_paul

Can any one help with the steps that would be required to setup this filter in the workday source? Is there any connector attribute that needs to be set in the source? If yes, what is the attribute name?

I have already gone through the workday connector documentation because i was not able to find any examples in the connector documentation.

I have also gone through this post Filter in Workday Source - #5

Shivam Bahl

Hi Shivam,

I think you can use the filterString connector attribute described here IdentityNow Account Filtering during Account Aggregation

In my experience, this filterString works for almost every connector. Just a reminder, the connector still will collect all the data from Workday, but after get all the information, IDN will filter out the accounts that does not match the criteria.

Best regards

In case Felipe’s linked article ever changes, here are the details of the article.


Often there is a need to filter accounts on a source during an account aggregation process.

While some source connectors offer an ability to filter accounts natively, other source connectors may not, usually due to technical limitations - such as a lack of filtering abilities in APIs the connector is calling.

Luckily, IdentityNow does have an ability to filter accounts on its side, as part of the aggregation process. This is configured by setting a filterString property on the source configuration. Once configured, the aggregation process matches accounts as they are aggregated against the filter string. Accounts which match the filter string will be filtered. Accounts which do not match, will be sent to IdentityNow as normal.

The trade-offs are summarized here:


  • Ability to filter accounts during an account aggregation, despite connectivity.
  • Applies to all account aggregations and delta aggregations.


  • This offers no aggregation performance improvements. This still forces an aggregation to run in its entriety, and filters the accounts as they are iterated back to IdentityNow.If performance improvements are desired, we recommend leveraging filtering on the connector, where applicable. Not all source connectors have filtering abilities, as described above.

  • Excessive filtering can produce aggregation timeouts. This is because IdentityNow (in the cloud) never receives any accounts (due to filtering) and keeps waiting for a response from the virtual appliance. The more accounts which are filtered, the greater chance for an aggregation timeout.

Note: For dedicated connectors, filterString will not work on the following attribute names unless they are marked as Account Name in the source.

  • displayName
  • identity
  • instance

We don’t recommend changing the default Account Name of any dedicated connectors as it may have some unforeseen issues.


In order to configure this, you need to modify the source configurations to add in a filterString property. This can be done with a simple partial update to the source, using the REST APIs.

As an example, we may want to only bring in accounts which belong to employees. If employee was denoted by the “type” attribute on the account, we might configure our filterString to look like this:

Attribute Value
filterString ( type != “Employee” )

Different Filters for Different Objects - The filterString applies to all objects which are aggregated. If you want to get more specific to accounts or groups which are filtered, you can use account.filterString or group.filterString to denote specific filters for those particular objects. This document assumes filterString but you can also use the others as well.

Any account which matches this criteria will be filtered. The value you see is filter string syntax. The filter string reference guide follows this section. More complex values can be implemented, such as groupings, logical operators, etc.

The configuration of this is done via the IdentityNow Source Partial Update API. The details are as follows:


PATCH /v3/sources/{id}

HTTP Headers

Key Value Description
authorization Bearer {token} This is the JWT OAuth token.
content-type application/json-patch+json This is needed for PATCH operations.

Path Parameters

  • id - The ID of the source. e.g. 2c9180835d191a86015d27ac132112ae

Query Parameters

  • (Not applicable)

Request Body

JSON Patch syntax representing the change:

content-type: application/json-patch+json

    "op": "add",
    "path": "/connectorAttributes/filterString",
    "value": "( type != \"Employee\" )"


curl -X PATCH \ \
  -H 'Authorization: Bearer eyJ...BRM' \
  -H 'Content-Type: application/json-patch+json' \
  -H 'cache-control: no-cache' \
  -d '[
	"op": "add",
	"path": "/connectorAttributes/filterString",
	"value": "( type != \"Employee\" )"


Response Codes

HTTP Code HTTP Status Description
200 OK Returned if the request was successfully processed.
401 Unauthorized Returned if there is no authorization header, or if the JWT token is expired.
403 Forbidden Returned if the user you are running as, doesn’t have access to this end-point.
429 Too Many Requests Returned in response to too many requests in a given period of time - rate limited. The Retry-After header in the response includes how long to wait before trying again.
500 Internal Server Error Returned if there is an unexpected error.

Response Body

content-type: application/json

A modified source object.

Filter Reference

This is a filter reference to show how various account filters might be constructed. The expressions genreally follow the form:

{property} {operation} {value}

Here are additional rules for parsing correctly:

  • String literals should have double-quotes.
    • e.g. firstname == "Neil"
  • True / false values are treated as boolean literals
    • e.g. inactive != false
  • Digits are treated as numbers
    • e.g. age < 18
  • The string value ‘null’ (no quotes) is treated as null
    • e.g. name != null
  • Everything else is assumed to be the property name
    • e.g. email == contactAddress

Composite Filters

Filters can also be grouped and used together as composite filters:

Composite Filter Pattern Example
Grouping ( {expression} ) `!( type == “Employee” )
AND ( {expression} && {expression} ) ( type == "Employee" && location == "Austin" )
OR `( {expression}
NOT !( {expression} ) !( company == "SailPoint" )


Note: Any comparison operator can be prepended with an ‘i’ to signify a case-insensitive comparison (eg - i==, i!=, etc…).

Operation Pattern Example
Equals {property} == {value} firstname == "Neil"
Not Equals {property} != {value} lastname != "Smith"
Less Than {property} < {value} age < 18
Greater Than {property} > value age > 18
Less Than, Equals {property} <= {value} age <= 18
Greater Than, Equals {property} >= value age >= 18
Is Null {property}.isNull() email.isNull()
Not Null {property}.notNull() company.notNull()
Is Empty {property}.isEmpty() Groups.isEmpty()
Like, Exact {property} == {value} firstname == "Neil"
Like, Start {property}.startsWith( {value} ) lastname.startsWith( "Mc" )
Like, Start
(Ignoring Case) {property}.startsWithIgnoreCase( {value} ) lastname.startsWithIgnoreCase( "Mc" )
Like, End {property}.endsWith( {value} ) email.endsWith( "" )
Like, End
(Ignoring Case) {property}.endsWithIgnoreCase( {value} ) email.endsWithIgnoreCase( "" )
Like, Anywhere {property}.contains( {value} ) email.contains( "sail" )
Like, Anywhere (Ignoring Case) {property}.containsIgnoreCase( {value} ) email.containsIgnoreCase( "sail" )
Contains All {property}.containsAll({ {value}, {value}, {value}, ... }) Groups.containsAll( { "A", "B", "C" } )
Contains All
(Ignoring Case) {property}.containsAllIgnoreCase({ {value}, {value}, {value}, ... }) Groups.containsAllIgnoreCase( { "A", "B", "C" } )

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.