Support Questions

Find answers, ask questions, and share your expertise
Announcements
Celebrating as our community reaches 100,000 members! Thank you!

Is it possible to reference multiple tags in one Ranger tag policy via Policy Conditions?

avatar
Rising Star

Is it possible to reference more than one Atlas tag in one Ranger policy via the Policy Conditions?

I can set-up allow or deny tag policies, but would like to reference a combination of tags in the Policy Conditions on one policy. Is this possible?

Example

Let's say I have these 3 tags: (tenancy_component with some attributes, tenancy_xxx and tenancy_yyy).

{
  "classificationDefs":[
    {
      "createdBy": "Laura",
      "name": "tenancy_component",
      "description": "tenancy_component",
      "attributeDefs": [
      {
	   "name":"landing",
	   "typeName":"boolean",
	   "isOptional":"true",
	   "isUnique":"false",
	   "isIndexable":"true",
	   "cardinality":"SINGLE"
      },
	  {
	   "name":"staging",
	   "typeName":"boolean",
	   "isOptional":"true",
	   "isUnique":"false",
	   "isIndexable":"true",
	   "cardinality":"SINGLE"
      },
	  {
	   "name":"data_lake",
	   "typeName":"boolean",
	   "isOptional":"true",
	   "isUnique":"false",
	   "isIndexable":"true",
	   "cardinality":"SINGLE"
      }],
     "superTypes": []
    }
  ]
}
{
  "classificationDefs":[
    {
      "createdBy": "Laura",
      "name": "tenancy_xxx",
      "description": "tenancy_xxx",
      "attributeDefs": [
      {
      }],
     "superTypes": []
    },
	{
      "createdBy": "Laura",
      "name": "tenancy_yyy",
      "description": "tenancy_yyy",
      "attributeDefs": [
      {
      }],
     "superTypes": []
    }
  ]
}

I want to provide access (ABAC) to a role such that it doesn't have access to landing unless it is in tenancy xxx, it has access to the data lake for tenancy xxx but not yyy. The role only have access to staging if it is part of tenancy_yyy.

Database nameTagsAccess
db1tenancy_xxx, tenancy_component.landing=trueAccess
db2tenancy_xxx, tenancy_component.staging=trueDeny
db3tenancy_xxx, tenancy_component.data_lake=trueAccess
db5tenancy_yyy, tenancy_component.landing=trueDeny
db6tenancy_yyy, tenancy_component.staging=trueAccess
db7tenancy_yyy, tenancy_component.data_lake=trueDeny
db7tenancy_component.data_lake=trueDeny

How many tag policies should I have and how would I do it?

1 ACCEPTED SOLUTION

avatar
Rising Star
Is it possible to reference more than one Atlas tag in one Ranger policy via the Policy Conditions?

Yes. Following can be used to access details of all tags associated with the resource being accessed:

ctx.getAllTagTypes() <== returns names of all tags associated with the resource (Set<String>)
ctx.getTagAttributes(tagType) <== returns attributes of given tag (Map<String, String>)
ctx.getAttributeValue(tagType, attrName) <== returns value of attribute 'attrName' in tagType tag

The usecase you describe seems to require access-control based on tenancy and the zone in which the data resides. Please consider the following approach:

1. Define a classification named 'DATA_ZONE', with one attribute named "name" - as shown below:

"classificationDefs": [
    {
      "name": "DATA_ZONE",
      "attributeDefs": [
        {
          "name":     "name",
          "typeName": "string"
        }
      ]
    }
  ]

2. Define one classification for each tenant. In your example, you already have 2 classifications "tenancy_xxx" and "tenancy_yyy".

3. Create one tag-based policy for each tenant. Per your example, you would create 2 policies - one for "tenancy_xxx" tag and another for "tenancy_yyy" tag.

4. In policy for each tenant, you can use conditions as shown below to allow/deny access to users/groups:

ctx.getAttributeValue("DATA_ZONE", "name").equals("landing")
ctx.getAttributeValue("DATA_ZONE", "name").equals("staging")
ctx.getAttributeValue("DATA_ZONE", "name").equals("data_lake")

View solution in original post

9 REPLIES 9

avatar
Rising Star
Is it possible to reference more than one Atlas tag in one Ranger policy via the Policy Conditions?

Yes. Following can be used to access details of all tags associated with the resource being accessed:

ctx.getAllTagTypes() <== returns names of all tags associated with the resource (Set<String>)
ctx.getTagAttributes(tagType) <== returns attributes of given tag (Map<String, String>)
ctx.getAttributeValue(tagType, attrName) <== returns value of attribute 'attrName' in tagType tag

The usecase you describe seems to require access-control based on tenancy and the zone in which the data resides. Please consider the following approach:

1. Define a classification named 'DATA_ZONE', with one attribute named "name" - as shown below:

"classificationDefs": [
    {
      "name": "DATA_ZONE",
      "attributeDefs": [
        {
          "name":     "name",
          "typeName": "string"
        }
      ]
    }
  ]

2. Define one classification for each tenant. In your example, you already have 2 classifications "tenancy_xxx" and "tenancy_yyy".

3. Create one tag-based policy for each tenant. Per your example, you would create 2 policies - one for "tenancy_xxx" tag and another for "tenancy_yyy" tag.

4. In policy for each tenant, you can use conditions as shown below to allow/deny access to users/groups:

