Version 0.7
Access Control Lists
Proposal for Access Control Lists in CMIS

04/05/2009

Versions

Version / Authors / Date / Changes
0.1 / Paul Goetz, SAP / 12/09/2008 / document created
0.2 / Florian Müller, Open Text
Jens Hübel, Open Text
Viktor Gavrysh, EMC
Martin Hermes, SAP
Paul Goetz, SAP / 12/16/2008 / completely restructured
0.3 / Paul Goetz, SAP / 12/18/2008 / motivation added, minor changes,
maps for required extend permission per operation added
0.4 / Paul Goetz, SAP / 02/18/2009 / adapted to findings from CMIS Faces2Face 28/01/2008, extended permission model removed
0.5 / Paul Goetz, SAP / 03/19/2009 / included proposals from Viktor Gavrysh, EMC
0.6 / Paul Goetz, SAP / 03/27/2009 / Principal as structure with optional attributes (e.g. type), addACEs and removeACEs combined to applyACEs
0.7 / Paul Goetz, SAP / 04/05/2009 / reworked to reflect input from Oracle, references to CMIS specificiation now updated to v0.6

Contents

Contents

Introduction

Recap: Security In CMIS Specification 0.5

ACL Design objectives

Relation to Other Standards

General Concepts

Overview of ACLs

Data Model

Discovering ACL Capabilities

Object Services

ACL Services

Checking Privileges

Changes to the Specification

Required permissions per operation

Overview

Object Service

Repository Service

Navigation Service

Multifiling Service

Discovery Service

Versioning Service

RelationShip Service

Policy Service

Introduction

While the CMIS specification contains a a generic policy model, this proposal is about Access Control Lists as a specific optional service.

Recap: Security In CMIS Specification 0.6

Version 0.6 of the CMIS specification draft contains a concept for policy objects (see Section 2.6 Policy Object). Access to certain aspects of an object can be restricted by a policy.

Policies – like other primary entities of the CMIS specification – are typed, have an object ID and have properties (see General Concepts below).

A policy is created using theObjectService’screatePolicy method. Input for this method is a description of the policy (name, type, properties, etc.), output is an IDof the created policy instance. Providing this ID, a policy can be applied to a controllable object (applyPolicy), removed (removePolicy), or retrieved from an object (getAppliedPolicies) via the Policy Service.

A controllable object can have zero or more policies applied. Not having a policy applied means that there exist no restrictions in accessing the object.

ACL Design objectives

The basic requirements for a ACLs are the following three tiers:

Tier 1 –Unified Search
This requires the ablity to discover who is allowed to read the content and properties of a document or folder: The data from a CMIS repository is to be indexed by an external search engine – to filter relevant results for a given user efficiently, the search engine needs to add index information about “who is allowed to read the search result”.

Tier 2 –Reporting Permissions
Tier 1 + the requirement to distinguish different permissions, like WRITE or DELETE. This is required when a user tries to figure out, with whom he can share documents or folders.

Tier 3 – Management
Tier 2 + the requirement to modify the ACL for a document or folder.The use case this proposal tries to address is focused on a collaborative scenario, where a user tries to extend a given ACL to allow other users (e.g. his team) to get access to a document or folder.

Therefore, we tried to classify applications and their security requirements intothree szenario types:

Scenario 1 – Collaborative applications – like Collaborative Content Creation, Portals, Mashups –where an end user needs to be able to control the permissions to be applied to documentsor folders at runtime at least to allow content sharing and collaboration.
E.g. “My working drafts for the documentation should only be editable by my co-workers John and Mary, be visible to my team, but they must not to be seen by someone else outside the team”.

Scenario 2 – Background tasks – like an archiving application – where a developer has to specify the permissions to be applied at designtime.
E.g. “Documents moved by the archiving service become read-only, except for the special group ‘archive admin’”.

Scenario 3 – Business applications– like attaching the scanned images of an invoice to ERP data –will require application specific security.
E.g. “Invoices with a total of more than 1Million EURO should not be visible by anyone who’s not a member of the controlling team and has doesn’t have at least a clearance level 2”.

