ctx and _ctx object in policy conditions

The ctx and _ctx objects in Apache Ranger enable dynamic, attribute-based policy conditions by providing the evaluation context. These objects allow for advanced access control decisions through JavaScript.

By leveraging the ctx object, the policy conditions evaluate factors such as how, when, and where the access request is made. This approach enables the application of a unified rule across all permissions within the policy.

When you define a condition at the policy level, you establish a master gateway. This gateway is a single JavaScript expression that must evaluate to True for Apache Ranger to even consider any of the individual allow or deny rules within that policy.

Policy-level conditions in Apache Ranger utilize JavaScript scripts to assess contextual information. The context evaluation system offers a comprehensive set of data through the ctx or _ctx context objects, which JavaScript scripts can use to make advanced policy decisions.

The following table outlines the key differences between the ctx and _ctx objects:

Table 1. Comparing ctx and _ctx
Aspect ctx _ctx
Type Java object with methods JavaScript object with data
Access pattern ctx.methodName() _ctx.property.subproperty
Best for Built-in utility functions Direct data access
Examples ctx.hasTag('PCI') _ctx.request.user

Best practices

The dual-context system in Apache Ranger offers policy authors maximum flexibility when writing JavaScript conditions. It provides convenience methods through ctx and raw data access through _ctx, enabling efficient and versatile policy creation. Cloudera recommends using the following best practices:

  • Use ctx to complete the following tasks:
    • Perform time-based validations, such as ctx.isAccessedAfter()
    • Run built-in checks, including ctx.hasTag() and ctx.isInGroup()
    • Execute complex utility functions
  • Use _ctx to complete the following tasks:
    • Access data directly, for example _ctx.request.user
    • Perform complex data comparisons
    • Apply custom logic on raw data
  • Use a hybrid approach:
    • Combine both ctx and _ctx objects for optimal performance and readability
    • Leverage ctx methods for intensive operations and use _ctx for direct data access

Context structure available in JavaScript

The _ctx object serves as a gateway to the following types of categorized information:
  • Request information (_ctx.request)
    • Resource details – Access resource-specific data using _ctx.request.resource.*
    • User information – Retrieve user-related details such as _ctx.request.user, _ctx.request.userGroups, and _ctx.request.userRoles
    • Access details – Understand access specifics through _ctx.request.accessType and _ctx.request.action
    • User attributes – Access user-specific attributes through _ctx.request.userAttributes.*
    • Group attributes – Retrieve group-specific attributes using _ctx.request.userGroupAttributes.*
  • Tag information (_ctx.tags, _ctx.tag)
    • All tags – Access all tags by using _ctx.tags
    • Current tag – Retrieve the current tag with _ctx.tag
    • Tag attributes – Access specific tag attributes such as _ctx.tag.attr1 or _ctx.tags['PCI'].attr1
  • Context attributes
    • Custom context – Retrieve custom context attributes by using ctx.getRequestContextAttribute('key')

JavaScript examples for policy-level conditions

  • Resource-based conditions
    // Check database access
                  _ctx.request.resource.database == 'sensitive_db'
                  // Check multiple resources
                  _ctx.request.resource.database == 'hr' && _ctx.request.resource.table == 'employees'
                  // Pattern matching
                  _ctx.request.resource.database.indexOf('prod') != -1
  • User and group-based conditions
    // Check specific user
                  _ctx.request.user == 'admin'
                  // Check user groups
                  _ctx.request.userGroups.indexOf('data_scientists') != -1
                  // Multiple group check
                  _ctx.request.userGroups.length >= 2 && 
                  _ctx.request.userGroups.indexOf('managers') != -1
                  // User roles check
                  _ctx.request.userRoles.indexOf('dba') != -1
  • User or group attribute-based conditions
    // Check user attributes
                  _ctx.request.userAttributes['department'] == 'finance'
                  // Check multiple user attributes
                  _ctx.request.userAttributes['clearance_level'] == 'top_secret' && 
                  _ctx.request.userAttributes['location'] == 'headquarters'
                  // Group attribute check
                  _ctx.request.userGroupAttributes['finance']['budget_access'] == 'unlimited'
  • Tag-based conditions
    <codeblock id="codeblock_tyd_jgx_c3c">// Check specific tag type
                  _ctx.tag._type == 'PCI'
                  // Check tag attributes
                  _ctx.tag.level == 'high'</codeblock>