diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/RoleMapperExpression.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/RoleMapperExpression.java
new file mode 100644
index 0000000000000..10c0d0911ba55
--- /dev/null
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/RoleMapperExpression.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.client.security.support.expressiondsl;
+
+import org.elasticsearch.common.xcontent.ToXContentObject;
+
+/**
+ * Implementations of this interface represent an expression used for user role mapping
+ * that can later be resolved to a boolean value.
+ */
+public interface RoleMapperExpression extends ToXContentObject {
+
+}
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/expressions/AllRoleMapperExpression.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/expressions/AllRoleMapperExpression.java
new file mode 100644
index 0000000000000..b5cbe4d2e425a
--- /dev/null
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/expressions/AllRoleMapperExpression.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.client.security.support.expressiondsl.expressions;
+
+import org.elasticsearch.client.security.support.expressiondsl.RoleMapperExpression;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An expression that evaluates to true if-and-only-if all its children
+ * evaluate to true.
+ * An all expression with no children is always true.
+ */
+public final class AllRoleMapperExpression extends CompositeRoleMapperExpression {
+
+ private AllRoleMapperExpression(String name, RoleMapperExpression[] elements) {
+ super(name, elements);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static final class Builder {
+ private List elements = new ArrayList<>();
+
+ public Builder addExpression(final RoleMapperExpression expression) {
+ assert expression != null : "expression cannot be null";
+ elements.add(expression);
+ return this;
+ }
+
+ public AllRoleMapperExpression build() {
+ return new AllRoleMapperExpression(CompositeType.ALL.getName(), elements.toArray(new RoleMapperExpression[0]));
+ }
+ }
+}
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/expressions/AnyRoleMapperExpression.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/expressions/AnyRoleMapperExpression.java
new file mode 100644
index 0000000000000..7632a071bd1c2
--- /dev/null
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/expressions/AnyRoleMapperExpression.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.client.security.support.expressiondsl.expressions;
+
+import org.elasticsearch.client.security.support.expressiondsl.RoleMapperExpression;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An expression that evaluates to true if at least one of its children
+ * evaluate to true.
+ * An any expression with no children is never true.
+ */
+public final class AnyRoleMapperExpression extends CompositeRoleMapperExpression {
+
+ private AnyRoleMapperExpression(String name, RoleMapperExpression[] elements) {
+ super(name, elements);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static final class Builder {
+ private List elements = new ArrayList<>();
+
+ public Builder addExpression(final RoleMapperExpression expression) {
+ assert expression != null : "expression cannot be null";
+ elements.add(expression);
+ return this;
+ }
+
+ public AnyRoleMapperExpression build() {
+ return new AnyRoleMapperExpression(CompositeType.ANY.getName(), elements.toArray(new RoleMapperExpression[0]));
+ }
+ }
+}
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/expressions/CompositeRoleMapperExpression.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/expressions/CompositeRoleMapperExpression.java
new file mode 100644
index 0000000000000..2519c59b68846
--- /dev/null
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/expressions/CompositeRoleMapperExpression.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.client.security.support.expressiondsl.expressions;
+
+import org.elasticsearch.client.security.support.expressiondsl.RoleMapperExpression;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Expression of role mapper expressions which can be combined by operators like AND, OR
+ *
+ */
+public abstract class CompositeRoleMapperExpression implements RoleMapperExpression {
+ private final String name;
+ private final List elements;
+
+ CompositeRoleMapperExpression(final String name, final RoleMapperExpression... elements) {
+ assert name != null : "field name cannot be null";
+ assert elements != null : "at least one field expression is required";
+ this.name = name;
+ this.elements = Collections.unmodifiableList(Arrays.asList(elements));
+ }
+
+ public String getName() {
+ return this.getName();
+ }
+
+ public List getElements() {
+ return elements;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final CompositeRoleMapperExpression that = (CompositeRoleMapperExpression) o;
+ if (Objects.equals(this.getName(), that.getName()) == false) {
+ return false;
+ }
+ return Objects.equals(this.getElements(), that.getElements());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, elements);
+ }
+
+ @Override
+ public XContentBuilder toXContent(final XContentBuilder builder, final Params params) throws IOException {
+ builder.startObject();
+ builder.startArray(name);
+ for (RoleMapperExpression e : elements) {
+ e.toXContent(builder, params);
+ }
+ builder.endArray();
+ return builder.endObject();
+ }
+
+}
+
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/expressions/CompositeType.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/expressions/CompositeType.java
new file mode 100644
index 0000000000000..1d6c8aea12263
--- /dev/null
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/expressions/CompositeType.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.client.security.support.expressiondsl.expressions;
+
+import org.elasticsearch.common.ParseField;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public enum CompositeType {
+
+ ANY("any"), ALL("all"), EXCEPT("except");
+
+ private static Map nameToType = Collections.unmodifiableMap(initialize());
+ private ParseField field;
+
+ CompositeType(String name) {
+ this.field = new ParseField(name);
+ }
+
+ public String getName() {
+ return field.getPreferredName();
+ }
+
+ public ParseField getParseField() {
+ return field;
+ }
+
+ public static CompositeType fromName(String name) {
+ return nameToType.get(name);
+ }
+
+ private static Map initialize() {
+ Map map = new HashMap<>();
+ for (CompositeType field : values()) {
+ map.put(field.getName(), field);
+ }
+ return map;
+ }
+
+}
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/expressions/ExceptRoleMapperExpression.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/expressions/ExceptRoleMapperExpression.java
new file mode 100644
index 0000000000000..c2cad0d18dad1
--- /dev/null
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/expressions/ExceptRoleMapperExpression.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.client.security.support.expressiondsl.expressions;
+
+import org.elasticsearch.client.security.support.expressiondsl.RoleMapperExpression;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+
+import java.io.IOException;
+
+/**
+ * A negating expression. That is, this expression evaluates to true if-and-only-if
+ * its delegate expression evaluate to false.
+ * Syntactically, except expressions are intended to be children of all
+ * expressions ({@link AllRoleMapperExpression}).
+ */
+public final class ExceptRoleMapperExpression extends CompositeRoleMapperExpression {
+
+ public ExceptRoleMapperExpression(final RoleMapperExpression expression) {
+ super(CompositeType.EXCEPT.getName(), expression);
+ }
+
+ @Override
+ public XContentBuilder toXContent(final XContentBuilder builder, final Params params) throws IOException {
+ builder.startObject();
+ builder.field(CompositeType.EXCEPT.getName());
+ builder.value(getElements().get(0));
+ return builder.endObject();
+ }
+
+}
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/fields/FieldRoleMapperExpression.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/fields/FieldRoleMapperExpression.java
new file mode 100644
index 0000000000000..c96ac3cc5b5ec
--- /dev/null
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/fields/FieldRoleMapperExpression.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.client.security.support.expressiondsl.fields;
+
+import org.elasticsearch.client.security.support.expressiondsl.RoleMapperExpression;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * An expression that evaluates to true if a field (map element) matches
+ * the provided values. A field expression may have more than one provided value, in which
+ * case the expression is true if any of the values are matched.
+ *