I'm using balana downloaded from git.
I'm working on a policy rule which should only Permit if the policy's string-bag is a subset of the matching attributes in the request.
Eg. Request contains attributes "letter=a, letter=b", and policy uses a string-subset to compare the set of letter attributes from the request to the string-bag. I've tried both orders of subset (subset letter stringbag vs subset stringbag letter) but they both come back with "Permit" when my test-request should be getting "Deny".
Sample policy
<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="policy1"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0">
<Target>
<AnyOf>
<AllOf>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
myguid0123456789
</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>
</AllOf>
</AnyOf>
</Target>
<Rule Effect="Deny" RuleId="securityLevel">
<Condition>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
<AttributeDesignator AttributeId="securityLevel" Category="tags" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true" />
</Apply>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">
9000
</AttributeValue>
</Apply>
</Condition>
<AdviceExpressions>
<AdviceExpression AdviceId="channel-security-too-low" AppliesTo="Deny">
<AttributeAssignmentExpression AttributeId="urn:oasis:names:tc:xacml:2.0:example:attribute:text">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
Message security is over 9000! It's not good cap'n, I cannae make it go any faster!
</AttributeValue>
</AttributeAssignmentExpression>
</AdviceExpression>
</AdviceExpressions>
</Rule>
<Rule Effect="Permit" RuleId="caveats">
<Condition>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-subset">
<AttributeDesignator AttributeId="caveats" Category="tags" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true" />
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
A
</AttributeValue>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
B
</AttributeValue>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
C
</AttributeValue>
</Apply>
</Apply>
</Condition>
<AdviceExpressions>
<AdviceExpression AdviceId="data-caveat-not-on-channel" AppliesTo="Deny">
<AttributeAssignmentExpression AttributeId="urn:oasis:names:tc:xacml:2.0:example:attribute:text">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
caveat advice fail
</AttributeValue>
</AttributeAssignmentExpression>
</AdviceExpression>
</AdviceExpressions>
</Rule>
<Rule RuleId="permit-rule" Effect="Permit" />
</Policy>
And I'm passing this request for testing:
Request
<Request xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" CombinedDecision="false" ReturnPolicyIdList="true">
<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="true">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
send
</AttributeValue>
</Attribute>
</Attributes>
<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="true">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
99991699
</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="true">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
myguid0123456789
</AttributeValue>
</Attribute>
</Attributes>
<Attributes Category="tags">
<Attribute AttributeId="securityLevel" IncludeInResult="true">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">
8000
</AttributeValue>
</Attribute>
<Attribute AttributeId="caveats" IncludeInResult="true">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
A
</AttributeValue>
</Attribute>
<Attribute AttributeId="caveats" IncludeInResult="true">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
B
</AttributeValue>
</Attribute>
</Attributes>
</Request>
So, my thinking (because I'm not sure of any way to tell it negation) is that
it implicitly associates a negative match on the condition to the negation of the effect.
If that's true, my intuition is that a matching subset that's OK should say "Permit" but then if it fails to match the condition, it would instead say "Deny".
Since there's no target statement, my intuition is that it "should" try to evaluate that condition on all requests, so not matching the condition shouldn't cause the rule to skip being evaluated.
In any case, looking at the sample, I want it to say "my policy takes A,B, but you have A,B,C, so I have to deny you." Unfortunately that's not what it's doing, and I'm not sure why. Please help. x_x
You have several issues in your policy and request.
First of all, in XML and XACML <element>value</element> is not the same as
<element>
value
</element>
If you are sending your requests as such and your policies are stored as such then the values you are checking are ' A ', ' B ' and so on. This is going to be an issue.
Secondly you use a deny-overrides combining algorithm with your policy P. P contains 3 rules R1, R2, and R3. R1 is a deny rule. If it applies, then deny is returned and R2 and R3 will not be considered. If R1 does not apply, then the PDP moves on to R2 and R3. If R2 applies then the possible decision is Permit BUT the PDP still needs to check R3 in case it returns a Deny.
You will get a Deny if securityLevel > 9000.
You will get a Permit if securityLevel <= 9000 and caveats contains at most A, B, C.
Finally R3 always grants you access. So no matter what you do in the second rule, the third one will grant you access. In other words R2 doesn't serve any purpose at all.
I tested your policy in the Axiomatics Policy Server and I could see that behavior in the simulator. You should get the same with Balana.
Also you should check for securityLevel in the target, not in the condition that's overkill.
it implicitly associates a negative match on the condition to the negation of the effect.
There is nothing implicit in XACML. The opposite of Permit is NotApplicable.
Since there's no target statement, my intuition is that it "should" try to evaluate that condition on all requests, so not matching the condition shouldn't cause the rule to skip being evaluated.
If there is no target in a rule, then it goes straight to the condition which it considers. It does not skip the rule. But in your case it returns NotApplicable.
If you want to achieve what you are looking for, use combining algorithm first-applicable and change R3 from Permit to Deny.
Have a look at this XACML blog for more information.
Related
I'm learning XACML 3.0 by reading the OASIS Standard document, 22 January 2013 version.
The first example policy (section 4.1.1) is quite simple and easy to understand: a Name-match function on the request's subject-id attribute (in form of a RFC822 name) must be performed: if the name submitted matches the value of the rule's AttributeValue attribute, the PDP evaluates to Permit.
<?xml version="1.0" encoding="UTF-8"?>
<Policy
xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd"
PolicyId="urn:oasis:names:tc:xacml:3.0:example:SimplePolicy1"
Version="1.0"
RuleCombiningAlgId="identifier:rule-combining-algorithm:deny-overrides">
<Description>
Medi Corp access control policy
</Description>
<Target/>
<Rule
RuleId= "urn:oasis:names:tc:xacml:3.0:example:SimpleRule1"
Effect="Permit">
<Description>
Any subject with an e-mail name in the med.example.com domain
can perform any action on any resource.
</Description>
<Target>
<AnyOf>
<AllOf>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:rfc822Name-match">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
med.example.com
</AttributeValue>
<AttributeDesignator
MustBePresent="false"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-688 subject"
AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
DataType="urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name"/>
</Match>
</AllOf>
</AnyOf>
</Target>
</Rule>
</Policy>
The document then proceeds to show an ipothetical decision request (properly formatted as a request context) sumbitted to the PDP. This is also quite simple: a subject whose subject-id is bs#simpsons.com is trying a read action on a filesystem resource:
<?xml version="1.0" encoding="UTF-8"?>
<Request
xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd"
ReturnPolicyIdList="false">
<Attributes
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-757 subject">
<Attribute
IncludeInResult="false"
AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id">
<AttributeValue DataType="urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name">
bs#simpsons.com
</AttributeValue>
</Attribute>
</Attributes>
<Attributes
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource">
<Attribute
IncludeInResult="false"
AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">
file://example/med/record/patient/BartSimpson
</AttributeValue>
</Attribute>
</Attributes>
<Attributes
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action">
<Attribute
IncludeInResult="false"
AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
read
</AttributeValue>
</Attribute>
</Attributes>
</Request>
Now, here comes the part that I don't understand: the document says (row numbers 805 to 807)
The PDP now compares the attributes in the request context with the target of the one rule in this policy. The requested resource matches the <Target> element and the requested action matches the <Target> element, but the requesting subject-id attribute does not match "med.example.com".
Ok the subject-id not matching, but how are the resource and action exactly matching if they're not specified within the rule? Maybe their absence is somehow discarded and not applies to the target, but the document says that they match and this is a standard document and the exact meaning of each word if of uttermost importance. I'm not finding anything about it and this - to me - is a big deal as I'm trying to build my own XACML3.0-compliant system as a side project.
What am I missing?
Thanks!
I'm testing the Authzforce Server application to enter XACML policies and test XACML decision requests. I'm trying to enter my first XACML policy set. The problem is that I always get a 409 Conflict response with no response body, although the policy set was apparently saved in the data store successfully when I retrieve it by ID and version.
Here's the policy set I've entered:
<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="PolicySetExample" Version="1.0" PolicyCombiningAlgId="identifier:policy-combining-algorithm:deny-overrides">
<Target/>
<Policy PolicyId="urn:oasis:names:tc:xacml:3.0:example:SimplePolicy1" Version="1.0" RuleCombiningAlgId="identifier:rule-combining-algorithm:deny-overrides">
<Target/>
<Rule RuleId="urn:oasis:names:tc:xacml:3.0:example:MyRule" Effect="Permit">
<Target>
<AnyOf>
<AllOf>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Medical record</AttributeValue>
<AttributeDesignator MustBePresent="false" 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"/>
</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 MustBePresent="false" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id-qualifier" DataType="http://www.w3.org/2001/XMLSchema#string"/>
</Match>
</AllOf>
</AnyOf>
</Target>
<Condition>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
<AttributeDesignator MustBePresent="false" 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"/>
</Apply>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue>
</Apply>
</Condition>
</Rule>
</Policy>
</PolicySet>
...using the service endpoint POST /domains/domain-id/pap/policies.
The service responds with a 409 with no details on the actual conflict but when I try to retrieve the policy using...
GET /domains/domain-id/pap/policies/PolicySetExample/1.0
...then I see that the policy set has been saved, I get the policy set document with a policy ID reference to the policy called "ComplexPolicy":
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns4:PolicySet xmlns="http://authzforce.github.io/core/xmlns/pdp/6.0" xmlns:ns2="http://authzforce.github.io/rest-api-model/xmlns/authz/5" xmlns:ns3="http://authzforce.github.io/pap-dao-flat-file/xmlns/properties/3.6" xmlns:ns4="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:ns5="http://www.w3.org/2005/Atom" PolicySetId="PolicySetExample" Version="1.0" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:permit-overrides">
<ns4:Description>TestPolicySet</ns4:Description>
<ns4:Target>
<ns4:AnyOf>
<ns4:AllOf>
<ns4:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<ns4:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">H1</ns4:AttributeValue>
<ns4:AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:environment-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
</ns4:Match>
</ns4:AllOf>
</ns4:AnyOf>
</ns4:Target>
<ns4:PolicyIdReference>ComplexPolicy</ns4:PolicyIdReference>
</ns4:PolicySet>
I've checked the Authzforce log file in /var/log/tomcat8/authzforce-ce/error.log but there's nothing related to this specific error.
Any ideas and pointers are welcome.
EDIT: can it be that the conflict is with the default "root" policy set of the Authzforce?
Thanks,
Andras
As far as I understand, you already did POST a PolicySet 'PolicySetExample' in Version '1.0' successfully, since this is the one you get with GET .../PolicySetExample/1.0.
Now you are trying to POST a PolicySet 'PolicySetExample' in Version '1.0' again (but new content), which fails because the REST API interprets that as an attempt to create a new PolicySet (PolicySet resource) with same PolicySetId and Version as another, whereas the (PolicySetId,Version) tuple should be unique on the domain. So in your case it's likely a Version conflict.
2 options:
If you want to replace/overwrite the previous PolicySet content, remove the existing .../PolicySetExample/1.0 on the server with DELETE method, then upload/create the PolicySet again with POST method.
If you want to upload a new version (and keep the old one on the server), increment the Version attribute. Be aware that: a) you can have multiple versions of a PolicySet (with same PolicySetId but different Version I mean); b) if you use it in a PolicySetIdReference, always the latest Version is used by default in AuthzForce, unless you specify the Version explicitly (or use EarliestVersion/LatestVersion as per XACML standard but I don't recommend to use them).
I try to use REST API to evaluate XACML requests as in the below documentation
https://docs.wso2.com/display/IS530/Using+REST+APIs+via+XACML+to+Manage+Entitlement
But I get 500 Internal server error and in the XACML logs, I see
"No operation matching request path
"/api/identity/entitlement/decision/pdp" is found, Relative Path:
/pdp, HTTP Method: POST, ContentType:
application/xml,application/xml, Accept: application/xml,."
XACML request
<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">customer1</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">POST</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">private/team</AttributeValue>
</Attribute>
</Attributes>
</Request>
Could somebody help to identify the issue ?
Regards,
Albie Morken
I validate your XACML request using the Axiomatics Policy Administration Point. It is correct.
Given the error you receive is
"No operation matching request path
"/api/identity/entitlement/decision/pdp" is found, Relative Path:
/pdp, HTTP Method: POST, ContentType: application/xml,application/xml,
Accept: application/xml,."
I am suspecting the issue is the URI / path you are using. You need to check how the REST PDP is exposed. For instance, inside the Axiomatics Policy Server, the PDP is exposed as https://host:port/asm-pdp/authorize. The REST Profile of XACML states how to retrieve the endpoint.
A PIP extension code using a "RedAttributeFinder" class is working now. It correctly register its claims into the WSO2 PDP extension console display.
I start to create a XACML policy now, addressing the field that returns the dynamic data value delivered by the extension program (for example a field named "http://w3.red.com/subject/employeeCountryCode").
The key field for a data look-up is: urn:oasis:names:tc:xacml:1.0:resource:resource-id
, which maps a user identity in an email format.
Question 1: How is invocation of the “getAttributesValues” method done at the "RedAttributeFinder" class, registered at the start of WSO2. What triggers the call of the method from the PDP process (or its incoming requests)?
In the sample code, as well as at my implementation, the key field is the resource-id which is loaded as part of the PEP request implementation.
..
myRequest += "<Attributes Category=\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\">" + "\n";
myRequest += "<Attribute AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\" IncludeInResult=\"false\">" + "\n";
myRequest += "<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">tony#br.red.com</AttributeValue>" + "\n";
myRequest += "</Attribute>" + "\n";
myRequest += "</Attributes>" + "\n";
myRequest += "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\">" + "\n";
myRequest += "<Attribute AttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\" IncludeInResult=\"true\">" + "\n";
..
This is the key input for the "getAttributesValues()" and will return a country code (similar to the role [blue, silver, gold] definition in the WSO2 example code [ available here https://svn.wso2.org/repos/wso2/carbon/platform/trunk/components/identity/org.wso2.carbon.identity.samples.entitlement.pip/ ] .
In the sample, I see that the required resolution of roles value, for example "blue" is part of the Policy target definition.
Question 2: Is this placement inside target section a requirement to call the dynamic PIP look-up, one per requests, or can it also be placed at other parts of the policy, like for example inside a rule?
I was able to test the PEP to PDP interaction with a rule definition, only by defining static variables, receiving "permit", a rule that I would like to change to the dynamic data obtained from the PIP implementation and its extension, addressing the new fields added by the code.
In a standard implementation that complies with the XACML standard, the PDP will invoke the PIP any time it finds an attribute designator in its policies that is also published by the PIP (it means the PIP must advertise which attributes it can provide e.g. it provides role, citizenship...).
The PDP could choose not to call a PIP and to use an attribute cache instead. The placement of the attribute in the policy is irrelevant. Whether the attribute is used inside a target or a condition should not matter - according to spec at least - and that is how the Axiomatics, SunXACML, and ATT engines all work.
Cheers,
David.
I've found a useful debug option in the WSO2 setup by adding this line into log4j.properties file:
log4j.logger.org.wso2.carbon.identity.entitlement=DEBUG
This command started to trace the requests sent to the PIP, including the call to the PIP extension class (by attribute designator) and returning data fields.
This confirmed that the PIP is called dynamically by the PDP, as well as the Try-It function. The policy below delivered the expected "permit" and "deny" results, by this confirming proper functioning of the PIP extension program.
Below a very simple policy that was tested with a PIP extension code fetching a value for the data variable named: employeeCountryCode.
Policy
<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="RedLDAPPolicy1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-overrides" Version="1.0">
<Target>
</Target>
<Rule Effect="Permit" RuleId="Permit-Rule1">
<Target>
<AnyOf>
<AllOf>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">631</AttributeValue>
<AttributeDesignator AttributeId="http://w3.red.com/subject/employeeCountryCode" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true">
</AttributeDesignator>
</Match>
</AllOf>
</AnyOf>
<AnyOf>
<AllOf>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ldap</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">
</AttributeDesignator>
</Match>
</AllOf>
</AnyOf>
<AnyOf>
<AllOf>
<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">
</AttributeDesignator>
</Match>
</AllOf>
</AnyOf>
</Target>
</Rule>
<Rule Effect="Deny" RuleId="Deny-Rule">
</Rule>
</Policy>
Request
<Request xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" CombinedDecision="false" ReturnPolicyIdList="false">
<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>
<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">tony#br.red.com</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="true">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ldap</AttributeValue>
</Attribute>
</Attributes>
</Request>
I'm trying to write an XACML policy that will utilize a custom attribute. I'm thinking of something like:
<?xml version="1.0" encoding="UTF-8"?>
<Policy xmlns="urn:oasis:names:tc:xacml:1.0:policy"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="deny-demo100"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
<Description> </Description>
<Target>
<Subjects>
<AnySubject/>
</Subjects>
<Resources>
<AnyResource/>
</Resources>
<Actions>
<AnyAction/>
</Actions>
</Target>
<Rule Effect="Deny" RuleId="rule-deny-demo100">
<Target>
<Subjects>
<AnySubject/>
</Subjects>
<Resources>
<Resource>
<AnyResource/>
</Resource>
</Resources>
<Actions>
<Action>
<ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">customAttribute</AttributeValue>
<ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action- id" MustBePresent="false" DataType="http://www.w3.org/2001/XMLSchema#string"/>
</ActionMatch>
</Action>
</Actions>
</Target>
</Rule>
<Rule RuleId="deny-demo100-catch-all" Effect="Permit" />
</Policy>
(We're using Fedora's XACML implementation).
I'm sure I'm missing something really simple and fundamental here, but cannot figure out what. Could someone point me in the right direction please?
What do you mean by custom attribute? What is it you want to express in 'plain old English'?
In XACML you can use any attribute you like such as role, citizenship, clearance, resource classification, time of day... Of course the availability of the attribute depends on the type of app you are protecting. How are you using the Fedora implementation? Is it for access control within Fedora Linux OS?
If you want to compare an attribute to a value e.g. citizenship == Canadian, then use a <Target/>. If you want to compare 2 attributes together e.g. clearance > classification, then use a <Condition>.
I am not sure what you are actually looking for, but I guess you need to do some attribute-based access control.
In XACML there is a component called PIP (Policy Information Point), where you can retrieve attributes from external sources and check authorization.
This may help you: Understanding PIP (Policy Information Point).
If you need to create XACML policies in a easier way, you can follow this: XACML Policy Editor in WSO2 Identity Server.
I have to admit I'm kinda new to XACML and Fedora's implementation of it, but my understanding is you should be able to query any value that appears when checking the user object. The URL on a default Fedora Commons install should be "localhost:8080/fedora/user" and yields the following object on my server after logging in a previously created LDAP user called "Joe User":
<user id="Joe User">
<attribute name="uid">
<value>userj</value>
</attribute>
<attribute name="mail">
<value>UserJ#ldap.test.user.uconn.edu</value>
</attribute>
<attribute name="sn">
<value>User</value>
</attribute>
<attribute name="ou">
<value>DPT</value>
</attribute>
<attribute name="cn">
<value>Joe User</value>
</attribute>
<attribute name="description">
<value>sample user</value>
</attribute>
<attribute name="role"/>
<attribute name="fedoraRole"/>
<attribute name="objectClass">
<value>organizationalPerson</value>
<value>person</value>
<value>inetOrgPerson</value>
<value>top</value>
</attribute>
<attribute name="displayName">
<value>Joe User (LDAP)</value>
</attribute>
</user>
Once a value has been injected into the user object via some JAAS authentication module (as in the above case using the LDAP module) or even an environment variable you should be able to query it. In the example policy below I've set Fedora to grant fedoraAdmin like access to API-M calls if a user has an OU set to "DPT":
<?xml version="1.0" encoding="UTF-8"?>
<Policy xmlns="urn:oasis:names:tc:xacml:1.0:policy"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
PolicyId="permit-apim-to-ldap-ou"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"
>
<!-- test policy to approve API-M operations if a specific LDAP OU exists -->
<!-- make sure access to API-M in premitted from the current client IP address first (check "deny-apim-if-not-in-list.xml" or "deny-apim-if-not-localhost.xml" ) -->
<Description>note that other policies may provide exceptions to this broad policy. This policy assumes api-m users have to be authenticated</Description>
<Target>
<Subjects>
<Subject>
<!-- specific OU - need to get this working with a range of values -->
<SubjectMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">DPT</AttributeValue>
<SubjectAttributeDesignator AttributeId="ou" MustBePresent="false" DataType="http://www.w3.org/2001/XMLSchema#string"/>
</SubjectMatch>
</Subject>
</Subjects>
<Resources>
<AnyResource/>
</Resources>
<Actions>
<AnyAction/>
</Actions>
</Target>
<Rule RuleId="1" Effect="Permit"/>
</Policy>
Custom attributes can even be added the Fedora XML User file (not the Tomcat user file) rather than using LDAP. Likely there is a better way to do this, but as I stated before I'm rather new to XACML and don't fully understand it. This rule works on my localhost test server based on the other rules also in place. Your mileage may vary.
Also, as stated in the sample policy file, make sure that the client you are testing from can both be permitted and then later denied API-M access before you put a rule like this in place as debugging XACML policies in Fedora seems to be extremely difficult with little data being written to the log file even in Debug mode (you will see an operation passed or failed but never the name of the rule that caused the pass/fail result to happen).