ctx.getAttributeValue("DATA_ZONE", "name").equals("landing")
ctx.getAttributeValue("DATA_ZONE", "name").equals("staging")
ctx.getAttributeValue("DATA_ZONE", "name").equals("data_lake")

avatar
Rising Star

Thanks, @Madhan Neethiraj - that's very helpful indeed. And I like your suggestion about how to structure the Ranger policies - very logical.

I will try this out and will post back if I have any other queries about this.

avatar
Rising Star
@Madhan Neethiraj

I'm having problems getting the tag policy to work. Here are the steps I've taken:

  • Disabled resource policies - holger_gov cannot select on default and foodmart database
  • Created a tag called tennant_xxx
  • Created a tag policy giving access to holger_gov if tag is tennant_xxx - so far so good as holger_gov now has select access
  • Created a tag called DATA_ZONE with attribute name (type string) and added to default and footmart database - one with a name = data_lake and one with name = staging
  • Added policy condition:
ctx.getAttributeValue("DATA_ZONE", "name").equals("data_lake")

But holger_gov can still select on both databases - I only want the data_lake one to be selectable.

I have tried various combinations to try to get it to work including the below, but to no avail. Any ideas?

if(ctx.getAttributeValue("DATA_ZONE", "name").equals("data_lake")) {
ctx.result = true;
} else {
ctx.result = false;
}

avatar
Rising Star

@Laura Ngo - can you verify that no other policy allowed select access on footmart database for holger_gov (please look at Ranger audit log)?

avatar
Rising Star

@Madhan Neethiraj - The Ranger Audit looks to me as though only policy 35 is being used. I've attached some screen prints. I'm not sure if it's relevant, but the Ranger Audit policy when clicked doesn't show the ',', although in the actual policy the ',' is still present.

64478-screen-shot-2018-03-05-at-003151.png

64479-screen-shot-2018-03-05-at-003222.png

64480-screen-shot-2018-03-05-at-003252.png

64481-screen-shot-2018-03-05-at-003318.png

avatar
Rising Star

@Laura Ngo - I was able to reproduce the issue. The expression you entered is indeed correct:

ctx.getAttributeValue("DATA_ZONE","name").equals("data_lake")

However, when the policy is saved from UI, the entered expression is broken into multiple strings, causing the evaluation to fail at runtime. This is likely an issue with Ranger UI. I was able to get around this issue by updating the policies via REST API; if possible, please update the policies via REST API. I will update on the UI issue shortly.

avatar
Rising Star

@Madhan Neethiraj - I've changed the Ranger policy via PUT service/public/v2/api/policy/35

"conditions": [
  {
"type": "expression",
"values": ["ctx.getAttributeValue('DATA_ZONE','name').equals('data_lake')"]
}
]
<br>

But I'm still not getting the desired behaviour - I would expect holger_gov to be denied access based on the below flow:

Here's a screenshot of the Ranger Audit

64500-ranger-audit.png

Could you perhaps paste the full output of your GET service/public/v2/api/policy/{i} policy so I can compare? Here's mine:

{"id": 35,
"guid": "1d7a6456-840d-4d1d-b5d5-7ec37d50eb8c",
"isEnabled": true,
"createdBy": "Admin",
"updatedBy": "Admin",
"createTime": 1520122079000,
"updateTime": 1520255099000,
"version": 22,
"service": "sandbox_tag",
"name": "tenancy_food",
"policyType": 0,
"description": "",
"resourceSignature": "5b2d59d4b57c1fa990c17143d54c89974270cf8e928f982e03c89055cbc69386",
"isAuditEnabled": true,
"resources": {"tag": {"values": [  "tenancy_food"
],


"isExcludes": false,
"isRecursive": false
}


},


"policyItems": [  {"accesses": [  {"type": "hive:select",
"isAllowed": true
},


  {"type": "hive:update",
"isAllowed": true
},


  {"type": "hive:create",
"isAllowed": true
},


  {"type": "hive:drop",
"isAllowed": true
},


  {"type": "hive:alter",
"isAllowed": true
},


  {"type": "hive:index",
"isAllowed": true
},


  {"type": "hive:lock",
"isAllowed": true
},


  {"type": "hive:all",
"isAllowed": true
},


  {"type": "hive:read",
"isAllowed": true
},


  {"type": "hive:write",
"isAllowed": true
},


  {"type": "hive:repladmin",
"isAllowed": true
},


  {"type": "hive:serviceadmin",
"isAllowed": true
}


],


"users": [  "holger_gov"
],


"groups": [],
"conditions": [  {"type": "expression",
"values": [  "ctx.getAttributeValue('DATA_ZONE','name').equals('data_lake')"
],


}


],


"delegateAdmin": false
}


],


"denyPolicyItems": [],
"allowExceptions": [],
"denyExceptions": [],
"dataMaskPolicyItems": [],
"rowFilterPolicyItems": [],
}
<br>

avatar
Rising Star

@Laura Ngo - the policy contents look right. Audit log shows the tag name in lower case - "data_zone". Please ensure that the tag name used in the condition is same as the one in Atlas.

avatar
Rising Star

You are exactly right - thank you. Both the Atlas tag and the Ranger policy were in caps but I don't think Ranger Audit likes caps. I changed both to lower and the access is denied.

access-denied.png

Thanks so much for your help. (I've never been so happy to see an 'access denied' message!)