Background
Update: The API has been extended to apply to Evaluations as well as Entities.
Update: The API has been extended to apply to Teams. See Teams
Update: We allow updating of Access Requirements by the ACT. We allow Access Requirements to apply to Folders as well as Files. Entities inherit any access restrictions applies to Folders which contain them.
Update: We add inheritance of access requirements: Each entity inherits the access requirements of its ancestors (e.g. the Folder(s) containing a given File).
IRB-approved versions of all of the 'data access documents' :
Summary:
- Data layer access in Synapse requires one or more approval steps.
- In Synapse granting data access is synonymous with providing the URL to the stored data.
(This URL may have an embedded access token.)
- Currently (i.e. as of Jan. 2012), the backend Prior to this work, the back end has a representation of EULAs and of Agreements (i.e. that a particular user agrees to a EULA)
- The work flow logic for creating the agreement is embedded in the Web client, so other clients would have to maintain duplicate logic. Specifically, the web client has the following logic:
1) When a user tries to download a layer, the Web client checks whether the parent dataset has an associate EULA;
2) If there is an EULA, the web client checks whether there is an Agreement, owned by the User and referencing the dataset and EULA;
3) If there is a EULA but no Agreement, the web client prompts the User to sign the EULA, creates the Agreement, then allows the download.
- There is no provision in our permissions scheme for an "IRB ACT role" which can grant or revoke 'download permission' to a user.
...
Tier 3: (Tier 1) + (Tier 2) + User access must be requested/approved through an institutional review board (IRBAccess and Compliance Team (ACT).
Straw man design
Security Model
- A "role" is a collection of permissions. E.g. if the available permissions for an entity are Create, Read, Update and Delete, there might be an Editor role which includes Read and Update. To meet the data layer access requirements we propose to extend the current permission scheme:
1) Instead of defining permissions on an entity, we define permissions on a property within an entity;
2) Instead of granting individual permissions on an entity to a principal, we grant a role to a principal
So instead of ACL=<Entity, {<Principal, Permission>}> (where "{}" indicates a set and "<>" a tuple) we have ACL= <Entity, {<Principal, Role>}> where Role={Permission}. (Q: Is a 'role' entity specific? How do we grant access to non-property aspects of an entity?)
Under this model we can separately grant read access to a layer's basic properties (name, created date, description) and its location. Read access to a layer's location is the equivalent of download access.
Note: This 'enhanced' security model can be used in advance of creating services for defining roles: We can define the currently required roles 'in the backend' and later add services and UIs for defining new roles.
Workflow Model
One design approach, explored below, is to put the workflow sequence in an external workflow system. An alternative is to put it in Synapse.
Tier 1 Approval Process
Here the user signs the Tier 1 agreement upon account creation and is added to a "Tier 1 group". The group has the Download role for all Tier 1 data layers.
"WF" refers to an envisioned workflow system which knows the approval workflows and can tell each participant what its next step is.
Version 1: Synapse interacts with User. This is not feasible since the User-Synapse interaction is synchronous while the Synapse-WF interaction is meant to be asynchronous (at least for the SWF workflow system). | Version 2: Synapse starts workflow; Worker interacts with User via email |
---|---|
| |
Below we see an alternative for synchronous user interaction.
Tier 2 Approval Process
This approval requires two hurdles, the Tier 1 agreement plus a new agreement which may be specific to the requested layer. Upon approval Synapse adds the User to the Access Control List for the Layer.
The following variation has the properties that (1) interaction between Synapse and the User is synchronous, (2) there is no representation of the required workflow in the client, (3) there is no representation of the workflow *state* in the back end:
This approach is based on the pattern used by "Basic Authentication", e.g. http://httpd.apache.org/docs/1.3/howto/auth.html#basicworks
in which a request can be denied, the denial containing information about what's required for the request to be approved.
Note: the "/accessRequest" service 'knows' to check that eula 456 is signed before adding user to group 789
changed services:
GET /layer: has to check whether there is an approval process and, if so, include the final step in the rejection
new services:
/accessRequest: checks precondition; can (1) add user to group or (2) add Role to User
POST /approvalProcess: creates an approvalProcess object whose parent is a Layer and
whose content is the sequence of requests that need to be fulfilled (specific to the layer)
POST /accessRequirements: creates an object containing the requirements for adding a User
to the ACL for an entity (e.g. the user must have signed a certain EULA)
Design considerations:
System does not track the 'state' of the approval process. That's left to the client. The risk is that the process might have to start over if it fails partway, but the benefit is in simplifying the server.
How do you set up an approval process?
POST /accessRequirements
POST /approvalProcess
How do you revoke approval?
1) remove the <User, Role> from the layer's ACL (or the <Group, Role> if all the users were added to a group)
2) delete the approvalProcess and accessRequirements objects
Tier 3 Approval Process
Here we have the added complexity of an external IRB. An "IRB daemon" is added to send approval requests to the IRB and to listen for replies. The interaction with the user is asynchronous: While waiting for approval the user may do other things (though not access the requested layer). Finally she receives an email saying the request was approved.
Some open questions:
- How does Synapse know not to wait for any more steps, once it gets the final reply from WF (the workflow is not yet done)?
- When Synapse asks "next step" can it refer to a specifc workflow instance (and avoid getting an approval step for some other user)?
New/Modified Synapse Services
Request account (initiates tier 1 workflow as a side effect)
Download access request (initiates tier 2 or tier 2 workflow as a side effect, depending on the layer)
Sign tier 1 agreement
Sign tier 2 agreement
...
Design
Database
We have tables for Requirements and Approvals: ACCESS_REQUIREMENT contains the requirement information, while NODE_ACCESS_REQUIREMENT 'joins' it to the JDONODE table, saying what entities are affected by the requirement. ACCESS_APPROVAL has foreign keys to ACCESS_REQUIREMENT and principal. The first imposes a requirement for access to the node. The second fulfills the requirement, for a given principal. The requirement and approval tables have an "ENTITY_TYPE" field (populated from an ENUM) and a "SERIALIZED_ENTITY" field, a BLOB, allowing them to have variable content, so they can be used for Tier 2 or Tier 3 requirements.
Below we omit the primary key and foreign key constraints for simplicity.
Code Block |
---|
CREATE TABLE `ACCESS_REQUIREMENT` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
`ETAG` bigint(20) NOT NULL,
`CREATED_BY` bigint(20) NOT NULL,
`CREATED_ON` bigint(20) NOT NULL,
`MODIFIED_BY` bigint(20) NOT NULL,
`MODIFIED_ON` bigint(20) NOT NULL,
`NODE_ID` bigint(20) NOT NULL,
`ACCESS_TYPE` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`ENTITY_TYPE` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`SERIALIZED_ENTITY` mediumblob
)
CREATE TABLE `NODE_ACCESS_REQUIREMENT` (
`NODE_ID` bigint(20) NOT NULL,
`REQUIREMENT_ID` bigint(20) NOT NULL,
PRIMARY KEY (`NODE_ID`, `REQUIREMENT_ID`)
)
CREATE TABLE `EVALAUTION_ACCESS_REQUIREMENT` (
`EVALUATION_ID` bigint(20) NOT NULL,
`REQUIREMENT_ID` bigint(20) NOT NULL,
PRIMARY KEY (`NODE_ID`, `REQUIREMENT_ID`)
) |
Code Block |
---|
CREATE TABLE `ACCESS_APPROVAL` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
`ETAG` bigint(20) NOT NULL,
`CREATED_BY` bigint(20) NOT NULL,
`CREATED_ON` bigint(20) NOT NULL,
`MODIFIED_BY` bigint(20) NOT NULL,
`MODIFIED_ON` bigint(20) NOT NULL,
`REQUIREMENT_ID` bigint(20) NOT NULL,
`ACCESSOR_ID` bigint(20) NOT NULL,
`ENTITY_TYPE` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`SERIALIZED_ENTITY` mediumblob
)
|
Data Access Object (DAO)
We have DAOs for AccessRequirement and AccessApproval objects. In addition to basic CRUD operations we have:
- AccessRequirementDAO.getForNode(), which returns all the AccessRequirements associated with a Node/Entity
- AccessApprovalDAO.getForNode(), which returns all the AccessApprovals associatd with a Node/Entity. This allows us to find all the users who have been given access to an entity via a single database query.
- AccessApprovalDAO.getForAccessRequirementsAndPrincipals() which returns the AccessApprovals for a given list of AccessRequirements and Principals. This method allows us to look up the approval of all the access requirements for a given node (focussing on user of interest) with a single database query.
JSON Schema
We introduce JSON schemas for the generic interfaces AccessApproval and AccessRequirement, and schemas for specific types, TermsOfUseAccessRequirement, TermsOfUseAccessApproval (for tier 2 data), ACTAccessRequirement, and ACTAccessApproval (for tier 3 data).
Services
Action | URI | Method | Request Body | Authorization |
create AccessRequirement | /accessRequirement | POST | extension of AccessRequirement.json | ACT membership |
create 'lock' Access Requirement | /entity/{id}/lockAccessRequirement | POST | N/A | CREATE or UPDATE access to the entity |
read paginated list of all AccessRequirement objects for an entity. This includes both requirements applied directly to the entity and those applied to its ancestors. | /entity/{entityId}/accessRequirement | GET | VariableContentPaginatedResults<AccessRequirement> | ALL |
read paginated list of all AccessRequirement objects for an evaluation | /evaluation/{evaluationId}/accessRequirement | GET | VariableContentPaginatedResults<AccessRequirement> | ALL |
read paginated list of all AccessRequirement objects for a team | /team/{teamId}/accessRequirement | GET | VariableContentPaginatedResults<AccessRequirement> | ALL |
Retrieve paginated list of unfufilled access requirements (of type DOWNLOAD) for an entity. This includes both requirements applied directly to the entity and those applied to its ancestors. | /entity/{entityId}/accessRequirementUnfulfilled | GET | VariableContentPaginatedResults<AccessRequirement> | ALL |
Retrieve paginated list of unfufilled access requirements (of type DOWNLOAD or PARTICIPATE) for an evaluation. | /evaluation/{evaluationId}/accessRequirementUnfulfilled | GET | VariableContentPaginatedResults<AccessRequirement> | ALL |
Retrieve paginated list of unfufilled access requirements (of type DOWNLOAD or PARTICIPATE) for a Team. | /team/{teamId}/accessRequirementUnfulfilled | GET | VariableContentPaginatedResults<AccessRequirement> | ALL |
update AccessRequirement | /accessRequirement/{accessRqmtId} | PUT | extension of AccessRequirement.json | ACT membership |
delete AccessRequirement (along with all approvals granted for the requirement) | /accessRequirement/{accessRqmtId} | DELETE | ---- | ACT membership |
create AccessApproval | /accessApproval | POST | extension of SelfSignAccessApproval.json | ALL |
ACTAccessApproval.json | ACT membership | |||
Read all AccessApproval objects for a given entity. This includes the approvals both for the access requirements applied directly to the entity and those applies to the entity's ancestors. | /entity/{entityId}/accessApproval | GET | VariableContentPaginatedResults<AccessApproval> | ACT membership |
read all AccessApproval objects for a given evaluation | /evaluation/{evaluationId}/accessApproval | GET | VariableContentPaginatedResults<AccessApproval> | ACT membership |
read all AccessApproval objects for a given team | /team/{teamId}/accessApproval | GET | VariableContentPaginatedResults<AccessApproval> | ACT membership |
delete AccessApproval | /accessApproval/{accessApprovalid} | DELETE | -- | ACT membership
|
Web UI
When a user clicks Download on the page for a Data object having a Terms of Use access requirement, they are presented with a dialog showing the text from the access requirement, as shown below. If they accept the terms, then an access approval is created and the Download link is presented.
When a user clicks Download on the page for a Data object having an ACT access requirement, they are presented with a dialog showing the text from the access requirement, as shown below. Once they contact the ACT team, someone from the team may create the approval object on their behalf, after which they may download the Data without encountering the dialog.