You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ranger.apache.org by "mneethiraj (via GitHub)" <gi...@apache.org> on 2026/10/08 18:41:36 UTC
[PR] RANGER-5822: make application supplied context attributes accessible in expressions [ranger]
mneethiraj opened a new pull request, #1302:
URL: https://github.com/apache/ranger/pull/1302
## What changes were proposed in this pull request?
- expressions can use variable CTX_ATTR to access context attributes in the access request
## How was this patch tested?
- added unit tests
- verified that all existing tests pass successfully
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] RANGER-5822: make application supplied context attributes accessible in expressions [ranger]
Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #1302:
URL: https://github.com/apache/ranger/pull/1302#discussion_r4230104965
##########
agents-common/src/main/java/org/apache/ranger/authorization/utils/JsonUtils.java:
##########
@@ -47,6 +48,7 @@ public class JsonUtils {
private static final Logger LOG = LoggerFactory.getLogger(JsonUtils.class);
private static final TypeReference<Map<String, String>> TYPE_MAP_STRING_STRING = new TypeReference<Map<String, String>>() {};
+ private static final TypeReference<Map<String, Object>> TYPE_MAP_STRING_OBJECT = new TypeReference<>() {};
Review Comment:
Using the diamond operator with an anonymous TypeReference (`new TypeReference<>() {}`) can break compilation when building with Java 8 (and is inconsistent with the explicit generic style used in the surrounding constants). Prefer `new TypeReference<Map<String, Object>>() {}` for compatibility and consistency.
##########
agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerRequestScriptEvaluatorTest.java:
##########
@@ -615,6 +653,14 @@ private static String tempFilePath(String tag, long nonce) {
return new File(System.getProperty("java.io.tmpdir"), "ranger_test_" + tag + "_" + nonce).getAbsolutePath();
}
+ RangerAccessRequest createRequest(String userName, String attributes) {
+ RangerAccessRequestImpl ret = (RangerAccessRequestImpl) createRequest(userName, Collections.emptySet(), Collections.emptySet(), Collections.emptyList());
+
+ RangerAccessRequestUtil.setContextAttrJson(ret.getContext(), attributes);
+
+ return ret;
+ }
Review Comment:
The cast to `RangerAccessRequestImpl` makes this helper brittle (it will fail with a `ClassCastException` if the underlying factory method ever returns a different implementation). If the `RangerAccessRequest` interface exposes `getContext()`, use it directly to avoid the cast; otherwise, consider changing the underlying `createRequest(...)` helper to return `RangerAccessRequestImpl` within the test.
##########
agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java:
##########
@@ -60,11 +60,36 @@ public class RangerAccessRequestUtil {
public static final String KEY_CONTEXT_BATCH_EVAL_CONTEXT = "BATCH_EVAL_CONTEXT";
public static final String KEY_CONTEXT_RESOURCE_ZONE_NAMES = "RESOURCE_ZONE_NAMES";
public static final String KEY_CONTEXT_ACL_ENFORCER = "_ACL_ENFORCER";
+ public static final String KEY_CONTEXT_ATTR_JSON = "_ATTR_JSON";
private RangerAccessRequestUtil() {
// to avoid instantiation
}
+ public static void setContextAttrJson(Map<String, Object> context, String attrJson) {
+ if (context != null) {
+ if (attrJson == null) {
+ context.remove(KEY_CONTEXT_ATTR_JSON);
+ } else {
+ context.put(KEY_CONTEXT_ATTR_JSON, attrJson);
+ }
+ }
+ }
+
+ public static String getContextAttrJson(Map<String, Object> context) {
+ Object ret = context != null ? context.get(KEY_CONTEXT_ATTR_JSON) : null;
+
+ if (ret != null) {
+ if (ret instanceof String) {
+ return (String) ret;
+ } else {
+ LOG.error("getContextAttrJson(): failed to get {} from context", KEY_CONTEXT_ATTR_JSON);
+ }
+ }
+
+ return null;
+ }
Review Comment:
If `_ATTR_JSON` is present but not a `String`, this will emit an error without indicating the offending type/value and will keep the bad value in the context, potentially causing repeated log noise. Consider including `ret.getClass()` in the log and removing the invalid entry from the context to self-heal.
##########
agents-common/src/main/java/org/apache/ranger/authorization/utils/JsonUtils.java:
##########
@@ -197,6 +199,20 @@ public static Map<String, String> jsonToMapStringString(String jsonStr) {
return ret;
}
+ public static Map<String, Object> jsonToMapStringObject(String jsonStr) {
+ Map<String, Object> ret = null;
+
+ if (StringUtils.isNotEmpty(jsonStr)) {
+ try {
+ ret = getMapper().readValue(jsonStr, TYPE_MAP_STRING_OBJECT);
+ } catch (Exception excp) {
+ LOG.warn("jsonToMapStringObject() failed to convert json to object: {}", jsonStr, excp);
+ }
Review Comment:
This warning log prints the full `jsonStr`, which may contain sensitive context attributes (PII/financial data). Consider logging only metadata (e.g., length) and/or truncating/masking the value, or moving the raw payload to debug-level under a feature flag.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] RANGER-5822: make application supplied context attributes accessible in expressions [ranger]
Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #1302:
URL: https://github.com/apache/ranger/pull/1302#discussion_r4226668321
##########
agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRequestScriptEvaluator.java:
##########
@@ -915,7 +918,7 @@ private String toJson() {
request.put(SCRIPT_FIELD_USER_GROUP_ATTRIBUTES, groupAttrs);
request.put(SCRIPT_FIELD_UGA, new UserGroupsAttributes(userGroups, groupAttrs).getAttributes());
-
+ request.put(SCRIPT_FIELD_CTX_ATTR, RangerAccessRequestUtil.cloneWithNoInternalKeys(getRequestContext()));
Review Comment:
`RangerAccessRequest.getContext()` permits arbitrary `Object` values, so adding the entire application context to the JSON payload makes every JSON-backed expression depend on every value being Jackson-serializable. A cyclic map or unsupported object makes `JsonUtils.objectToJson()` return `null`; the constructor's pre-exec then cannot initialize `REQ`/`CTX_ATTR`, and the condition falls back to `false`. Normalize or validate each exposed value (or omit/reject unsupported attributes independently) so one unrelated attribute cannot disable policy expression evaluation, and cover this with a regression test.
##########
agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerRequestScriptEvaluatorTest.java:
##########
@@ -605,6 +605,46 @@ void testBlockJavaClassReferencesWithDefaultConfig() {
Assertions.assertTrue(escaped.isEmpty(), "Sandbox escape OS command executed via:\n " + String.join("\n ", escaped));
}
+ @Test
+ public void testContextAttributes() {
+ Map<String, Object> attributes = new HashMap<>();
+
+ attributes.put("trx_amount", 10000);
+
+ RangerAccessRequest request = createRequest("test-user", Collections.emptySet(), Collections.emptySet(), attributes);
+ RangerRequestScriptEvaluator evaluator = new RangerRequestScriptEvaluator(request, scriptEngine);
+
+ // trx_amount=10,000; test if less-than-or-equals 10,000 => false
Review Comment:
The comment states that the less-than-or-equal comparison is false, but `10,000 <= 10,000` and the assertion below are true.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] RANGER-5822: make application supplied context attributes accessible in expressions [ranger]
Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #1302:
URL: https://github.com/apache/ranger/pull/1302#discussion_r4229482033
##########
agents-common/src/main/java/org/apache/ranger/authorization/utils/JsonUtils.java:
##########
@@ -197,6 +199,20 @@ public static Map<String, String> jsonToMapStringString(String jsonStr) {
return ret;
}
+ public static Map<String, Object> jsonToMapStringObject(String jsonStr) {
+ Map<String, Object> ret = null;
+
+ if (StringUtils.isNotEmpty(jsonStr)) {
+ try {
+ ret = getMapper().readValue(jsonStr, TYPE_MAP_STRING_OBJECT);
+ } catch (Exception excp) {
+ LOG.warn("jsonToMapStringObject() failed to convert json to object: {}", jsonStr, excp);
Review Comment:
This log line includes the full `jsonStr`, which may contain sensitive request context attributes (PII/transaction data). Consider avoiding logging raw input (or logging only a truncated/redacted version and/or length) to prevent sensitive-data disclosure in logs.
##########
agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerAccessRequestUtil.java:
##########
@@ -246,4 +247,43 @@ public ResourceMatchingScope getResourceMatchingScope() {
};
assertEquals(rs, RangerAccessRequestUtil.getUserRoles(req));
}
+
+ @Test
+ public void testContextAttributes() {
+ Map<String, Object> context = new HashMap<>();
+
+ // null context
+ assertEquals(Collections.emptyMap(), JsonUtils.jsonToMapStringObject(null));
+
+ Map<String, Map<String, Object>> tests = new HashMap<>() {{
+ put(null, Collections.emptyMap()); // null
+ put("", Collections.emptyMap()); // empty
+ put("[]", Collections.emptyMap()); // invalid map value
+ put("xyz", Collections.emptyMap()); // invalid map value
+ put("xyz=43", Collections.emptyMap()); // invalid map value
+ put("xyz: 43", Collections.emptyMap()); // invalid map value
+ put("{xyz: 43", Collections.emptyMap()); // invalid map value
+ put("{}", Collections.emptyMap()); // valid map value: empty
+ put("{'amount': 43}", toMap("amount", 43)); // valid map value, one entry
+ put("{\"amount\": 43}", toMap("amount", 43)); // valid map value, one entry
+ put("{\"amount\": 43, \"limit\": 127}", toMap("amount", 43, "limit", 127)); // valid map value, two entries
+ }};
Review Comment:
This uses double-brace initialization, which creates an anonymous inner class and can retain unintended references and complicate debugging/serialization. Prefer building the map explicitly (e.g., sequential `put()` calls, or `Map.ofEntries(...)`) to keep the test simpler and avoid the anonymous class.
##########
agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerRequestScriptEvaluatorTest.java:
##########
@@ -605,6 +605,44 @@ void testBlockJavaClassReferencesWithDefaultConfig() {
Assertions.assertTrue(escaped.isEmpty(), "Sandbox escape OS command executed via:\n " + String.join("\n ", escaped));
}
+ @Test
+ public void testContextAttributes() {
+ String attrJson = "{'trx_amount':10000}";
Review Comment:
This uses single quotes, which is not valid JSON per the spec and may break if the underlying Jackson/ObjectMapper configuration changes (or differs across environments). Prefer standard JSON with double quotes here (and in subsequent `attrJson` strings) to keep the test robust and aligned with real-world JSON producers.
##########
agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java:
##########
@@ -60,11 +60,26 @@ public class RangerAccessRequestUtil {
public static final String KEY_CONTEXT_BATCH_EVAL_CONTEXT = "BATCH_EVAL_CONTEXT";
public static final String KEY_CONTEXT_RESOURCE_ZONE_NAMES = "RESOURCE_ZONE_NAMES";
public static final String KEY_CONTEXT_ACL_ENFORCER = "_ACL_ENFORCER";
+ public static final String KEY_CONTEXT_ATTR_JSON = "_ATTR_JSON";
private RangerAccessRequestUtil() {
// to avoid instantiation
}
+ public static void setContextAttrJson(Map<String, Object> context, String attrJson) {
+ if (context != null) {
+ if (attrJson == null) {
+ context.remove(KEY_CONTEXT_ATTR_JSON);
+ } else {
+ context.put(KEY_CONTEXT_ATTR_JSON, attrJson);
+ }
+ }
+ }
+
+ public static String getContextAttrJson(Map<String, Object> context) {
+ return context != null ? (String) context.get(KEY_CONTEXT_ATTR_JSON) : null;
Review Comment:
This unchecked cast can throw `ClassCastException` if a non-String value is present under `_ATTR_JSON` (e.g., if another caller populates the context directly). Consider using an `instanceof String` check (or `String.valueOf(...)` with a null check) to make this helper more defensive and avoid a runtime failure in request processing.
##########
agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerAccessRequestUtil.java:
##########
@@ -246,4 +247,43 @@ public ResourceMatchingScope getResourceMatchingScope() {
};
assertEquals(rs, RangerAccessRequestUtil.getUserRoles(req));
}
+
+ @Test
+ public void testContextAttributes() {
+ Map<String, Object> context = new HashMap<>();
+
+ // null context
+ assertEquals(Collections.emptyMap(), JsonUtils.jsonToMapStringObject(null));
+
+ Map<String, Map<String, Object>> tests = new HashMap<>() {{
+ put(null, Collections.emptyMap()); // null
+ put("", Collections.emptyMap()); // empty
+ put("[]", Collections.emptyMap()); // invalid map value
+ put("xyz", Collections.emptyMap()); // invalid map value
+ put("xyz=43", Collections.emptyMap()); // invalid map value
+ put("xyz: 43", Collections.emptyMap()); // invalid map value
+ put("{xyz: 43", Collections.emptyMap()); // invalid map value
+ put("{}", Collections.emptyMap()); // valid map value: empty
+ put("{'amount': 43}", toMap("amount", 43)); // valid map value, one entry
+ put("{\"amount\": 43}", toMap("amount", 43)); // valid map value, one entry
+ put("{\"amount\": 43, \"limit\": 127}", toMap("amount", 43, "limit", 127)); // valid map value, two entries
+ }};
+
+ tests.forEach((key, value) -> {
+ RangerAccessRequestUtil.setContextAttrJson(context, key);
+ assertEquals(value, JsonUtils.jsonToMapStringObject(RangerAccessRequestUtil.getContextAttrJson(context)));
+ });
+ }
+
+ private static Map<String, Object> toMap(String key1, Object val1, Object...args) {
+ Map<String, Object> ret = new HashMap<>();
+
+ ret.put(key1, val1);
+
Review Comment:
The loop assumes `args` has an even length; if it is ever called with an odd number of varargs, `args[idx + 1]` will throw `ArrayIndexOutOfBoundsException`. Add a guard (e.g., validate `args.length % 2 == 0` and fail fast with a clear exception) to make the helper safe and the failure mode clearer.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] RANGER-5822: make application supplied context attributes accessible in expressions [ranger]
Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #1302:
URL: https://github.com/apache/ranger/pull/1302#discussion_r4222939581
##########
agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java:
##########
@@ -60,11 +61,18 @@ public class RangerAccessRequestUtil {
public static final String KEY_CONTEXT_BATCH_EVAL_CONTEXT = "BATCH_EVAL_CONTEXT";
public static final String KEY_CONTEXT_RESOURCE_ZONE_NAMES = "RESOURCE_ZONE_NAMES";
public static final String KEY_CONTEXT_ACL_ENFORCER = "_ACL_ENFORCER";
+ // make sure to add all internal keys in INTERNAL_CONTEXT_KEYS, to exclude them from CTX_ATTR in expressions
+
+ private static final Set<String> INTERNAL_CONTEXT_KEYS;
private RangerAccessRequestUtil() {
// to avoid instantiation
}
+ public static boolean isInternalKey(String key) {
+ return INTERNAL_CONTEXT_KEYS.contains(key);
+ }
Review Comment:
`KEY_TOKEN_NAMESPACE` is a prefix (`"token:"`), but `contains()` only filters a key exactly equal to that prefix. Keys created by `setTokenInContext()` (for example `token:USER`, `token:ROLES`, and HDFS filename tokens) therefore leak into `CTX_ATTR`, contrary to this internal-key filter. Treat every key beginning with the namespace as internal, and add a regression assertion for a namespaced token.
##########
agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerRequestScriptEvaluatorTest.java:
##########
@@ -605,6 +605,40 @@ void testBlockJavaClassReferencesWithDefaultConfig() {
Assertions.assertTrue(escaped.isEmpty(), "Sandbox escape OS command executed via:\n " + String.join("\n ", escaped));
}
+ @Test
+ public void testContextAttributes() {
+ Map<String, Object> attributes = new HashMap<>();
+
+ attributes.put("trx_amount", 10000);
+
+ RangerAccessRequest request = createRequest("test-user", Collections.emptySet(), Collections.emptySet(), attributes);
+ RangerRequestScriptEvaluator evaluator = new RangerRequestScriptEvaluator(request, scriptEngine);
+
+ Assertions.assertTrue((Boolean) evaluator.evaluateScript("CTX_ATTR.trx_amount <= 10000"), "CTX_ATTR.trx_amount <= 10000");
Review Comment:
This test constructs the evaluator with the overload that always enables the JSON context, so it would still pass if `CTX_ATTR` were omitted from `needsJsonCtxEnabled()`—the path used by `RangerScriptConditionEvaluator` in production. Add an assertion for automatic detection (or exercise `RangerScriptConditionEvaluator`) so the new variable cannot silently evaluate without initialization.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] RANGER-5822: make application supplied context attributes accessible in expressions [ranger]
Posted by "mneethiraj (via GitHub)" <gi...@apache.org>.
mneethiraj merged PR #1302:
URL: https://github.com/apache/ranger/pull/1302
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org