I am doing an access control application using XACML and, specifically, the Balana implementation for the PDP.
In this application, specific types of user accounts can access only determinate resources. This is a reduced version of the Policy:
<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="NormalMode" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0">
<Description>Medical Records access control policy in Normal operational Mode</Description>
<Target />
<Rule Effect="Deny" RuleId="doctors">
<Target>
<AnyOf>
<AllOf>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">PersonalData</AttributeValue>
<AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true" />
</Match>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">DOCTOR</AttributeValue>
<AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true" />
</Match>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
<AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true" />
</Match>
</AllOf>
</AnyOf>
</Target>
<AdviceExpressions>
<AdviceExpression AdviceId="doctors_advice" AppliesTo="Deny">
<AttributeAssignmentExpression AttributeId="urn:oasis:names:tc:xacml:2.0:example:attribute:text">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Doctors are not allowed to see Personal Data</AttributeValue>
</AttributeAssignmentExpression>
</AdviceExpression>
</AdviceExpressions>
</Rule>
<Rule RuleId="permit-rule" Effect="Permit" />
</Policy>
In reality there are many more rules that cover all account types and all resource types, but they all have the same structure: the target is a subject-id (type of account), trying to access one [or more] resource[s] through an action. All the rules are with "Deny" effect, since the combining algorithm is "Deny-Overrides". At the end of all the rules, there is a general rule that grants access to everyone to anything with any action (I know this is not the best approach and in the future I will switch to a "least privilege" approach). If a request matches any of the deny rules (along with the last "Permit" rule), the final decision will be "Deny", otherwise only the last rule will be a match and the decision will be "Permit", instead.
The following is a request generated by the PEP to the Balana PDP:
<Request xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" CombinedDecision="false" ReturnPolicyIdList="false">
<Attributes Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject">
<Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" IncludeInResult="false">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">DOCTOR</AttributeValue>
</Attribute>
</Attributes>
<Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource">
<Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" IncludeInResult="false">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">NameSurname</AttributeValue>
</Attribute>
</Attributes>
<Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action">
<Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" IncludeInResult="false">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
</Attribute>
</Attributes>
</Request>
The decision of the PDP with this specific request should be "Permit", since it does not match the first rule due to the requested resource-id and it will match only the last Permit rule.
Now, the issue is that, regardless of the request I send, the outcome of the PDP decision is the following:
<Response xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17">
<Result>
<Decision>Indeterminate</Decision>
<Status>
<StatusCode Value="urn:oasis:names:tc:xacml:1.0:status:missing-attribute" />
<StatusMessage>Couldn't find AttributeDesignator attribute</StatusMessage>
<StatusDetail>
<MissingAttributeDetail AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:access-subject"></MissingAttributeDetail>
</StatusDetail>
</Status>
</Result>
</Response>
And I have no clue why.
https://docs.oasis-open.org/xacml/3.0/xacml-3.0-core-spec-cd-1-en.html
The XACML docs say that it's due to "The absence of matching attributes in the request context for any of the attribute designators attribute or selectors that are found in the policy" but I don't see why, since the last rule should always be a match. (This policy "format" is taken by the official Balana Github repository: https://github.com/wso2/balana/blob/master/modules/balana-samples/kmarket-trading-sample/resources/kmarket-blue-policy.xml)
First of all the supplied policy is incomplete. It is missing the closing tag and the Permit rule. In my testing I added these and it "works for me" but since we do not know exactly what you have it is possible you have other mistakes.
Your issue seems to be that you copy/pasted the attributes in the policy and are using the wrong category for subject-id. It should be:
urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
instead of:
urn:oasis:names:tc:xacml:3.0:subject-category:access-subject
So yes the request is missing the required subject-id attribute since the request is using a different category for subject-id than what is defined in the policy.
When I use the below corrected policy and request I do get a Permit. Note that I am not using Balana but you should see the same results.
Policy:
<xacml3:Policy xmlns:xacml3="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="NormalMode" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides">
<xacml3:Description>Medical Records access control policy in Normal operational Mode</xacml3:Description>
<xacml3:PolicyDefaults>
<xacml3:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116</xacml3:XPathVersion>
</xacml3:PolicyDefaults>
<xacml3:Target/>
<xacml3:Rule RuleId="doctors" Effect="Deny">
<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">PersonalData</xacml3:AttributeValue>
<xacml3:AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
</xacml3:Match>
<xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">DOCTOR</xacml3:AttributeValue>
<xacml3:AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml3:Match>
<xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</xacml3:AttributeValue>
<xacml3:AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:AdviceExpressions>
<xacml3:AdviceExpression AdviceId="doctors_advice" AppliesTo="Deny">
<xacml3:AttributeAssignmentExpression AttributeId="urn:oasis:names:tc:xacml:2.0:example:attribute:text" Category="http://axiomatics.com/ObligationAndAdvice/DefaultCategory">
<xacml3:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Doctors are not allowed to see Personal Data</xacml3:AttributeValue>
</xacml3:AttributeAssignmentExpression>
</xacml3:AdviceExpression>
</xacml3:AdviceExpressions>
</xacml3:Rule>
<xacml3:Rule RuleId="d3a90374-79e6-47e6-9cfd-f3e23f737c99" Effect="Permit">
<xacml3:Description>Rule description</xacml3:Description>
<xacml3:Target/>
</xacml3:Rule>
</xacml3:Policy>
Request:
<xacml-ctx:Request ReturnPolicyIdList="true" CombinedDecision="false" xmlns:xacml-ctx="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17">
<xacml-ctx:RequestDefaults>
<xacml-ctx:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116</xacml-ctx:XPathVersion>
</xacml-ctx:RequestDefaults>
<xacml-ctx:Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource">
<xacml-ctx:Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" IncludeInResult="false">
<xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">NameSurname</xacml-ctx:AttributeValue>
</xacml-ctx:Attribute>
</xacml-ctx:Attributes>
<xacml-ctx:Attributes Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject">
<xacml-ctx:Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" IncludeInResult="false">
<xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">DOCTOR</xacml-ctx:AttributeValue>
</xacml-ctx:Attribute>
</xacml-ctx:Attributes>
<xacml-ctx:Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action">
<xacml-ctx:Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" IncludeInResult="false">
<xacml-ctx:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</xacml-ctx:AttributeValue>
</xacml-ctx:Attribute>
</xacml-ctx:Attributes>
</xacml-ctx:Request>