I'm trying to enter our database model into ALFA in order to check the capabilities of ALFA and XACML.
Are attributes like the following possible? How would look the rules then?
1:n by list of strings
namespace com.mycompany {
namespace resources {
namespace patient {
attribute trustedDoctorIds{
category = resourceCat
id = "trustedDoctorIds"
type = list<string> //maybe it should be bag[string]
}
}
}
}
1:n by list of complex type
namespace com.mycompany {
namespace resources {
namespace patient {
attribute trustedDoctors{
category = resourceCat
id = "trustedDoctors"
type = list<doctor> //maybe it should be bag[doctor]
}
}
}
namespace subjects {
namespace doctor {
attribute id {
category = subjectCat
id = "id"
type = string
}
attribute lastname {
category = subjectCat
id = "lastname"
type = string
}
}
}
}
You have a great question there.
By default all attributes in ALFA and XACML are multi-valued. Attributes are bags of values rather than single values. This means that when you define the following,
attribute trustedDoctorIds{
category = resourceCat
id = "trustedDoctorIds"
type = string
}
This means the attribute has a type of string and it can be multi-valued. You could choose to express cardinality information in the comments above the attribute definition e.g.
/**
* This attribute, trustedDoctorIds, contains the list of doctors a patient
*trusts. The list can have 0 or more values.
*/
The policy is the one that will convey how many values there can be depending on the functiosn being used.
For instance, you could write a condition that states
stringOneAndOnly(trustedDoctorIds)==stringOneAndOnly(userId)
In that case, you are forcing each attribute to have one value and one value only. If you have 0 or more than 1 value, then the evaluation of the XACML policy will yield Indeterminate
.
In a XACML (or ALFA) target, when you write:
trustedDoctorIds == "Joe"
You are saying: if there is at least one value in trustedDoctorIds equal to 'Joe'...
In an ALFA condition, when you write
trustedDoctorIds==userId
You are saying: *if there is at least one value in trustedDoctorIds
equal to at least one value in userId
Note: I always use singular names for my attributes when I can. It's a convention, not a hard limit. Remembering the cardinality of your attributes will help later in your policy testing.
What would be a plural name you try to avoid by your convention?
Well trustedDoctorId***s*** looks rather plural to me. I would use trustedDoctorId
unless you know that the attribute is necessarily always multi-valued.
So, this should be possible: In my request I provide resource.patient.trustedDoctorIds=="2,13,67" and subject.doctor.id=="6". How would the rule then look like in ALFA? Smth. like "resource.patient.trustedDoctorIds.contains(subject.doctor.id) permit"
The rule would look like the following:
stringIsIn(stringOneAndOnly(subject.doctor.id),resource.patient.trustedDoctorIds)
Make sure that you provide multiple values in your request, not one value that contains comma-separated values. Send in [1,2,3] rather than "1,2,3".
So, by [2,13,67] the result is deny as expected and not permit like with "2,13,67" and doctorId==6. I chose that example on purpose, since the stringIsIn function would result unwantedly with true since 6 is included in 67
Do not confuse stringIsIn()
and stringContains()
.
stringIsIn(a, b)
takes in 2 parameters a and b where a is an atomic value and b is a bag of values. stringIsIn(a, b)
returns true if the value of a is in the bag of values of b.stringContains(a, b)
takes in 2 parameters a and b that are both atomic values of type string. It returns true if the string value a is found inside b.stringIsIn(stringOneAndOnly(userCitizenship), stringBag("Swedish", "German"))
returns true if the user has a single citizenship equal to either of Swedish or German.stringContains("a", "alfa")
returns true if the second string contains the first one. So it returns true in this example.