Axiom Query Language

Last modified 26 May 2022 16:56 +02:00
Since 4.3
This functionality is available since version 4.3.

Axiom Query Language is a language used to query objects in midPoint repository. It is a universal language used to search for objects in the repository, filter objects, set up object references and so on. It is used in all the places where we need to look for an object.

The language closely follows midPoint data model. Names of the properties, attributes and all the data items are directly taken from midPoint data model.

This description is an attempt to provide introduction to the Axiom Query Language for the users. Some details are omitted, and there are some simplifications for clarity. Exact specification of the query language will be provided in Axiom section of this site.

The Basics

The query language is designed to allow specification of a complex queries. Yet the basic structure of the language is relative simple and easy to understand.

The query is a combination of a filter with additional parts such as paging and sorting. It is the filter part that attracts most attention.

Simple filter usually take the usual form of item filterName value triple, where:


Item Path - specifies on which item filter matching should be applied


Name of filter to be used


Value literal or Item Path which should be matched according filter specification. String needs to be enclosed in quotes (') or double-qoutes (")

Some examples of valid filters are:

  • fullName = "John Doe"

  • givenName startsWith "J"

  • activation/effectiveStatus = "enabled"

Item Path

The item on which data are filtered is specified by item path. In its simplest form it is a name of object property, or names of items and containers separated by slashes. Such as:

  • fullName

  • activation/administrativeStatus

  • attributes/uid

Filter Name

Item path is followed by filter name or its alias, which specifies which filtering condition should be used.

Following tables summarizes common property filters:

Comparison filters

Name Alias Description



Matches if any item is equal to value

not equal


Matches if item is different than value



Matches if item is smaller than value



Matches if item is smaller or equal to the value



Matches if item is greater than value



Matches if item is greater or equal to value

Examples of comparison filters on users
familyName = "Doe"

equals filter - All users with familyName Doe

name != "Administrator"

not equals filter - Everyone except administrator

activation/validTo < "2022-01-01"

less filter - All users which will not be valid after 2021

Comparison filters also supports item path on right side of filter. For example activation/validFrom > activation/validTo should return all objects with incorrectly set activations (activation start is after activation end).

String filters

Name Value Description


Matches if item starts with specified string.


Matches string property if it contains specified substring.


Matches string property if it ends with specified substring.


Performs full text search. Item path must be dot (.)


Value is usually a string literal, enclosed in double quotes. However, value may take various forms. For example, it may be a path of another item, e.g. in case when the query compares two items. The value may be also quite complex. The exact form of the value part of the filter depends on the operator.

Numeric values and QNames does not need double quotes.

Logical Filters

Logical filters are used to combine several sub-filters into one filter or to negate filter.

givenName = "John" and familyName = "Doe"

There is a usual set of logic operators:

Table 1. Logic Operators
Operator Example Description


givenName = "John" and familyName = "Doe"

All subfilters must be true.


givenName = "Bill" or nickName = "Bill"

Any of the subfilters is true.


givenName not startsWith "J" givenName != "John"

Logical negation. Not prefixes filter name (as seen in example).

You can use round brackets to group logical statements into more readable form.

familyName = "Doe" and (givenName = "John" or givenName ="Bill")

Advanced filters

matches filter

matches filter operates on the container or structured value and specifies conditions that must be met by a single container value. It is in form of itemPath matches (subfilter), where subfilter (and item paths) are relative to the container, for example assignment/validTo < "2022-01-01" is same as assignment matches (validTo < "2022-01-01").

The subfilter is any supported filter, where paths are relative to container and allows us to specify multiple conditions (joined using Logical Filters), which must be met by container value.

Example matches filter:

activation matches (
  validFrom > "2022-01-01"
   and validTo <"2023-01-01"

For filters matching multiple properties of multi value containers (such as assignment). It is important to consider if we want to match a container where one container value meets all criteria, or these criteria could be met by multiple different container values.

If these multiple criteria must be met by one container value you must use matches.

The filter assignment/validFrom > "2022-01-01" and assignment/validTo <"2023-01-01" is different from assignment matches (validFrom > "2022-01-01" and validTo <"2023-01-01"). First will matches user who has one assignment starting after 2022 and possible other assignment ending by 2023. The second filter with match user who has an assignment which starts in 2022 and expires before 2023.

Reference Filters

Reference filters allows to match on references themselves using matches or on properties of referenced objects using dereferencing

You can also perform inverse search using referencedBy to search for object by properties of it’s referencer (eg. search roles by properties of its members).

Reference matches filter

Reference itself is structured value, which contains target oid, target type and relationship type.

You can use matches filter with nested subfilters to target these properties of object reference:


Exact match of target oid (UUID as string). Example: assignment/targetRef matches (oid = efaf89f4-77e9-460b-abc2-0fbfd60d9167)


Matches any reference with specified relation (QName). Example: roleMembershipRef matches (relation = manager)


Matches any reference with specified target type (QName). Example: roleMembershipRef matches (targetType = OrgType)

It is possible to match on any combination of these three properties of reference, but only equals and and filter are supported.

roleMembershipRef matches (
  oid = "bc3f7659-e8d8-4f56-a647-2a352eead720"
  and relation = manager
  and targetType = OrgType


Dereferencing allows to write filter condition which is executed on referenced object. Dereferencing is done using @ special character in item path after reference, item path assignment/targetRef/@ points to object referenced by targetRef instead of targetRef itself. This allows you to continue path with properties of referenced objects such as assignment/targetRef/@/name - which means name of assigned object.

For example this enables us to search for users with assigned role by role name instead of oid (but it is executed bit slower, since we need to dereference objects). assignment/targetRef/@/name = "Superuser" - matches any user who is directly assigned role of super user.

To match also users, who are indirectly assigned role, you should use roleMembershipRef instead of assignment/targetRef.
If you need to match referenced object on multiple properties you should use matches filter.

Dereferencing inside reference matches filter

This feature is currently supported in midPoint 4.6 Postgres native repository only

If user wants to match on properties of reference itself and also on properties of it’s target it is possible now, using dereferencing inside reference matches filter.

In order to match on target you can use dereferencing and matching: @ matches (…​).

Find all users, which are managers for roles with Business Role archetype
assignment/targetRef matches ( (1)
  targetType = RoleType (2)
  and relation = manager (3)
  and @ matches ( (4)
     archetypeRef/@/name = "Business Role" (5)
1 We are matching references in assignment/targetRef
2 Type of referenced target should be RoleType
3 Users relation to assigned role is manager
4 We dereference target and match on its properties
5 Name of role archetype should be Business Role. This is done by dereferencing archetypeRef using @ in item path.

referencedBy Filter

Filter is currently supported in midPoint 4.6 Postgres native repository only

referencedBy filter allows you to find object based on properties on objects, which reference it. Since object as whole is referenced the item path

In order to use referencedBy filter you must also specify type of objects, which references it, and path of object reference, which is used for reference (e.g assignment/targetRef or inducement/targetRef)

The short Axiom syntax is:

Find all roles which are assigned to Administrator
. referencedBy ( (1)
  @type = UserType (2)
  and @path = assignment/targetRef (3)
  and name = "Administrator" (4)
1 . referencedBy filter name
2 @type - required, special filter property which specified type of objects which should be considered in evaluation of filter. In this case we are interested in users.
3 @path - required, special filter property which specifies which Object reference should be used in filter, in this case we are interested in directly assigned roles (assignment/targetRef)
4 Filter which referencing object must match, in this case the name of referencing object must be Administrator.

ownedBy Filter

Filter is currently supported in midPoint 4.6 Postgres native repository only

ownedBy filter allows for matching indexed containers based on properties of their parent (owning object or container).

The syntax is similar to referencedBy. ownedBy filter can only be applied on self path (.). The properties of ownedBy filter are:


(Required) Type of parent / owner


(Optional) name / location of container inside parent


(Optional) filter, to which parent needs to conform, filter is explicit element in XML/YAML/JSON. In Axiom any filter which is not special property of ownedBy is automaticly nested in filter.

Using searchContainers, find all inducements
. ownedBy ( @type = AbstractRoleType and @path = inducement)

Organization Filters

Organization filters are used to filter objects based on their organization membership. These filters operates on object as a whole, so item path must be .

Name Value Description



Matches if object is part of organization unit or its subunits.



Matches if object is organization root. Filter does not have value.

. inOrg "00000000-1eam-0000-0000-111111111111"

All object which are members of specified organization

. isRoot

All roles and organization units which are organization tree roots.

Other filters






Matches if item exists (has any value). Filter does not have value.


object type

Matches if object is of specified type. Usually used in combination with and filter for dereferenced objects, or it is needed to match on property defined in more specific type.

Using Axiom Query Language in midPoint

Using Axiom Query in GUI

Axiom Query is still experimental feature, so it needs to be explicitly enabled in GUI.

  1. In Admin GUI navigate to Configuration → System → Admin GUI

  2. Click Show Empty fields in Admin GUI Configuration section

  3. Select True in Enable experimental features

  4. Save configuration changes, logout and login in order to changes to be applied.

After reload, you could click on down arrow in search fields to select Axiom query as one of the search options.

Using Axiom Query in XML

Axiom Query filters are usable in any configuration place, normal XML filters would be used. Axiom Query filter is wrapped inside <text> element inside <filter> element.

Example XML
 <text>roleMembershipRef matches (relation = manager)</text>
Example YAML
  text: roleMembershipRef matches (relation = manager)

Motivation, Origin and Future

Axiom Query Language was developed during midScale project. The concepts of the language are based on Axiom data modeling. Axiom Query Language is replacing an old XML-based query language. The new language is more natural, user-friendly and better aligned with foundations of Axiom data modeling.

Axiom query language is a relative new development, introduced in midPoint 4.3. It was almost fully supported in midPoint 4.4 LTS, except for embedded expression. Since midPoint 4.5, Axiom query language is fully supported and recommended option.

The Axiom query language is a full replacement for XML-based language. The XML-based language will be still supported for some time, but it will be dropped eventually. Users of XML-based query language should migrate to Axiom query language as soon as possible.