Scenarios 1 and 2 (Collaborative applications and background tasks) relate to the three tiers outlined above. E.g. the unified search indexing (scenario 2) would correspond to Tier 1, a collaborative application (scenario 1) would most likely correspond to Tier 3.

Szenario 3 is considered as being out of scope for ACLs - we assume that policies are a better choice to handle this kind of specific security constraints, especially when security constraints are shared between several objects.

Policies are intended to express security constraints more on an enterprise level and that are shared by several objects (e.g. “job references in folder EMEA can be read by members of the HR department in the EMEA region only”). ACLs are intended as an additional mechanism for collaborative scenarios.

This results in the following requirement:

A developer should be able to work with permissions for CMIS objects in an interoperable manner at designtime, without additional assumptions about the repository be used at runtime.Therfore, ACLs imply at least a basic semantic in terms of “who is allowed to do what” – in the scenarios above, the who is known by the application, so this proposal will focus on the what (the permissions).

As outlined above, one of these use cases for a szenario-2-type application is “Unified Search”, which would need a defined semantic for READ.While indexing, the ACL entries for READ permissions are indexed. When searching, the search query could be extended to something like WHERE … AND currentuser IS IN read-acl-entries).

There are basically two different options how the semantics of permissions can be made predefined for the application: Either there is one permission model already predefined by CMIS (the applications and the repositories would have to map their permissions to that “standard”, requiring potentially 1:n mappings for the applications and 1:m mappings for the repositories). Or the mapping of the permissions is done for potentially every combination of application and repository (resulting in n:m-mappings, either to be handled by the application or the repository).

The second options allows for more flexibility – but requires more mappings and therefore more administrative effort than the first option, so this proposal tries to provide a minimal approach for the first option. But as there are different requirements for the different types of applications yet, we will have to support both options.

Therefore we suggest to divide the requirements for handling policies and permissions in three different levels (related to the scenarios and the three tiers above):

  • Level 0 =Policies only
     security defined via generic policy (for business applications, szenario type 3 above)
    for interoperability this will require a notation for specifying generic policies in an interchangeable format (e.g. using XACML)
     out of scope for this proposal
  • Level 1 = ACLs with a flexiblemapping of permissions per repository
     security defined via ACL, where permissionsare unknown to the application and have to be understood by the user (for end user applications, szenario type 1 above)
     will require mappings either on the application or the repository side, thus requires at least the capability to discover the available permissions
     will be refered to as Level-1-ACLs or Generic ACLs
  • Level 2 =ACLs with a fixed mapping of permissions
     like Level 1, but permissionsare known to the application (e.g. unified search or application specific permissions, szenario type 2 above)
     requires mappings on the repository side, the known permissions are predefined by CMIS
     will be refered to as Level-2-ACLs or CMIS-Definedor BasicACLs.

As the ACEs of an ACL define who is allowed to do what, two additional assumptions:

  1. Regarding the who:
    We assume that all the systems share a common understanding of the principalsto be checked. In an enterprise or intranet scenario, this is more likely to be the case, as a central LDAP or other kind of directory service will most probably be available. For extranet/internet scenarios, we assume that more generic authentication standards will be relevant (in the worst case, the CMIS consumer would have to do the user mapping by means beyond the scope of CMIS).
     We assume that principals are known to both, consumer and provider – thus user/group discovery is not within the scope of this document.
  1. Regarding the what:
    We assume that ACLs are applied to folder- and document-like objects only, and that checks against ACLs are performed for operations on those objects only.
    We assume that ACLs are appropriate for the basic object types folder and document (not for relationship, policy) as this concept is known from existing file system implementations – other CMIS objects would have to be secured by policies then.

Relation to Other Standards

Content Repository for Java – JSR 283

Reference:

As we expect that JCR might serve as a local Java API for the CMIS protocol (either for consumers – using JCR to access a CMIS provider – or for providers – using CMIS to expose a JCR repository), the ACL concepts proposed by CMIS should be mappeable to JCR:

