The standard access control policies supplied with the GRIA basic applications package are suitable for an environment where the submitter of a job owns all inputs and outputs. In this tutorial we consider a more complex scenario, where different organisations each contribute input data to a job without exposing their data to the other partners.
Two organisations wish to run a job without letting the other see their part of the input or output data.
The diagram below shows a scenario in which two organisations need to collaborate to run a job. They each provide some of the input data for the job, and they both see some of the output data. However, neither party should be able to see the other's data. An example of this type of situation would be safety testing the interactions between two products which are still under development.
If one organisation doesn't mind the other seeing its data, the solution is simple. Bob creates a job, gives Alice write access to Input-A and read access to Output-A and then runs the job. How to do this is explained in the Delegating access to a data stager section of the client user guide.
If Alice needs to be sure that Bob won't be able to read her data then things are slightly more complicated. The trick is for Bob to put Input-A into a state where he can't read it and where he can't change the access control rules any further. Alice can check the access control rules and verify that this is the case before uploading her data.
The default data stager policy that comes with GRIA 5.1 is not sufficient for this, because it does not allow delegation of the 'manager' role. Alice needs this role in order to check that Bob doesn't have it. Therefore, the trusted third party must first modify their data stager policy to allow a 'manager' to add, remove and list manager roles:
- Go to the web administration pages.
- Click on Access control in the navigation bar at the top of the screen.
- Select http://www.it-innovation.soton.ac.uk/grid/resource/data and undeploy it.
- Replace it with a suitable policy, for example: new-data-policy.xml.
Alice and Bob can now run jobs as follows (the examples show Java code, but this can also be done using the Swing client):
- Alice creates a MatchPattern which will match her and sends it to Bob. Typically, this is just Alice's X.509 certificate along with the CA certificate that signed it:
MatchPattern isAlice = new MatchPattern(alice, CAofOrganisationA);
- Bob creates the job, which automatically causes the inputs and outputs to be created:
Job job = jobService.createJob(JOB_URI, "My shared job");
- Bob adds rules granting Alice ownership of the job, Input-A and Output-A (the inputs are actually owned by the job, so we give Alice the manager role instead):
job.addPolicyRule(new PolicyRule(isAlice, "owner", PolicyRuleType.SUFFICIENT));
job.input("Input-A").addPolicyRule(new PolicyRule(isAlice, "manager", PolicyRuleType.SUFFICIENT));
job.output("Output-A").addPolicyRule(new PolicyRule(isAlice, "manager", PolicyRuleType.SUFFICIENT));
- Bob removes the default rules granting him access to Input-A and Output-A:
job.input("Input-A").removePolicyRule(bobIsManager);
job.output("Output-A").removePolicyRule(bobIsManager);
- Bob tells Alice the EPR for the job.
Alice now needs to check that things are set up correctly before uploading her data:
- Alice checks that the address in the EPR is that of the trusted third party's job service.
- Alice fetches information about the job:
JobStatus status = job.checkJob();
if (!JOB_URI.equals(status.getApplicationURI())) throw new Exception(...);
PolicyRule[] inputRules = job.input("Input-A").getPolicyRules();
PolicyRule[] outputRules = job.output("Output-A").getPolicyRules();
- Alice must ensure that the only rules are the ones she asked Bob to add:
PolicyRule expected = new PolicyRule(isAlice, "manager", PolicyRuleType.SUFFICIENT);
if (inputRules.length != 1 || outputRules.length != 1) throw new Exception(...);
if (inputRules[0].compareTo(expected) != 0) throw new Exception(...);
if (outputRules[0].compareTo(expected) != 0) throw new Exception(...);
- Finally, she uploads her data and runs the job (or asks Bob to run it; they both have permission):
job.submitJob(...);
Both parties can monitor the progress of the job. When it completes, they can each download from their output stager.
Alice knows that Bob can't read Input-A or Output-A because:
- There is no rule granting Bob read access to either resource, and
- There is no rule granting Bob permission to change the rules.
Likewise, there are no rules on Input-B or Output-B allowing Alice to do anything.
In this scenario, one of the partners needs to check their part of the output before allowing the other party to read theirs.
In this section we extend the previous scenario with a new requirement: Alice is not permitted to see her part of the output without Bob's permission. This is typically the case if Bob will need several iterations of the job to get the output correct. Once Bob is happy with the results, he will allow Alice to see hers. Bob still never actually sees Alice's results, however.
The challenge here is to allow Bob to grant Alice read access to her results, without also allowing Bob to give himself read access. We can do this by introducing a new role and a couple of new PBAC states: empty-locked and full-locked. The sequence will now look like this:
- Bob creates the job as before.
- Bob adds a rule to Output-A granting himself the unlocker role and puts it into the empty-locked state.
- Bob then transfers control of the manager role to Alice, as before.
- When the job finishes, Output-A moves from empty-locked to full-locked. No-one can read the data while it is locked.
- Bob checks Output-B. When he is happy with the results, he unlocks Output-A, allowing Alice to read it.
As it happens, the data stager state model already has some locked states, but it uses them to prevent changes to the contents (i.e. as a
write-protect feature). Ideally, we would add some different states and new operations to lock and unlock. However, the data service doesn't allow us to add extra operations so we're going to change the behaviour of the existing
lock and
unlock
operations instead.
We need to ensure that:
- When a stager is locked, no-one can read it until it is unlocked.
- When a stager is locked, no-one else can be granted the unlocker role (otherwise Alice can just make herself an unlocker).
Here is a suitable policy, which you can upload as before: lockable-data-policy.xml.