使用 XACML 的复杂授权
Complex Authorization using XACML
我的公司正在寻求实施集中式安全服务,XACML 似乎是一个流行的标准。我有一个复杂的授权场景,我一直无法弄清楚如何使用 XACML 策略的属性来定义它。
我正在使用的系统有几个部分与此身份验证方案相关:
- 用户创建项目来组织他们的工作。每个项目都有一个团队成员和查看者列表(可以查看项目但不能修改项目的用户或组)。
- 在这些项目中,用户创建配方来描述应该如何制造某物。
- 用户请求这些配方由另一组制造。
如果用户想要查看特定项目的食谱,则必须满足以下任一条件:
- 用户必须是食谱的所有者(编写食谱的人)。
- 用户必须是创建配方的项目的团队成员。 (直接或通过群组成员资格)
- 用户必须是制作配方的组的成员。 (他们需要查看配方才能制造它。)
- 用户必须是在过去两周内制作该配方的组的成员。 (即,在完成制造配方的请求后,他们可以继续查看配方两周以纠正任何问题。)
- 用户必须是管理员。
根据这些规则,确定用户是否可以查看食谱所需的属性似乎包括:
- 用户
- 用户的组成员身份(用于项目访问、制造组或管理员访问)
- 项目组成员及观众
- 配方的制造请求
问题:
- PIP 如何收集这些信息?直接从数据库?通过服务调用存储此信息的系统?
- XACML(通常)如何表示此信息?我见过的大多数示例都使用不使用数据集合(如制造请求列表)的简单模型;只是直接在被访问的对象上设置属性。数据会以某种方式变平吗,比如 "isBeingManufacturedByUserGroup"? (如果是,如何确定该属性的值?)
- 如何构建政策来评估这些规则?
- 是否有其他方法可以处理此类授权(除了 XACML)? OAuth 2.0 是否能够更轻松地处理此类问题?
(免责声明 - 我为 Axiomatics 工作,这是 XACML 和 ABAC 的领先实施)
好问题。实际上,我已经整合了一个授权策略生命周期,引导用户完成收集需求、识别属性和实施策略的过程。
根据您的情况,让我们看一下您的要求
需求收集
你原来的要求
Any of the following must be true:
- The user must be the owner of the recipe (the person who wrote it).
- The user must be a team member on the project where the recipe was created. (either directly or via group membership)
- The user must be a member of a group manufacturing the recipe. (They need to see the recipe to manufacture it.)
- The user must be a member of a group that has manufactured the recipe within the past two weeks. (i.e., after completing a request to manufacture the recipe, they can continue to view the recipe for two weeks to correct any problems.)
- The user must be an administrator.
重组要求
我喜欢将需求修改为主语-动词-宾语,例如用户可以查看食谱...基于此模型,您的原始要求可以改写如下:
- 用户可以查看 he/she 拥有的食谱。
- 用户可以查看在用户所属的项目中创建的配方
- 用户可以查看属于该用户所属(制造)组的制造阶段的配方。
- 用户可以查看属于用户所属(制造)组的制造阶段的配方,如果制造日期在今天日期的 2 周内。
- 管理员可以查看食谱。
识别属性
您可以将属性分解为不同的类别(或语法功能)。 XACML 使用类别本身,因此这是使用 XACML(或 ALFA)实施的自然步骤。
主题属性
- userId:该类的关键属性。它将用于识别用户,但也检索所有其他派生属性。
- 项目:用户所属的项目列表
- 组:用户所属的组列表
- 角色:用户的角色,例如
资源属性
- objectType:这是一个属性,用于区分您要控制访问的不同类型的项目,例如食谱、文件或交易
- recipeId:食谱的关键属性。它将用于识别您想要访问的特定配方,也将用作查找其他属性的键,例如食谱所在的状态,所属的组和项目。
- 组:食谱所属的组
- 项目:菜谱所属的项目
动作属性
在这个类别中,从外观上看,您只有:
- 潜在值为{查看、编辑、删除...}的actionId。
使用属性重写的需求
- 任何人都可以在 objectType == "recipe" if recipe.owner == userId
上执行操作 == "view"
- 任何人都可以对 objectType == "view" 执行操作 == "recipe" if recipe.project == user.project
- 任何人都可以对 objectType == "recipe" 执行操作 == "view" if recipe.stage == "manufacturing" and recipe.group == user.group
- 任何人都可以对 objectType == "recipe" 执行操作 == "view" if recipe.stage == "manufactured" and recipe.group == user.group 和 currentDate <= recipe.manufacturedDate + "2 周".
- 具有角色 == "administrator" 的任何人都可以对 objectType == "recipe".
执行操作 == "view"
使用 ALFA 或 XACML 实施策略
下一步是实施您的政策。您可以使用 ALFA(授权缩写语言)。 Axiomatics 有一个 Eclipse plugin 可将 ALFA 转换为 XACML 3.0。
让我们创建一个处理食谱的策略集。该策略集将包含处理操作视图的策略。该政策反过来将包含满足每项要求的规则。
policyset recipe{
target clause objectType == "recipe"
apply firstApplicable
/**
* View recipes
*/
policy viewRecipe{
target clause actionId == "view"
apply firstApplicable
/**
* Administrators can view all recipes
*/
rule administrator{
target clause user.role == "administrator"
permit
}
/**
* Recipe owners can view their own recipes
*/
rule owner{
permit
condition user.userId == recipe.owner
}
/**
* Users can view recipes in their project
*/
rule sameProject{
permit
condition user.assignedProject == recipe.assignedProject
}
/**
* Users can view recipes in their project
*/
rule sameGroup{
target clause recipe.stage == "manufacturing"
permit
condition user.assignedGroup == recipe.assignedGroup
}
/**
* Users can view recipes in their project
*/
rule sameGroupManufactured{
target clause recipe.stage == "manufacturing"
permit
condition user.assignedGroup == recipe.assignedGroup && currentDate<=dateTimeAddDayTimeDuration(dateTimeOneAndOnly(recipe.manufacturedDate),"P14D":dayTimeDuration)
}
}
}
使用政策信息点
How would a PIP gather this information? Directly from a database? Via service calls to the system that stores this information?
PIP 只是外部属性源的抽象概念。它可以是任何东西。不同的实现将具有不同的 PIP 连接器。例如,Axiomatics Policy Server 为 SQL、LDAP 和 REST 服务提供连接器。这涵盖了客户的大部分需求。
XACML 和 OAuth 2.0
您比较了这两种技术,但它们在某种程度上有些不同。 OAuth 2.0 首先关注身份验证。它即将击败 password anti-pattern. Then there was a need to define permissions or, as they call them in OAuth, scopes. However those scopes are only punctual permissions. You still rely on the target application to publish a set of valid scopes and you still cannot do fine-grained access control. My colleague wrote a three-part blog on the topic, the first part of which you can read here.
希望对您有所帮助。欢迎随时向我提出后续问题或推文。
XACML 输出(奖金)
<?xml version="1.0" encoding="UTF-8"?>
<!--This file was generated by the ALFA Plugin for Eclipse from Axiomatics AB (http://www.axiomatics.com).
Any modification to this file will be lost upon recompilation of the source ALFA file-->
<xacml3:PolicySet xmlns:xacml3="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
PolicySetId="http://axiomatics.com/alfa/identifier/so.recipe"
PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable"
Version="1.0">
<xacml3:Description>Control access to recipes</xacml3:Description>
<xacml3:PolicySetDefaults>
<xacml3:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116</xacml3:XPathVersion>
</xacml3:PolicySetDefaults>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">recipe</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="so.objectType"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Policy xmlns:xacml3="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
PolicyId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"
Version="1.0">
<xacml3:Description>View recipes</xacml3:Description>
<xacml3:PolicyDefaults>
<xacml3:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116</xacml3:XPathVersion>
</xacml3:PolicyDefaults>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">view</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="so.actionId"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
MustBePresent="false"
/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe.administrator">
<xacml3:Description>Administrators can view all recipes</xacml3:Description>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">administrator</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="so.user.role"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
</xacml3:Rule>
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe.owner">
<xacml3:Description>Recipe owners can view their own recipes</xacml3:Description>
<xacml3:Target />
<xacml3:Condition>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of-any">
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
<xacml3:AttributeDesignator
AttributeId="so.user.userId"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
<xacml3:AttributeDesignator
AttributeId="so.recipe.owner"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe.sameProject">
<xacml3:Description>Users can view recipes in their project</xacml3:Description>
<xacml3:Target />
<xacml3:Condition>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of-any">
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
<xacml3:AttributeDesignator
AttributeId="so.user.assignedProject"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
<xacml3:AttributeDesignator
AttributeId="so.recipe.assignedProject"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe.sameGroup">
<xacml3:Description>Users can view recipes in their project</xacml3:Description>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">manufacturing</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="so.recipe.stage"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Condition>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of-any">
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
<xacml3:AttributeDesignator
AttributeId="so.user.assignedGroup"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
<xacml3:AttributeDesignator
AttributeId="so.recipe.assignedGroup"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe.sameGroupManufactured">
<xacml3:Description>Users can view recipes in their project</xacml3:Description>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">manufacturing</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="so.recipe.stage"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Condition>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of-any">
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
<xacml3:AttributeDesignator
AttributeId="so.user.assignedGroup"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
<xacml3:AttributeDesignator
AttributeId="so.recipe.assignedGroup"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Apply>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of">
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:dateTime-greater-than-or-equal"/>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:dateTime-add-dayTimeDuration" >
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only" >
<xacml3:AttributeDesignator
AttributeId="so.recipe.manufacturedDate"
DataType="http://www.w3.org/2001/XMLSchema#dateTime"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Apply>
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#dayTimeDuration">P14D</xacml3:AttributeValue>
</xacml3:Apply>
<xacml3:AttributeDesignator
AttributeId="currentDate"
DataType="http://www.w3.org/2001/XMLSchema#dateTime"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment"
MustBePresent="false"
/>
</xacml3:Apply>
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
</xacml3:Policy>
</xacml3:PolicySet>
我的公司正在寻求实施集中式安全服务,XACML 似乎是一个流行的标准。我有一个复杂的授权场景,我一直无法弄清楚如何使用 XACML 策略的属性来定义它。
我正在使用的系统有几个部分与此身份验证方案相关:
- 用户创建项目来组织他们的工作。每个项目都有一个团队成员和查看者列表(可以查看项目但不能修改项目的用户或组)。
- 在这些项目中,用户创建配方来描述应该如何制造某物。
- 用户请求这些配方由另一组制造。
如果用户想要查看特定项目的食谱,则必须满足以下任一条件:
- 用户必须是食谱的所有者(编写食谱的人)。
- 用户必须是创建配方的项目的团队成员。 (直接或通过群组成员资格)
- 用户必须是制作配方的组的成员。 (他们需要查看配方才能制造它。)
- 用户必须是在过去两周内制作该配方的组的成员。 (即,在完成制造配方的请求后,他们可以继续查看配方两周以纠正任何问题。)
- 用户必须是管理员。
根据这些规则,确定用户是否可以查看食谱所需的属性似乎包括:
- 用户
- 用户的组成员身份(用于项目访问、制造组或管理员访问)
- 项目组成员及观众
- 配方的制造请求
问题:
- PIP 如何收集这些信息?直接从数据库?通过服务调用存储此信息的系统?
- XACML(通常)如何表示此信息?我见过的大多数示例都使用不使用数据集合(如制造请求列表)的简单模型;只是直接在被访问的对象上设置属性。数据会以某种方式变平吗,比如 "isBeingManufacturedByUserGroup"? (如果是,如何确定该属性的值?)
- 如何构建政策来评估这些规则?
- 是否有其他方法可以处理此类授权(除了 XACML)? OAuth 2.0 是否能够更轻松地处理此类问题?
(免责声明 - 我为 Axiomatics 工作,这是 XACML 和 ABAC 的领先实施)
好问题。实际上,我已经整合了一个授权策略生命周期,引导用户完成收集需求、识别属性和实施策略的过程。
根据您的情况,让我们看一下您的要求
需求收集
你原来的要求
Any of the following must be true:
- The user must be the owner of the recipe (the person who wrote it).
- The user must be a team member on the project where the recipe was created. (either directly or via group membership)
- The user must be a member of a group manufacturing the recipe. (They need to see the recipe to manufacture it.)
- The user must be a member of a group that has manufactured the recipe within the past two weeks. (i.e., after completing a request to manufacture the recipe, they can continue to view the recipe for two weeks to correct any problems.)
- The user must be an administrator.
重组要求
我喜欢将需求修改为主语-动词-宾语,例如用户可以查看食谱...基于此模型,您的原始要求可以改写如下:
- 用户可以查看 he/she 拥有的食谱。
- 用户可以查看在用户所属的项目中创建的配方
- 用户可以查看属于该用户所属(制造)组的制造阶段的配方。
- 用户可以查看属于用户所属(制造)组的制造阶段的配方,如果制造日期在今天日期的 2 周内。
- 管理员可以查看食谱。
识别属性
您可以将属性分解为不同的类别(或语法功能)。 XACML 使用类别本身,因此这是使用 XACML(或 ALFA)实施的自然步骤。
主题属性
- userId:该类的关键属性。它将用于识别用户,但也检索所有其他派生属性。
- 项目:用户所属的项目列表
- 组:用户所属的组列表
- 角色:用户的角色,例如
资源属性
- objectType:这是一个属性,用于区分您要控制访问的不同类型的项目,例如食谱、文件或交易
- recipeId:食谱的关键属性。它将用于识别您想要访问的特定配方,也将用作查找其他属性的键,例如食谱所在的状态,所属的组和项目。
- 组:食谱所属的组
- 项目:菜谱所属的项目
动作属性
在这个类别中,从外观上看,您只有:
- 潜在值为{查看、编辑、删除...}的actionId。
使用属性重写的需求
- 任何人都可以在 objectType == "recipe" if recipe.owner == userId 上执行操作 == "view"
- 任何人都可以对 objectType == "view" 执行操作 == "recipe" if recipe.project == user.project
- 任何人都可以对 objectType == "recipe" 执行操作 == "view" if recipe.stage == "manufacturing" and recipe.group == user.group
- 任何人都可以对 objectType == "recipe" 执行操作 == "view" if recipe.stage == "manufactured" and recipe.group == user.group 和 currentDate <= recipe.manufacturedDate + "2 周".
- 具有角色 == "administrator" 的任何人都可以对 objectType == "recipe". 执行操作 == "view"
使用 ALFA 或 XACML 实施策略
下一步是实施您的政策。您可以使用 ALFA(授权缩写语言)。 Axiomatics 有一个 Eclipse plugin 可将 ALFA 转换为 XACML 3.0。
让我们创建一个处理食谱的策略集。该策略集将包含处理操作视图的策略。该政策反过来将包含满足每项要求的规则。
policyset recipe{
target clause objectType == "recipe"
apply firstApplicable
/**
* View recipes
*/
policy viewRecipe{
target clause actionId == "view"
apply firstApplicable
/**
* Administrators can view all recipes
*/
rule administrator{
target clause user.role == "administrator"
permit
}
/**
* Recipe owners can view their own recipes
*/
rule owner{
permit
condition user.userId == recipe.owner
}
/**
* Users can view recipes in their project
*/
rule sameProject{
permit
condition user.assignedProject == recipe.assignedProject
}
/**
* Users can view recipes in their project
*/
rule sameGroup{
target clause recipe.stage == "manufacturing"
permit
condition user.assignedGroup == recipe.assignedGroup
}
/**
* Users can view recipes in their project
*/
rule sameGroupManufactured{
target clause recipe.stage == "manufacturing"
permit
condition user.assignedGroup == recipe.assignedGroup && currentDate<=dateTimeAddDayTimeDuration(dateTimeOneAndOnly(recipe.manufacturedDate),"P14D":dayTimeDuration)
}
}
}
使用政策信息点
How would a PIP gather this information? Directly from a database? Via service calls to the system that stores this information?
PIP 只是外部属性源的抽象概念。它可以是任何东西。不同的实现将具有不同的 PIP 连接器。例如,Axiomatics Policy Server 为 SQL、LDAP 和 REST 服务提供连接器。这涵盖了客户的大部分需求。
XACML 和 OAuth 2.0
您比较了这两种技术,但它们在某种程度上有些不同。 OAuth 2.0 首先关注身份验证。它即将击败 password anti-pattern. Then there was a need to define permissions or, as they call them in OAuth, scopes. However those scopes are only punctual permissions. You still rely on the target application to publish a set of valid scopes and you still cannot do fine-grained access control. My colleague wrote a three-part blog on the topic, the first part of which you can read here.
希望对您有所帮助。欢迎随时向我提出后续问题或推文。
XACML 输出(奖金)
<?xml version="1.0" encoding="UTF-8"?>
<!--This file was generated by the ALFA Plugin for Eclipse from Axiomatics AB (http://www.axiomatics.com).
Any modification to this file will be lost upon recompilation of the source ALFA file-->
<xacml3:PolicySet xmlns:xacml3="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
PolicySetId="http://axiomatics.com/alfa/identifier/so.recipe"
PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable"
Version="1.0">
<xacml3:Description>Control access to recipes</xacml3:Description>
<xacml3:PolicySetDefaults>
<xacml3:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116</xacml3:XPathVersion>
</xacml3:PolicySetDefaults>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">recipe</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="so.objectType"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Policy xmlns:xacml3="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
PolicyId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"
Version="1.0">
<xacml3:Description>View recipes</xacml3:Description>
<xacml3:PolicyDefaults>
<xacml3:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116</xacml3:XPathVersion>
</xacml3:PolicyDefaults>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">view</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="so.actionId"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
MustBePresent="false"
/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe.administrator">
<xacml3:Description>Administrators can view all recipes</xacml3:Description>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">administrator</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="so.user.role"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
</xacml3:Rule>
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe.owner">
<xacml3:Description>Recipe owners can view their own recipes</xacml3:Description>
<xacml3:Target />
<xacml3:Condition>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of-any">
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
<xacml3:AttributeDesignator
AttributeId="so.user.userId"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
<xacml3:AttributeDesignator
AttributeId="so.recipe.owner"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe.sameProject">
<xacml3:Description>Users can view recipes in their project</xacml3:Description>
<xacml3:Target />
<xacml3:Condition>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of-any">
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
<xacml3:AttributeDesignator
AttributeId="so.user.assignedProject"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
<xacml3:AttributeDesignator
AttributeId="so.recipe.assignedProject"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe.sameGroup">
<xacml3:Description>Users can view recipes in their project</xacml3:Description>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">manufacturing</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="so.recipe.stage"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Condition>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of-any">
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
<xacml3:AttributeDesignator
AttributeId="so.user.assignedGroup"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
<xacml3:AttributeDesignator
AttributeId="so.recipe.assignedGroup"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe.sameGroupManufactured">
<xacml3:Description>Users can view recipes in their project</xacml3:Description>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">manufacturing</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="so.recipe.stage"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Condition>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of-any">
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
<xacml3:AttributeDesignator
AttributeId="so.user.assignedGroup"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
<xacml3:AttributeDesignator
AttributeId="so.recipe.assignedGroup"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Apply>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of">
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:dateTime-greater-than-or-equal"/>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:dateTime-add-dayTimeDuration" >
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only" >
<xacml3:AttributeDesignator
AttributeId="so.recipe.manufacturedDate"
DataType="http://www.w3.org/2001/XMLSchema#dateTime"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Apply>
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#dayTimeDuration">P14D</xacml3:AttributeValue>
</xacml3:Apply>
<xacml3:AttributeDesignator
AttributeId="currentDate"
DataType="http://www.w3.org/2001/XMLSchema#dateTime"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment"
MustBePresent="false"
/>
</xacml3:Apply>
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
</xacml3:Policy>
</xacml3:PolicySet>