Level 0 (Policies) can be mapped to the JCR’s AccessControlPolicy objects and handling of policies can be mapped to theAccessControlManager’s get…/set…/delete… methods (while CMIS’ addPolicy could be mapped to a getApplicablePolicies on a specific system path, or createing a node with a specific structure (e.g. using XACML)).

Level 1 (Generic) ACLsare not covered by JCR –would have to be mapped to JCR policies as well.

Level 2 (Basic) ACLs should be mappable, by taking care that the semantics defined in this proposal are compliant with the JCR’s standard privileges jcr:read, jcr:setProperties, jcr:addChildNodes, jcr:removeChildNodes, jcr:write, jcr:getAccessControlPolicy, jcr:setAccessControlPolicy, and jcr:all. See Permissions below.

HTTP Extensions for Distributed Authoring – WebDAV

Reference: and

As we assume that a CMIS providers might also expose its repository via WebDAV, the proposed ACL concept should be mappeable to WebDAV.

Level 0 (Policies) are not covered by WebDAV.

Level 1 (Generic) ACLs are pretty much the same as specified in WebDAV, using specific privileges (aka permissions).

Level 2 (Basic) ACLs use a simplified set of privileges which can be mapped as well. See Permissions below.

XACML

Reference:

XACML is much more generic and flexible then the proposed ACLs. As outlined above, we consider more generic security handling and policies as being out of scope for this proposal.

Thus –although XACML might become relevant when getting into more details for policies or the discovery of permissions – we won’t take XACML into account for this proposal.

General Concepts

To provide an overview about the general concept and to provide a more formal naming, the following sections use a Java style pseudo code to illustrate the proposal.

The CMIS specification currently defines the following object hierarchy:

A [CMIS] Object is either a Document, a Folder, a Relationship or a Policy. All of them may have Properties assigned, while only documents may have a content (i.e. can be a Contentallowable) and are Versionable. Folders and documents are Queryable and Fileable. Relations can reference to a a Sourceobject and a Targetobject. Documents, folders, relationsships and policies might be Controllable which may be controlled by zero or more policies.Vice versa, a policy may be assigned to zero or several controllables.

ACLs shall be added as a specific object type, thus the propsed changed object hierarchy would look like:

Only Documents and Foldersmay be ACLControllable.AnACLControllable may then be controlled by one ACL (can have an ACL assigned). If no ACL is assigned, no permission is granted (unless specified differently by a policy applied to the object).

An ACLin turn is implicitly assigned to its object – an ACLis nota [CMIS] Objecton its own, an ACL depends on the [CMIS] Object it belongs to (like a Property, but in contrast to Policies).

Objects may have an ACL assigned – but only if they are “tagged” as being ACLControllable.

Overview of ACLs

Access Control Lists

An Access Control List (ACL) is just a list of Access Control Entires (ACEs)

public List<AccessControlEntry>AccessControlList;

Access Control Entries

An Access Control Entry (ACE) specifies a permission and a principal.

public class AccessControlEntry {

public Principalprincipal;

public StringPermissionName;

public Boolean isDirect;

}

This proposal restricts to positive ACEs. Thus, no negative flag is required.

See alsoPermissionsbelow for more details on the PermissionName.

Since an ACE is specified by it’s prinicpal’s ID and the permission’s name, “changing” an ACE means either removing an existing ACE (PrincipalID,PermissionName) or adding a new ACE (PrincipalID,PermissionName).

The isDirect flag indicates that the ACE is applied to the document or folder itself (isDirect=TRUE), or is derived or inherited from another object (isDirect=FALSE). The isDirect flag is provided just for reporting purposes when the ACL is retrieved from the repository – it is not relevant (can be omitted) when a client specifies an ACE to be applied to an document or folder and will be ignored by the repository.

For more details, see Discovering ACL Capabilities and Applying ACES below.

Principals

A principal represents either a single user, or a set of users – this can be a group, or some other notion like a “role”. A principal might have some additional (optional) attributes:

public class Principal {

public String principalId;

public HashMap<String,String> attributes;

}

The attributes are optional key-value-pairs which can be used to add more information about the principal, e.g. some additional type information (e.g. “type”=”user” or “datasource”=”LDAP”).

