Rich, Hal, all,
This is to capture our conversation at the last OpenAz conference call.
The submission we made to OpenAz a couple of months ago uses a simple “dispatch” mechanism to handle Obligations. We did this to support use cases that we saw, where Obligations needed to be handled _after_ the PEP returns control to the application.
1. An application can define one or more “Obligation Handlers” – objects that understand how to handle enforcement of specific types of Obligations.
2. Obligation Handlers get registered with the framework at startup.
3. Each Obligation Handler provides an “acceptor” function that will evaluate an Obligation and either accept or reject it.
4. When the PEP receives a response with XACML Obligations (or Advice), it looks to the set of Obligation Handlers, and ensures that each Obligation or Advice has a Handler that will accept it.
5. The PEP will throw an exception if there is no handler that accepts a specific Obligation. If there is no handler for an Advice object, that Advice object is silently dropped.
6. Responsibility is thus transferred from the PEP to the Obligation Handler.
Some additional notes:
1. Obligation Handlers have a common interface, supplied within the OpenAz framework, but specific handlers need to be implemented either by applications or as part of other frameworks and services.
2. The delegation model, where the Policy Enforcement Point delegates to purpose-built Obligation Handlers, allows obligations to be handled after the PEP completes its work. That is, the PEP ensures that responsibility for an Obligation has been delegated, but the PEP returns control to the invoking application without confirming that the conditions in the Obligation are fully met. We took this design approach because many of our use cases for obligations involved required actions that must happen within the transaction being protected, and therefore enforcement cannot be guaranteed before control is returned to the application.
3. The OpenAz framework works within a single Java process, and the Obligation Handler class likewise exists within that process. However, we have use cases where we want to delegate an obligation to a support service. For example, an application may want to delegate an obligation to redact sensitive data to the supporting data service, or to delegate an obligation for secondary authentication to a supporting authentication service. In these cases, the Obligation Handler delegates the obligation across process boundaries.
4. One significant intent in our design was to keep the OpenAz framework focused on the base XACML specification, and agnostic to any profiles in use. The “acceptor” function was designed as a part of the Handler, to be supplied from outside the framework, because acceptance criteria may well include verification of Obligation ID in conformance with a XACML profile. We believe our design can be extended by supplying a library of Acceptor functions that aligns with such a Profile, but those Acceptor functions should be integrated optionally.
We discussed whether this delegation approach is consistent with the meaning of the “Policy Enforcement Point.” If the PEP is intended architecturally to be responsible for guaranteeing enforcement, the idea that it would return control before enforcement is guaranteed does seem troublesome. But I think this is inevitable because different types of obligations require different enforcement strategies, and some obligations can only be fully enforced during or after the protected operation. Here is my understanding of that:
All obligations can be understood as logical preconditions. But different obligations may or may not be temporal preconditions, and some obligations are impossible to enforce outside of the business transaction. Some example obligations:
1. When permitting display of account summary information, mask the account and card numbers to show only the last 4 digits.
2. When permitting a debit transaction, override the permission if the debit would overdraw the account.
3. When permitting a financial transaction, require that the user’s session has been authenticated with multiple factors.
4. When permitting a financial transaction, require a transaction-specific authentication as “confirmation.”
The first of these – redaction – must be enforced either by the data service, so that numbers are masked before they are sent to the application, or by the presentation layer, so that they are masked before they are displayed.
In the second case, enforcement must be done within the permitted transaction. While you can check to see whether the account is already overdrawn, or whether its current balance would allow a withdrawal of the given amount, it is still possible in an event-driven system that a separate transaction against the account could be in progress, so limit enforcement before the transaction could be insufficient to guarantee that the permitted transaction does not overdraw the account.
In the third, actual enforcement would be delegated to an authentication service. This is a temporal precondition: we want multi-factor authentication in place before the transaction, so the Obligation Handler can interrogate the authentication service when the PEP calls the acceptor function.
In the fourth, the authentication / confirmation must be logically within the transaction, typically just after the user has completed the request, but it may still be possible to enforce the obligation fully when the PEP calls the acceptor function. Whether it is in fact possible depends upon other application factors, so for example there may be UI or workflow steps within the permitted transaction that the application must serialize in order to manage the user’s experience, for example.
We also discussed the topic of Obligation types, and I will document that discussion on the TC list. Do you think there is value in forwarding this mail to the TC mailing list as a part of that discussion?
Regards,
David
Hi Darshak,
Thanks for providing this use case.
I have done some thinking about it, and I am suggesting that an approach
along the following lines might be used to address some of the issues.
Analysis:
As you point out, we used the ordering of parameters
in the current pepapi to implicitly specify the category
that the object being passed in should map to.
This approach, while fairly brittle, did meet the known reqts
for XACML 2.0, so that's what was used.
However, for various reasons this approach will not scale for
XACML 3.0, so something needs to be done.
Looking at the implementation of the mappers, which is described
in the OpenAz Mapper Tutorial:
http://openaz.svn.sourceforge.net/viewvc/openaz/branches/RB-1.2/openaz/test/doc/org/openliberty/openaz/pep/package-summary.html#tutorialmappers
one will find that a single mapper can map multiple object types, as
well as mapping to different categories.
Also, a mapper, typically tests for Category based on the AzCategoryId of
the AzEntity<T> passed into it, so it really has no hard dependency on the
parameter order of the pepapi call. For an example see the impl associated
with the SimpleJavaPermissionMapper:
http://openaz.svn.sourceforge.net/viewvc/openaz/branches/RB-1.2/openaz/test/doc/org/openliberty/openaz/pep/SimpleJavaPermissionMapper.html
With the above analysis in mind for background, please consider the following as
a proposed approach for addressing these issues:
The general approach is to start by covering all the possibilities using
a standard nested loop for:
- the objects passed to PepRequestFactory.*newPepRequest(<objects>)
- the list of Categories supported by the current environment
- the list of mappers configured for the current environment
Such a loop might look like the following, and be used as the main body
of the newPepRequest calls:
Set<AzEntity<T>> azEntities = azReqCtx.createAzFullEntitySet(); // a new call
Set<JavaObjectMapper> objectMappers = pepReqFactory.getMappers();
Set<Object> objects = objects-from-newPepRequest-call;
Iterator<Object> itObjects = objects.iterator();
while ( itObject.hasNext() ) {
Object o = itObjects.next();
Iterator<AzEntity<T>> itEntities = azEntities.iterator();
while ( itEntities.hasNext() ) {
AzEntity<T> azEntityT = itEntities.next();
Iterator<JavaObjectMapper> itObjectMappers.iterator();
while ( itObjectMappers.hasNext() ) {
JavaObjectMapper objectMapper = itObjectMappers.next();
if (objectMapper.canMapObject(o)) {
objectMapper.map(o,azEntityT);
}
}
}
}
The above code segment should:
- call every mapper
- for every object
- for every category.
As with the current impl, if a mapper does not support an object type,
then a preliminary call to canMapObject(<object>) will enable elimination
of those cases.
Basically, when the mapper is called, it has the object to map and the
AzEntity<T> for the specific category, T, that it needs to map the object
into.
Conclusions:
The proposed approach should address the following:
- it should remove the dependency on the ordering of the
objects in the original call to newPepRequest to determine
the Category that the object should be mapped to. - it should eliminate any need for category-oriented objects,
which depend on named prefixes, such as Subject, Resource,
Action, and Environment.
These can all be replaced with a single "AzEntity" prefix, which
will cover them all plus any others. - It should reduce the number of newPepRequest calls, which
currently really only provide "convenient" variations in the
ways the parameters can be submitted, all of which should
be enveloped within this approach - It may also be usable for the bulkPepRequest calls, simply by
providing a Set<specific-class> as one of the entries in the
top level Set<Object>. i.e. if a Set is a parameter, then it can
be regarded as a multiplier on the Categories to which it
applies, by providing one entry for each non-duplicated value
of a particular Object.
We also recognize that this approach, in and of itself, may not solve
"all" the issues that may be implied by some of the 3.0 flexibility.
For example, in your use case, you pass a "Person" object both for
user from which subject attributes will be obtained, and a "Person"
object for the co-worker to whom the user's duties will be delegated,
maybe called the "delegatee".
From the use case descr, we can assume that the Manager ID of
both Person objects can be tested to verify the user and delegatee
are team members on the same team w same manager.
One possible approach would be to pass a "binary object", which is
a wrapper for the two person objects. For example, if there was
a Delegation object w methods
- Delegation.setUser(Person user) and
- Delegation.setDelegatee(Person delegatee)
Then the Mapper can apply the appropriate category to each person object.
For example when it is called w AzEntity<AzCategoryIdAccessSubject>,
it will pull the attrs from the Person p = Delegation.getUser() method.
And when it is called w AzEntity<AzCategoryIdDelegatee>, it will
pull attrs from the Person p = Delegation.getDelegatee() method.
It seems to me that we can most effectively approach this problem
space if we assume the general mechanism proposed above that
will generalize and simplify the current parameter passing model.
Then within that model, we can consider possible solns that require
additional strategy beyond the general parameter passing model.
Let me know if this helps move things along.
Thanks,
Rich
On 4/4/2013 10:50 AM, Kothari, Darshak wrote:
Hi Prateek, Hal & Rich,
As discussed in our last bi-weekly call, below is the use case we need to ensure pepApi can handle for XACML 3.0.
Use Case: Same Java Class to be mapped differently depending on the custom category it represents for a given request
Policy Rule: User can only delegate his/her duty to one of his/her team members (person that has same manager as user’s manager)
Java Domain class that represents user and co-worker is person that has following attributes:
ID
First Name
Last Name
Manager ID
Policy Uses following 4 attributes:
urn:oasis:names:tc:xacml:1.0:subject:subject-id
urn:oasis:names:tc:xacml:1.0:subject:manager-id
abc:xacml:3.0:delegate:manager-id
urn:oasis:names:tc:xacml:1.0:action:action-id
Sample request will require to pass instance of Person class for the user (representing subject attributes), Instance of Person class for co-worker (Representing “abc:xacml:3.0:delegate” category) and action “Delegate Duties”.
In this case object of type Person that represents Subject will have its attribute “ID” mapped to XACML attribute “urn:oasis:names:tc:xacml:1.0:subject:subject-id” and “Manager ID” mapped to “urn:oasis:names:tc:xacml:1.0:subject:manager-id”.
Object of type Person that represents co-worker/abc:xacml:3.0:delegate will need “Manager ID” attribute mapped to “abc:xacml:3.0:delegate:manager-id”.
Above User case requires need for the PEP api to be able to specify association of java object (Not Class) to category/Categories. How can we accomplish this use case with current pepApi? Do we need to extend pepApi to support such use case with XACML 3.0?
In XACML 2.0 it is not an issue as argument position is used to map java object to specific categories (eg. Subject, Resource, Action, Environment)
Thanks,
Darshak
This communication is for informational purposes only. It is not intended as an offer or solicitation for the purchase or sale of any financial instrument or as an official confirmation of any transaction. All market prices, data and other information are not warranted as to completeness or accuracy and are subject to change without notice. Any comments or statements made herein do not necessarily reflect those of JPMorgan Chase & Co., its subsidiaries and affiliates. This transmission may contain information that is privileged, confidential, legally privileged, and/or exempt from disclosure under applicable law. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information contained herein (including any reliance thereon) is STRICTLY PROHIBITED. Although this transmission and any attachments are believed to be free of any virus or other defect that might affect any computer system into which it is received and opened, it is the responsibility of the recipient to ensure that it is virus free and no responsibility is accepted by JPMorgan Chase & Co., its subsidiaries and affiliates, as applicable, for any loss or damage arising in any way from its use. If you received this transmission in error, please immediately contact the sender and destroy the material in its entirety, whether in electronic or hard copy format. Thank you. Please refer to http://www.jpmorgan.com/pages/disclosures for disclosures relating to European legal entities.
_______________________________________________
OpenAz mailing list
OpenAz@lists.openliberty.org
http://lists.openliberty.org/mailman/listinfo/openaz
This email is confidential and subject to important disclaimers and conditions including on offers for the purchase or sale of securities, accuracy and completeness of information, viruses, confidentiality, legal privilege, and legal entity disclaimers, available at http://www.jpmorgan.com/pages/disclosures/email.