While the principal ID is just an opaque string to the client, we assume that every system has some kind of user management, which is able to retrieve the relevant information from the central LDAP or directory service for a given principal ID:

public class UserManagement {

public SecurityPrincipal getPrincipalByID(String id);

}

For this usermanagement objects, we assume that at least checks for equality are available:

public interface SecurityPrincipal {

public String getPrincipalID();

public boolean equals(SecurityPrincipal user);

}

For a set of users, we assume that at least a check to determine if a given user is contained in that set (direct or indirect in a subset contained in the set) is available:

public interface SecurityPrincipalSet extends SecurityPrincipal {

public boolean contains(SecurityPrincipal user);

}

Permissions

As outlined in the Design Objectives, the goal for this proposal is to specifiy an interoperable permission model – at least providing mechanisms to discover the “meaning” of the permissions provided by the repositories; or if possible to specify a predefined set of permissions.

The absolute minimal permission to discover is Read (see Tier 1 and the Unified Search use case above).

For Tier 2 and 3 at least this three permissions All, Write, Read should to be exposed by a repository as a minimal set:

  • All:includes all other permissions.
    (corresponding to jcr:all or DAV:all)
  • Write: permits to delete the object, write properties and content of the object, as well as filing or unfiling (plus Read, see below).
    (corresponding to jcr:write+jcr:setProperty+jcr:addChildNodes+ jcr:removeChildNodes or DAV:write)
  • Read: permits to read properties and content of the given object.
    (corresponding to jcr:read or DAV:read)

As this are the most basic Permissions, which might be changed to more specific ones in the future, the proposal is to name them accordingly: CMIS.BasicPermission.All, CMIS.BasicPermission.Write, and CMIS.BasicPermission.Read.

This proposal restricts to positive ACEs. Thus, a Denypermission is not required, as this is the default permission for a principal not being listed in an ACE (direct or via PrincipalSet, see below).

For an application consuming CMIS ACLs, it might be helpful to distinguish between the different “levels” of permissions (see Design objectives above), so we propose the following naming.

A Level-1-ACLor GenericACL has ACEs with repository specific permission assigned – i.E. for a GenericACL there may be several ACEs with PermissionNamenot in { CMIS.BasicPermission.All, CMIS.BasicPermission.Write, CMIS.BasicPermission.Read } (but it also might support ACEs with these specified CMIS permissions, if the repositories semantics match those of the CMIS permission).

For a Level-2-ACL or BasicACL, all the ACEs’ PermissionName are in { CMIS.BasicPermission.All, CMIS.BasicPermission.Write, CMIS.BasicPermission.Read } and match the specified semantics.

E.g. an ACL like {(john: CMIS.BasicPermission.All), (mary: bind), (mary:unbind), (mary:write)} would be a GenericACL, since bind- and unbind-permission would not be specified by CMIS.
An ACL like {(john: CMIS.BasicPermission.All), (mary: CMIS.BasicPermissionWrite)}
would be a BasicACL then.

ForBasicReadACL, only CMIS.BasicPermission.Read is allowed as PermissionName in the ACEs.

If no ACL is assigned to an object, all permissions are granted by default (unless overwritten by specific policies) – this is similar to policies (defaulting to full access for an object if no policies are applied).

As this proposal is about using positive ACEs only, access is restricted according by ACL as follows:

If an ACL exists:

If an ACE exists where the given where the given user matches*) the ACE’s principal entry, access is granted.

else (no ACE exists, where the given user matches*) the ACE’s principal entry), access is denied.

else (if no ACL exists):

If polcies exist, access is granted or denied according to these policies.

else (no policies exist), access is granted.

*)Matching means something like

ace_principal = UserManagement.getPrincipalByID(ACE.getPrincipalID()); matches = ace_principal.equals(user)
|| ((ace_principal instanceof SecurityPrincipalSet)
& ((SecurityPrinicpalSet)ace_principal).contains(user));

Data Model

A new optionalenumACLControllable needs to be added to the “Basic Object Types”, which may have one of the following values for Documents and Folders (and is not existend for Relations and Policies): GenericACL, BasicACL, or BasicReadACL (others might be added later).