Security
Authentication and JAAS
Authentication is the act of verifying a user's identity based on credentials they present. Authentication in the Content Engine functions differently, depending on how a request arrives at the server. The Content Engine server accepts incoming requests over two transport protocols: Enterprise Java™ (EJB) and Content Engine Web Service (CEWS) transports.
The Content Engine resides within a Java Platform, Enterprise Edition (Java EE) application server, and uses the Java Authentication and Authorization (JAAS) standard as the basis for authentication. The JAAS programming model is a standard Java framework that manages authentication and authorization. FileNet P8 Platform uses JAAS to perform authentication, but not authorization. (Authorization is performed by FileNet P8 Platform code.) Authentication occurs between a Java EE client application and Java EE application server, and one or more JAAS LoginModules.
Authentication over the EJB transport is handled by using the JAAS framework. FileNet code is not involved in this authentication process. Callers are authenticated by the Java EE application server before they can access the EJB layer. A JAAS Subject is created that contains the credentials of the authenticated user, and the Subject is returned to the client application.
Authentication over the CEWS transport is handled differently and FileNet code is involved in the authentication process of a web service-based client. The WS-Security standard defines how security credentials are formatted and inserted in a web service request. When a web service request arrives in the Content Engine server, the CEWS listener extracts the WS-Security header and based on its contents, performs a JAAS login. If this JAAS login is successful, the CEWS listener passes the request to the Content Engine EJB layer within the EJB container.
The Content Engine supports the WS-Security Username/Password Token profile, and the Kerberos profile. However, to be able to use binary security tokens as defined in the WS-Security standard, FileNet P8 Platform provides a pluggable authentication mechanism: the Content Engine Web Service Extensible Authentication Framework (WS-EAF). WS-EAF consists of a set of conventions for writing a custom JAAS LoginModule that is able to interact with the FileNet P8 CEWS listener to obtain the credentials that are present in a WS-Security header of an incoming request packet. For more information, see the WS-EAF Developer's Guide. This document contains details and code samples for extending the framework.
LoginModules
Authentication occurs in JAAS LoginModules, which are specified in a JAAS configuration file. The use of JAAS configuration files allows authentication to be dynamically configured for both clients and servers in a Java Platform, Enterprise Edition environment.
Generally, a Java client program that accesses the Content Engine uses the installed JAAS configuration file for the relevant application server (such as jaas.conf.WebSphere or jaas.conf.WebLogic). A client can also choose to use jaas.conf.WSI. In this case, the definition of the FileNet P8 stanza in the configuration file uses the CEWS transport, rather than the default EJB transport.
The configuration file contains one JAAS configuration (stanza), and within each JAAS configuration (stanza) is a list of LoginModules. Each entry in the list specifies the fully qualified name of a Java LoginModule class, a flag (set to Required, Optional, Sufficient, or Requisite), and options for that LoginModule. The following stanzas are supplied:
- FileNetP8
This configuration is used by all stand-alone (thick) Java clients. For compatibility, this stanza can also be used by servlet-based Java clients, although the FileNetP8Server stanza is now supplied for this purpose. When the jaas.conf.WSI file is used, this stanza specifies the CEWS transport, rather than the EJB transport (specified in this stanza for the jaas.conf.<app server> files).
- FileNetP8Engine
(Not for client use.) This configuration is used internally by the CEWS transport handling processes, and must not be used by clients. You can only modify this stanza only if you are using WS-EAF.
- FileNetP8Server
This configuration is used by servlet-based clients that run within an application server container.
- FileNetP8WSI
This configuration can be used by Java clients (stand-alone or within a servlet) that need to use the CEWS transport, rather than the default EJB transport. Another way to accomplish this is to use the jaas.conf.WSI sample configuration file with the FileNetP8 configuration.
- FileNetP8KerberosService
(Not for client use.) This configuration is used internally by the CEWS transport handling processes, and must not be used by clients.
There are a number of other stanzas (such as Credentials, ReceivedCredentials, HttpCredentials) that are required by the server while it handles the CEWS transport. These stanzas can be removed safely from a JAAS configuration file that is used by a client.
When a client application attempts to authenticate, the JAAS framework dynamically determines the set of LoginModules to invoke based on the contents of the configuration file. Authentication succeeds only if all LoginModules marked either Required or Requisite succeed. If no Required or Requisite LoginModules succeed, then at least one Sufficient or Optional LoginModule must succeed.
A set of sample JAAS configuration files are supplied for you to use to set up your own configurations. The FileNet P8 installation program stores these sample files in the \config\samples subdirectory of your Content Engine installation directory. By default, the installation directory for the Windows version of Content Engine is C:\Program Files\IBM\FileNet\ContentEngine, and for the non-Windows version is /opt/IBM/FileNet/ContentEngine. Each application server has slightly different requirements, and the files are named for the supported application server environments: jaas.conf.WebLogic, jaas.conf.jaas.conf.WebSphere, and a special CEWS transport configuration file, jaas.conf.WSI.
Authorization
Authorization to access objects within an object store is verified after authentication occurs. Every object has its own security settings. Where multiple versions of a document exist, each version has its own security settings.
Assets
that are managed in the Content Engine and Process Engine are protected and can be
seen or modified according to a user's access rights only. Each object
has its own security, which controls a user's or group's access to
that object. An object can have several rules that govern access to
it. For example, users in GroupA might have permission only to view
the object, while UserB has permission to view and modify the object.
Each rule (also called access control) is represented by a Permission
object,
which establishes the access that is granted to a user or group (the
grantee), and contains a reference to the user or group that is assigned
the permission. For more information about users and groups, see Grantees, and to
the reference help provided for the User
, Group
, SecurityPrincipal
,
and Permission
interfaces.
The access level specifies the access rights, such as read and write permission, held by or denied to the referenced grantee, and determines the activities that the grantee can perform on objects. A system administrator is typically responsible for establishing the type of access that is granted to users and groups.
A Permissions
collection represents the full set of access control entries
(ACEs) associated with an object and forms the object's Access Control List (ACL). To grant rights,
call methods on the AccessPermission
object to set the appropriate property, add
the permission to the object's permissions list, and then save the modified
AccessPermissionList
collection on the object. Removing access rights is a similar
process. For a code sample that illustrates how to set access rights, see
Working with Security.
Access to an object can also be affected by properties that are set at the Content Engine level. Notably, the settings of the ModificationAccessRequired and TargetAccessRequired properties can further restrict a user's access to, and ability to modify, an object's custom properties and its object valued properties. You cannot set or retrieve the values of the ModificationAccessRequired and TargetAccessRequired properties by using the Content Engine APIs. However, depending on the requirements of your application, you might need to understand the effect that these properties can have on object access. For more information, see Property modification access and Target access required.
Within each ACE is a security identifier (SID). The SID is a globally unique value that identifies a security principal (a user or group to which Content Engine grants or denies object access).
IBM® FileNet P8 uses the LDAP directory server's built-in attributes as stable and unique user or group identifiers. The unique ID is converted to a SID format to be stored in the object's ACL. After a user or group is created in the LDAP server and the SID attribute value is populated, the value must not be changed. For more information about the SID and to see the list of default SID attributes for LDAP servers that are supported by Content Engine, see Security identifier (SID) in the What are access rights? topic
Because most of the default SID attributes are generated by the LDAP server itself during user or group creation and are machine-dependent, complications can arise during backup, restore, moves, and duplication of the underlying LDAP server and hardware. To introduce configuration flexibility and to avoid problems that are associated with a fixed SID attribute, you are not restricted to the default attributes provided by the LDAP server when you configure the SID. Instead, you can choose other LDAP attributes, such as Distinguished Name (DN), employee number, and so on, to function as the SID.
The value of the attribute that you choose for your user and group IDs must be unique across the configured LDAP realms. Because the Content Engine authorization process uses the attribute as the single identifier of a user or group in an LDAP repository, a non-unique value causes authorization failures. You specify the attribute through the value of the UserUniqueIDAttribute and GroupUniqueIDAttribute properties of the DirectoryConfiguration class. The values are typically the same for both properties, but it is possible to specify different values for each property if required by your design.
Currently, you are limited to using as SID attributes only those LDAP attributes that return Java String in the LDAP Java API.
Grantees
Realm
object is to retrieve lists of the
groups and users in the realm.A user account is defined to the Content Engine server by using tools that are provided by the directory service,
for example, Microsoft Active Directory, Microsoft Active Directory Application Mode (ADAM), Microsoft Active Directory Lightweight Directory Services (AD LDS),
Oracle Directory Server, Novell eDirectory, or Computer Associates (CA) eTrust. A
User
object exists in the Content Engine API as part of
the security interface that allows a particular user to access a Content Engine resource. A Group
object represents a set of user
accounts. Access rights (permissions) are assigned to individual user accounts and to the groups to
which the individual user belongs.
Security
on objects, such as folders and documents, can pertain to particular
groups. These groups, and the users and subgroups that make up the
group's membership, are typically defined and created by a system
administrator that uses tools that are provided by the directory service.
You cannot call a Content Engine API
method to create a new group or user; however, you can instantiate
a Group
or User
object that is defined
to your directory service. You can retrieve a collection of groups
and a collection of users then retrieve elements from the collections,
or you can call methods on the Factory
classes for
the type of object (group or user) you want to instantiate. You can
then call methods on the object to retrieve information about it,
such as name and ID.
How your application retrieves user and group information can affect system performance; refer to Role-Based Security for information on performance considerations.
Encryption
When password properties are stored in the Content Engine, they are encrypted by using the Federal Information Processing Standard (FIPS) Advanced Encryption Standard (AES) 128-bit algorithm with the Content Engine server’s master encryption key. The master key for encrypting and decrypting credentials is generated and stored during installation of the Content Engine software. For more information, see Content Engine Encryption for more information. Encryption information is also specified in the CEMPBoot.properties file. (For more information, see the descriptions of the CipherKeyLength, CipherAlgorithm, and EncryptedPassword CEMPBootstrap properties in the Content Engine bootstrap properties topic of the Security section of the Content Engine Administration documentation.)
The actual encryption and decryption of password values is performed on the Content Engine server, by using the Java Cryptography Enhancements (JCE) module that is present in the application server that hosts the Content Engine. The Content Engine can run in FIPS 140-2 enabled mode, but only when a FIPS 140-2 certified JCE provider is configured. To place the Content Engine in FIPS enabled mode, use the IBM WebSphere® 7.0 platform with the IBMJCEFIPS JCE provider.
Security Caching
The IBM FileNet Content Engine has numerous caches that are related to security, some that are associated with the object store and others that are associated with server security configuration. As with other Content Engine caches, most of these caches are based on a least recently used (LRU) algorithm and some also have an associated TTL (time to live). Caches have a configurable maximum entries attribute that defines the maximum number of cached entries allowed. When this value is exceeded, the least recently used elements are removed to make room for the new, more recently used elements. The TTL (if applicable) that is associated with a cache element defines the amount of time that the cached value remains before it is refreshed. TTL values are also configurable. Because characteristics of a cached element can change (for example, when the security permissions on an object get updated), cached values are refreshed periodically to provide a mechanism for those changes to take effect.
- SecurityDescriptorCache is responsible for managing (caching) security descriptors to reduce database roundtrips. This cache has only a maximum entries attribute (ObjectStore.SecurityDescCacheMaxEntries) and no TTL attribute since security descriptors never change (only new ones are added) so they never become stale and never need to be refreshed. When the maximum entries value of this LRU cache is exceeded, the least recently used elements are removed to make way for more recently used items.
- ObjectSecurityCache is responsible for managing (caching) the security characteristics
that are associated with a given object. This cache is used for security proxy support (the SecurityProxyType constant class). This cache is used when computing inherited security
and for Records Management when an object is declared as a record. Any object-valued property with
the
SecurityProxyType
set in the metadata uses this cache when security is computed for the related object. This cache has both a maximum entries attribute (ObjectStore.ObjectSecurityCacheMaxEntries) and a TTL attribute (ObjectStore.ObjectSecurityCacheEntryTTL). - MarkingSetCache is responsible for managing (caching) marking sets from the FileNet P8 . Marking sets are domain-wide resources that can be associated with objects in one or more object stores. The marking set cache has both a maximum entries attribute (ServerCacheConfiguration.MarkingSetCacheMaxEntries) and a TTL attribute (ServerCacheConfiguration.MarkingSetCacheEntryTTL). Marking sets are stored in the GCD and any refresh of the GCD refreshes all of the marking sets.
- SubjectCache is responsible for managing (caching) security principal (JAAS Subject) information. This cache is used by the server's CEWS interface to reduce the number of LDAP authentication requests the server must perform. (All CEWS requests to server processes must be performed by an authenticated user.) The Subject cache has both a maximum entries attribute (ServerCacheConfiguration.SubjectCacheMaxEntries) and a TTL attribute (ServerCacheConfiguration.SubjectCacheEntryTTL). You should always set the TTL to a value that is smaller than the configured credentials expiration time (usually an application server's configuration value).
- PrincipalCache is responsible for managing (caching) principal information. This cache stores a local copy of the mapping between information about the principal (such as its name and other properties) and the principal’s security ID. Maintaining this information in Principal cache means Content Engine does not have to retrieve the information from the authentication provider every time it needs the information. The PrincipalCache has both a maximum entries attribute (PrincipalCacheMaxEntries) and a TTL attribute (PrincipalCacheEntryTTL).
- UserTokenCache is responsible for managing (caching) user token information. This cache stores a local copy of the mapping from a security principal (a user or a group) to its list of security IDs (SIDs) used by Content Engine to authorize the principal. The list of security IDs contains the SID of the current user, the SID for each group the user belongs to (either directly, or as the result of being a nested member of the group, indirectly), and the SID of the #AUTHENTICATED-USERS built in group. Maintaining this information in UserToken cache means Content Engine does not have to retrieve the information from the authentication provider every time it needs information about a user. The UserTokenCache has both a maximum entries attribute (UserTokenCacheMaxEntries) and a TTL attribute (UserTokenCacheEntryTTL).
User and Group Caching
For performance reasons, the Content Engine keeps a cached copy of the users, groups, and realms that are returned from the database of your system's configured authentication provider. Cache refresh rates are controlled by cache configuration settings that specify a time to live (TTL) value for cached information. The default values are the following:
- For the collection of
Realms
returned by a call toEntireNetwork.get_AllRealms
: 12 hours - For a
User
orGroup
associated with a realm: 1 hour - For a
Users
orGroups
collection that is associated with a user or group: 1 hour
The consequences of caching user, group, and realm information can include the following unexpected behaviors:
- An application might continue to see an object for a user, group, or realm that was deleted since the last cache refresh. This behavior can occur when lists of users, groups, or realms are manipulated.
- An application might see an exception when it is trying to use
a recently deleted user or group as a grantee in an
AccessPermissionList
collection. - An application might not see, and therefore does not use, a recently added user, group, or realm when retrieving collections of these objects.
- Updates to user and group information (such as a change to the display name) might not be immediately visible.
Security of objects in the Content Engine is not compromised by these consequences.
Because adding and removing groups tends to happen much less frequently than adding and removing users, sites and applications that use mostly groups and not users as security grantees are less affected by the these consequences.
Integrated Logon (SSO)
Integrated logon (also known as single sign-on or SSO) is the feature whereby a user can access multiple systems after being authenticated just one time. The Content Engine server takes advantage of an earlier Windows logon to authenticate a user (that is, establish the user's identity) without requiring the user to provide credentials (such as user name and password) again for each subsequent logon.
Using the SSO support that is provided in FileNet P8 Platform , your custom applications can integrate with any SSO vendor (such as CA/Netegrity or IBM Tivoli®) that provides JAAS-based authentication on the platforms that are supported by FileNet P8 . If an SSO vendor has provided JAAS LoginModules that work with a given application server, FileNet P8 can support that single sign-on solution for Java based applications. There are limitations to this ability to integrate with SSO providers; for a complete list of limitations, see Single Sign-on Integrations via JAAS. Custom applications have the following limitations:
- JAAS-based SSO integration is only available to Java EE-based clients (clients who are able to perform a JAAS login). These clients include most browser-based clients that work with a Java EE-based presentation tier server.
- JAAS-based SSO integration does not generally extend to .NET based clients or pure web server-based clients, who are not able to directly take advantage of the JAAS integration. (For these clients, the username/password and Kerberos authentication profiles are supported.)
- JAAS-based SSO integration is only supported when the Content Engine is configured to run over the EJB transport.
For information about the requirements and configuration steps for clients that use Kerberos as the SSO provider, see Implementing Kerberos.
Object Permissions
Security for an object is specified in terms of access rights. Access rights are permissions that specify operations that the grantee (user or group) is allowed to perform on an object. Access rights are set as a bitmask, where each bit in the mask represents an access right. A grantee does or does not have a particular right, depending on whether the corresponding bit is set or not. Access rights are represented in the APIs as AccessRight constants that identify individual permissions.
A class has default instance permissions in the form of an Access Control List (ACL), a list of grantees and the access rights that each grantee has on objects of that class. An individual entry in the list, specifying a single grantee and its associated access rights, is an Access Control Entry (ACE). When a new object is created, the default instance permissions of the class are assigned to the object, unless the creating application explicitly provides its own ACL.
You can modify or replace an ACL on an object,
and any inherited permissions supplement the object's access control
entries in the ACL. For example, say that the default ACL of a document
object includes a grantee with rights to view properties and content
(AccessRight.READ_ACL
, AccessRight.READ
,
and AccessRight.VIEW_CONTENT
). You might grant the
additional permission of AccessRight.WRITE
to allow
the grantee to modify the document's properties and view its content.
To determine which access rights are required to perform common actions on Content Engine objects, see Access rights required to take actions.
Retrieving Permissions
To retrieve the basic permissions on an object, call get_Permissions
. This
method returns an access permission list with all of the grantees with permissions on the object.
Each AccessPermission
object in the list specifies a grantee (a user or group), the access rights (permissions) associated
with the grantee, and whether the grantee is granted or denied the specified access rights on the
object.
You can call get_Permissions
on most IndependentlyPersistableObject objects.
Note that the Marking
interface is the only one with a
Permissions property that is not used to calculate effective access of the primary object. For more
information, see Marking Object
Permissions.
Setting and Checking Permissions
To set permissions on an object, call set_Permissions
and pass in a collection
of AccessPermission
objects. See Setting Permissions for a code example.
To check basic access rights for a user, call getAccessAllowed
on an
IndependentlyPersistableObject
to return a bit mask that represents the current
caller's effective access to the object. Then, use AccessRight
constants to check
permissions. See Checking
Permissions for a code example.
Displaying Permissions in a User Interface
For applications that require a user interface (UI) for selecting object permissions, the Content Engine APIs provide the AccessPermissionDescription interface. The interface provides methods that retrieve descriptive information about access rights and access levels that users need in selecting permissions.
To populate a UI with all of the available access rights and levels for an object, you retrieve a collection of access permission descriptions (APDs) from the class of the object type. The collection represents all of the permissions that a user can set for that object type. You then iterate the collection and display the permission type, display name, and descriptive text of each APD.
AccessLevel
constants to set or
check permissions in non-interactive code. The values of APDs are
subject to change over time and might not accurately reflect your
code's original intent. Use only collections of individual access
rights to set and check permissions.See Getting Access Permission Descriptions for a code example.
Role-Based Security
Role-based security means that permissions are based on group membership. Using role-based security provides performance benefits and is recommended over assigning permissions to individual users.
Calling methods
that return collections of User
and Group
objects
(such as get_Users
on the Group
interface
and findUsers
and findGroups
on
the Realm
interface) involves a lookup operation
on the directory server. Response times for the lookup operations
that associated with these calls increase with the number of entries
to return, and are further degraded when the lookup is performed on
a directory server with limited system resources. Because the number
of groups in a realm is typically much smaller than the number of
users in the realm, group lookups yield better response times than
user lookups. For example, when you contruct your application, call Realm.findGroups
first
and make calls to Group.get_Users
only as necessary.
When collections are returned from a large directory of groups and
users, use the filtering capability that is provided by parameters
to the findGroups
and findUsers
methods
to limit the number of items returned.
When get_MemberOfGroups
is
called on a User
or Group
object
that belongs to a nested set of groups, all groups to which the user
or group belongs are returned.
You can restrict a group membership search to search within the realms that
are configured in IBM Administration Console for Content
Platform Engine by setting the
RestrictMembershipToConfiguredRealms property on the DirectoryConfiguration
class.
When the value of this property is false
(the default), the Content Engine server searches the following types of group memberships:
- Realm-local group memberships.
- Cross-realm group memberships that are in the configured realms.
- Cross-realm group memberships that involve realms that are not configured in Administration Console for Content Platform Engine. If the Content Engine server encounters this type of group membership, it logs an error and stops processing the search.
If the value of this property is true
, the Content Engine server searches the first two types of group memberships, but
ignores the third type. More specifically, it does not generate an error when the group membership
search encounters a realm that is not configured in Administration Console for Content Platform Engine.
Instead, it writes an INFO level message to the Content Engine server
error log, skips this specific group membership, and moves forward. In other words, if this
Boolean
property is enabled, the Content Engine server
ignores any cross-realm group memberships that involve realms that are not configured in Administration Console for Content Platform Engine.
Except for Windows Active
Directory Application Mode (ADAM), the RestrictMembershipToConfiguredRealms property is supported in
every type of directory service provider that is supported in IBM
FileNet Content Engine 4.5. In the case of ADAM, which does not support cross-realm
group memberships, the property is retained on the DirectoryConfiguration
class for
consistency across all supported directory servers, but the setting of the property on a
DirectoryConfigurationADAM
object has no meaning and is ignored. (Note that
RestrictMembershipToConfiguredRealms is specified in the DirectoryConfiguration
class, which is inherited by its child classes, such as
DirectoryConfigurationADAM
.)
There can be security implications if you choose to restrict membership
searches to only the realms that are configured in Administration Console for Content Platform Engine.
The following scenario is one example: The
security administrator configures two Active Directory domains, X and Y. The administrator then
configures Group A in Domain X and configures Group A to belong to Group B in Domain Y. Group B is
then denied access to Content Engine. As a result, Group A in Domain X
is also denied access to Content Engine. The administrator then removes
Domain Y from the configuration and sets the
DirectoryConfigurationAD.RestrictMembershipToConfiguredRealms
to
true
(that is, use only local group memberships) in Domain X. Now the preconfigured
Deny action for Group A is no longer in effect and security might be compromised.
Carefully examine security implications before you choose to ignore cross-realm group memberships on lookup operations.
Security Markings
A security marking is an extra level of security that can be assigned to an object, and is
represented by a Marking
object. A Marking
object combines
metadata behavior with access control behavior in a way that allows an object's access control to
change by changing a property value. Each marking has a string metadata value that is assigned to a
property value when the marking is applied to an object.
A Marking
object represents a single item in a marking set. The markings in the
marking set define the list of possible values for a single or multivalued property of an object. A
marking set is associated with a property on an object class. As an example, in a marking set that
is called Security Codes, the individual markings might have string values such as Top Secret,
Secret, Confidential. After you assign the Security Codes marking set to a Document
object, you can assign one or more of its markings to the document by setting the value of one of
its properties. (Note that an object can be assigned only one marking set but multiple markings.)
For example, you might assign a value of Top Secret to a custom property called Clearance on a
document. After the authorization service evaluates the permissions on a particular object, it also
evaluates the markings on the object. A security principal who wants to access that document must
have sufficient access from all assigned markings.
You can set multiple values for the Marking property on a new object. If you attempt to create an object, passing in a Marking property value for which the user has been granted Add rights but not Use rights, the method throws an access denied exception.
Creating a Marking Object
Creating marking sets and markings requires FileNet
P8
domain
administrator access rights. Marking sets and markings are stored in the Content Engine GCD. A marking set is associated with a property on an object
class. You cannot create a Marking
object by using the Content Engine APIs. However, you can create an instance of a saved Content Engine marking. For a list of ways to instantiate a
Marking
object and for a list of objects to which you can assign one or more
markings, refer to the reference help for the Marking
interface. (For information
about creating the Content Engine
Marking
and MarkingSet
objects, see the Markings topic in the Content Engine Security documentation.)
From an instance of a Marking
object, you can obtain its ID, the ID of its class
description, and its display name. In addition, you can call methods that return the marking's value
and the set of access rights that are associated with the marking value when the marking is applied.
You can also retrieve the marking's constraint mask. The constraint mask is a bit mask that
represents the set of access rights that are affected by the marking when it is applied to an
object. For information on each of these methods, refer to the online help for the
Marking
interface. For code examples, refer to Working with Marking Objects.
Active Markings
Any object that can have a marking can be assigned one or more markings. A marking that is
assigned to an object is called an active marking. The list of all markings that are assigned to a
single object is represented by an ActiveMarkings
collection. You cannot create an
ActiveMarking
object or an ActiveMarkings
collection with the
Content Java API. However, through an object's ActiveMarkings property you can
instantiate an ActiveMarking
object from which you can then retrieve the
Marking
object that is assigned to the object.
Marking Set Caching
Marking set information is cached in much the same manner that user and group information is cached. You can set the refresh time for the cache by using the MarkingSetCacheEntryTTL property, similar to setting refresh times for user and group caches. The cache is also refreshed automatically when a marking set is modified (for example, a new marking is added to the marking set), and the cache is expired when a marking set is deleted.
The marking set cache contains one entry for each defined marking set. (The number of marking values within a marking set is not constrained by the cache size.) As an example, if you set the maximum size of a marking set cache to 100, and you have defined 200 marking sets, only half of the marking sets are loaded in memory. For the best performance, set the maximum size of the marking set cache to be larger than the actual number of marking set instances.
A user's access to an object to which markings have been applied or modified might be affected due to time lags in updating the cache. For more information, see Security cache.
Marking Object Permissions
When retrieving the permissions on a Marking
object, note that the permissions
returned by the Marking.get_Permissions
method do not represent access rights to the
Marking
object of which they are a part. Rather, they are a collection of access
rights that are associated with the marking value and are applied when the marking is assigned to an
object. This method also returns special permissions that determine who can apply the marking to and
remove the marking from an object. The next few paragraphs describe these special Add, Rremove, and
Use permissions.
A user or group must be granted specific permissions to perform operations relevant to a marking
that are performed by the authorization service: add, delete, and use a marking. You must have Add
permission (AccessRight.ADD_MARKING
) to be able to assign (add) a marking to an
object, or Remove permission (AccessRight.REMOVE_MARKING
) to delete a marking from
an object.
The Use permission (AccessRight.USE_MARKING
) determines whether a constraint
mask is applied when a marking is assigned to an object. If a user is denied the Use access right,
then the value of the ConstraintMask
property is applied to, and overrides, the object's preliminary Effective Access Mask
as computed by the authorization service.
To obtain the access mask for a Marking
object based on the current user and the
Marking
object's permissions, call get_MarkingUseGranted
. From the
returned value, you can determine if a given user has the appropriate rights to perform marking
related operations on an object.
Marking-related Properties
In order to apply a Marking
to an object, the MarkingSet
that
contains the Marking
must first be associated with a
PropertyDescription
from the object’s ClassDescription
. This
association has the effect of constraining the possible values that can be assigned to the property
defined by the PropertyDescription
to values associated with the
Markings
in the Marking Set
.
The following topics provide information about specific marking-related properties: MarkingSets, MarkingSet, IsHierarchical, ActiveMarkings, and ConstraintMask.
MarkingSets and MarkingSet Properties
The Domain
object's MarkingSets property specifies a collection that contains
the MarkingSet
objects that are associated with a given domain.
Any object to which a marking can be assigned has a MarkingSet property in its
PropertyDescription
object. The value of this property defines the possible marking
values that can be assigned to the property described by the
PropertyDescription
.
You can use this property to retrieve a list of Marking
objects that can be
assigned to an object by a particular security principal. You can display the returned markings in a
user interface from which a particular user can make selections. As an example, the MarkingSet
property on a marking set that is called Security Codes might contain the markings Top Secret,
Secret, and Confidential.
IsHierarchical Property
A MarkingSet
object can be defined as nonhierarchical or hierarchical, according
to the value of its IsHierarchical property.
A nonhierarchical marking set contains one or more markings, each independent of all others. To compute security access to an object, in most cases the server accesses both the marking set and its contained marking values by ID, which is efficient and fast. However, when a new marking value is added to the marking set, the server examines each value in the marking set to recompute security access, regardless of whether the marking set is nonhierarchical or hierarchical. Having many values in the marking set can impact the performance of this operation.
A hierarchical marking set arranges markings in a simple, single branch hierarchy. Each marking has a superior marking (which must be in the same set), except for the top marking (its superior is null).
The purpose of a hierarchical marking set is to support an order of precedence when evaluating access rights. A marking in a hierarchical marking set explicitly grants access rights to a set of security principals. In addition, it also implicitly grants the same rights for all markings that are inferior to it in the hierarchy. When the marking set is hierarchical, the server must follow the hierarchical path of the marking values in the marking set to compute security access to an object. Having many marking values in the marking set can impact the performance of this operation.
A best practice is to keep the number of marking values small within a marking set, regardless of whether the marking set is defined as hierarchical or nonhierarchical. If you require many marking values, it is more efficient to create more marking sets, each with a smaller number of marking values. An entry is created in the marking set cache for each defined marking set, and each entry takes up a small amount of memory, but the effect on the system is negligible compared with the impact on performance of many marking values in a single marking set.
ActiveMarkings Property
All objects that can have markings have an ActiveMarkings property, which is a list-valued
property that returns all ActiveMarking
objects that are assigned to the object in
question. The list is a Values
collection whose elements are the
ActiveMarking
objects that are assigned to the object. Through an object's
ActiveMarkings property, you can get an ActiveMarking
object. From that object
instance, you can then call getMarking
to retrieve the actual
Marking
object that is assigned to the object in question. For a code sample, refer
to Working with Marking Objects.
ConstraintMask Property
An object's ConstraintMask property represents the access rights that are affected when a marking is applied to the object. The constraint mask is specified when the Marking object is created. When the marking is applied to an object, the constraint mask serves to subtract from the object's preliminary Effective Access Mask those access rights that correspond to the bit settings in the mask.
Whether the constraint mask is applied to an object's preliminary Effective Access Mask is
determined by whether a security principal is granted or denied the Use access right for a marking.
If the security principal is granted Use permission, the constraint mask is not applied. If the
security principal is denied Use permission, the object's access control is modified based on the
constraint mask. For example, if all bits of the constraint mask are on and a user has been denied
the AccessRight.USE_MARKING
permission, when the marking is applied to a
Document
object, the bits in the constraint mask are subtracted from the
Document
object's preliminary Effective Access Mask. The computed result
(the Effective Access Mask) prevents the user from accessing that document.
If you assign a marking to an object, and the marking's permissions have not granted the user or
group the Use access right (AccessRight.USE_MARKING
), then the rights that are
represented by bits in the constraint mask are subtracted (removed) from the preliminary Effective
Access Mask that was computed by the authorization service. The computed result of this subtraction
is the Effective Access Mask for the object.
You can retrieve the value of the constraint mask by calling get_ConstraintMask
on the Marking
interface.
Object Security
A
newly-created object acquires its default permissions directly from
its class. The ClassDescription
interface's get_DefaultInstancePermissions
method
returns the default permissions for an object that belongs to the
class. You can use this method to determine if the class's permissions
are appropriate for your application or to display the default permissions
in a user interface and allow the user to modify the permissions when
you are creating a new object of this class.
An object can also acquire permissions through inheritance and from a security policy.
Security Inheritance
Security inheritance is a customizable mechanism for managing access control based on inherited security relationships. The security relationships can be assigned to reflect the relationships inherent in your application object model.
A Document
or CustomObject
object (any class implementing the
Versionable
interface) can inherit security based on the following sources:
- A
Folder
object that is identified as a security parent in the SecurityFolder property for the child object. Multiple, different security parents (folders) can be specified by using object-valued properties on the child object. - A security policy.
- A combination of security parents and security policy.
A Folder
object always inherits its
permissions from its parent folder. A Document
or CustomObject
object's
security parent is reflected in the value of its SecurityFolder
property.
You can indirectly set the SecurityFolder
value for
an object at the time it is filed into a folder by calling the Folder.file
method
and specifying DefineSecurityParentage
as the value
for the defineSecurityParentage
parameter. The folder
into which the object is filed is then set as the SecurityFolder
value.
SecurityFolder
value
identifies the folder in which the object is filed, it is not a constraint.
The SecurityFolder
value can be any Folder
object.However, setting a child object's SecurityFolder
property alone does not
guarantee that the child object will inherit a specified parent's permissions: only those
permissions that are inheritable to the depth (level) of the child object (in an abstract
inheritance tree) are inherited. Use the set_InheritableDepth
method on the Permission
interface to specify the depth to which a parent object's security can be inherited. Set the
method's parameter to a value corresponding to a level in the inheritance chain. The inheritable
depth values are as follows:
- 0 - This object only (no inheritance).
- 1 - This object and immediate children only. Other positive values greater than 1 indicate the allowed depth of inheritance (for example, 2 indicates that this object, its immediate children and grandchildren only can inherit the permission).
- -1 - This object and all children (infinite levels deep).
- -2 - All children (infinite levels deep) but not the object itself.
- -3 - Immediate children only but not this object. Other negative values less than -3 indicate the allowed depth of inheritance (for example, -4 means only immediate children and grandchildren of the object inherit the permission, but not the object itself).
As the ACE is inherited by an object in a chain of objects, the InheritableDepth property value is decremented.
You
can determine the source of an inherited permission by retrieving
the value of the Permission
object's PermissionSource
property, for example, by calling Permission.get_PermissionSource
.
Permission entries with a source of PARENT (SOURCE_PARENT
)
have been inherited.
Inheritance of security for any child
object is calculated dynamically: whenever an access check is performed
on the child object, or the Permissions
collection
that is associated with the child object is retrieved. The inherited
access control entries (ACEs) are not persisted in the child object's
access control list, but are calculated from the inheritable ACEs
for the security parent that is specified in the child object's SecurityFolder
property.
A security parent or parents also can be designated by using object-valued properties. Use
the INHERITANCE
setting for the SecurityProxyType
constant. You can set SecurityProxyType
by using PropertyTemplateObject.set_SecurityProxyType.
When
the INHERITANCE
type of security proxy is used, it
is possible to specify multiple security parents for an object. You
can do so by assigning SecurityProxyType.INHERITANCE
values
to more than one object-valued property on the object. The resulting
security descriptor for the object is calculated by merging the inheritable
ACEs of the different security parents with the child object's persisted
ACEs.
For information about security inheritance rules, refer to Understanding security inheritance topic in the Content Engine Security documentation.
Security Policies
Security policies allow greater administrative control over object security than that provided by standard security. For example, instead of an object inheriting its security through a security parent, you can elect to use the security policy feature to assign access rights based on an object's state changes.
Security policies support the following two security management mechanisms:
- Server-managed versioning state-based security changes
- Application-managed state-based security changes
Version State Security
Enabling version
state security automatically applies access rights to versionable
objects (Document
and its subclasses) as the object
moves from one state to another. This behavior is seen with two-level
versioning, in which the expectation is that as a document moves through
four pre-defined states, access to that document differs for each
state. The four pre-defined document states are: InProcess, Released,
Reservation, and Superseded. For example, when a document enters the
released state (becomes the current major version), you might want
all users to be able to view it, but if the document is superseded
by a newer version, you might want only the document owner to be able
to view it.
Application-managed State Security
You
can also choose application-managed security, in which state based
changes to both versionable and nonversionable objects (for example, CustomObject
or Folder
objects)
are applied as the object transitions from one state to another. The
definition of a state change in this case is entirely application-defined.
For example, the application can define a state change as occurring
when some specific period of time has passed since the last modification
to the object. As the object undergoes state changes, your application
controls access to it by identifying points at which security is changed
and then explicitly applying access rights that are specified by a
selected security template. This process differs from an application
directly modifying access rights at various times in that it provides
a level of indirection and abstraction. The application still controls
the nature and timing of access right changes, but the specific details
of the changes are isolated to security policies.
Security Policy
The security policy is the mechanism for controlling
access to an object as its state changes. The security policy is a
container that holds a set of security templates. Templates hold a
collection of predefined permissions that can be applied to a Document
, CustomObject
,
or Folder
object. The template defines the exact
security change that occurs when the template is applied to an object.
Security
policies are created and a default security policy can be assigned
to Document
, CustomObject
, and Folder
classes.
(Typically, these tasks are performed by a Content Engine administrator.) An object's
security policy is reflected in the value of its SecurityPolicy property.
Users with appropriate permissions can remove the security policy
from the class, or change the security policy on the class. When a
new subclass of one of these classes is created, the subclass inherits
the security policy of its parent class. However, after the subclass
is successfully created, that security policy can be removed or changed
by setting the object's SecurityPolicy property in the same manner
as you set any other object-valued property.
Security policies offer flexible control over object security.
- A single security policy can manage objects of different classes.
For example, you can create a single security policy that is assigned
to any combination of
Document
,Folder
, andCustomObject
classes, or their subclasses. - More than one security policy can be used by different groups
of objects of the same class. For example, you can create multiple
Document
objects and assign each a different security policy. - A single security policy can be shared by many objects. For example,
you can create a single security policy and assign it to zero or more
Document
,Folder
, orCustomObject
objects, or any combination of the three object types.
A security policy is made up of a set of security templates,
each of which corresponds to an object's state. Each template contains
the access rights that are assigned to an object as a result of applying
the template. When versionable objects (such as Document
)
move from one versioning state to another, for example, from InProcess
to Released, the appropriate security template is retrieved from the
security policy and automatically applied to the object. "Applied"
in this context means that the permissions defined in the security
template are assigned to the object, replacing any permissions previously
inherited from a security template. Your application can also explicitly
apply a template to a versionable or nonversionable object. For more
information, see Applying
a Security Template.
From the Content Engine APIs, you manage and manipulate
the security policy through the SecurityPolicy
object
and SecurityTemplate
objects. For more information
about these objects, see SecurityPolicy Object and SecurityTemplate Object.
SecurityPolicy Object
A SecurityPolicy
object
is an independently persistable, subclassable container object for
a set of SecurityTemplate
objects. Each SecurityPolicy
object
can contain zero or more application security templates and from zero
to four versioning security templates. The SecurityPolicy
object's
multi-valued, object-valued SecurityTemplates property contains the
security templates that are contained in the policy. A SecurityPolicy
object
can be associated with one or more Document
, CustomObject
,
or Folder
objects, or any combination thereof that
shares a common access control scheme. Associating a SecurityPolicy
object
with an object allows the templates that are contained in the policy
to be applied to the object. A single SecurityPolicy
object
can contain versioning security templates, application security templates,
or both.
Given the appropriate permissions, you can create
a new SecurityPolicy
object, or retrieve, change,
and save an existing one. You can also:
- Add new
SecurityTemplate
objects to theSecurityPolicy
object. - Delete existing
SecurityTemplate
objects from theSecurityPolicy
object. - Modify
SecurityTemplate
objects that are contained in theSecurityPolicy
object.
Modifications to an existing SecurityPolicy
object
are not propagated to objects that refer to that policy.
For
ways to instantiate a SecurityPolicy
object, refer
to the SecurityPolicy
interface description in the
reference help.
Security Policy Assignment
A SecurityPolicy
object
can be associated with a Document
, CustomObject
,
or Folder
object by setting the object's SecurityPolicy
property. When you create the object, you can assign to it a maximum
of one security policy. Multiple security policies are not allowed
on a class definition or a single object instance. If you do not assign
a security policy to the new object at creation time, the value, if
any, specified as the default (in the SecurityPolicy property description
of the class) is copied to the object instance. When subclasses of
a class that has an associated security policy is created, the new
subclass shares the security policy with its parent class.
As
a versionable object undergoes versioning state changes, its permissions,
based on its security policy, are modified. If the versionable object
has no associated security policy, its permissions remain unchanged
when its versioning state changes. When you set the SecurityPolicy
property of a Document
object for the first time,
or you change it to refer to a different security policy, the new
policy is applied to the current (latest) version of the document
in the version series.
An object's security policy can also
change when you change the class of a Document
, CustomObject
,
or Folder
object. The value for the object's SecurityPolicy
property is changed according to the same rules as for other properties.
For more information, see the reference help for the changeClass
method.
Security Policy Removal
You can remove a security policy from an object, or remove security policy objects from the object store.
To
remove a security policy from an object, set the object's SecurityPolicy
property to null
. This removes from the object all
permissions that were inherited from the security policy's templates.
Given
the appropriate permissions, you can delete a security policy from
the object store. Doing so removes the SecurityPolicy
object
and all its contained SecurityTemplate
objects. You
cannot delete a SecurityPolicy
object that is in
use. A SecurityPolicy
object is considered in use
if there are any outstanding references to it. Outstanding references
include when it is identified as a class default value or when the
SecurityPolicy property of at least one Document
, CustomObject
,
or Folder
object is set to the SecurityPolicy
object
you want to delete. When any of the following events occurs on a Document
, CustomObject
,
or Folder
object, the associated SecurityPolicy
object
is no longer be considered to be in use and you can delete it:
- The object's SecurityPolicy property is changed to reference a
different
SecurityPolicy
object. - The object's SecurityPolicy property is set to
null
. - The object itself is deleted.
SecurityTemplate Object
The SecurityTemplate
object
is a dependently persistable object that contains the permissions
that are applied to an object. An instance of this object cannot be
created or persisted independently of a parent SecurityPolicy
object.
(For ways to create a new SecurityTemplate
object
or retrieve an existing one, refer to the VersioningSecurityTemplate
or ApplicationSecurityTemplate
interface
description in the reference help.) Using the SecurityTemplate
object's
methods, you set its properties and permissions before you add it
to a SecurityPolicy
object. The SecurityTemplates
property of the SecurityPolicy
object reflects the
templates that are contained within the policy.
A description
of the permissions that the SecurityTemplate object represents can
be obtained by getting the value of the object's TemplatePermissionDescriptions
property. From this property, you can determine the template's AccessPermissionDescription
objects,
each of which provides descriptive information for an access right
or level. The information, which you can use to populate security
editing dialogs in a user interface, consists of the permission's
access mask, permission type, and display name.
A SecurityTemplate
object
can represent either an application security template or a versioning
security template. The two types have the same object type, but are
differentiated by their class IDs (GUIDs) and by their uses. Class
IDs for the security template types are defined by the following constants: APPLICATION_SECURITY_TEMPLATE
and VERSIONING_SECURITY_TEMPLATE
.
(Refer to the FileNet.Api.Constants
namespace or filenet.com.api.constants
package in
the reference help.)
Application Security Template
Use
application security templates when you want your application to manage
object security as an object's state changes. An application security
template is a predefined collection of permissions that can be applied
to a Document
, CustomObject
, or Folder
object.
An application security template is never automatically applied; it
must be explicitly applied to the object.
An application security
template's ApplyStateId property associates the template with a particular
state that is defined by your application. When the application determines
that an object has transitioned to that state, the application can
call the applySecurityTemplate
method on the object,
specifying the value for the applyStateId
parameter
as either a user-defined GUID or one of the pre-defined versioning
state GUIDs. The method uses the GUID to locate and select the appropriate
template to apply from those available in the SecurityPolicy
object
that is associated with the object.
A user or group with permission
to modify an object's security (AccessRight.WRITE_ACL
)
can change an object's security by explicitly applying any of the
enabled SecurityTemplate
objects that are contained
in the SecurityPolicy
object.
Versioning Security Template
A versioning security template is used
exclusively to support the automatic update of a Document
object's
permissions as its versioning state changes. A default versioning
security template is available for each state through which a document
version can transition: InProcess, Released, Reservation, and Superseded.
The template's ApplyStateId property contains a value that corresponds
to one of the four statically defined GUIDs for each state. The GUIDs
are defined as constants in the VersionStatusId
class
as follows:
-
IN_PROCESS
-
RELEASED
-
RESERVATION
-
SUPERSEDED
When a versionable object's state changes, the template corresponding
to the changed state is located from those available in the SecurityPolicy
object
and is automatically applied to the object.
As an example,
when a Document
object's version state changes from
InProcess to Released, the associated SecurityPolicy
object
is searched for a versioning security template whose ApplyStateId
property is set to VersionStatusId.RELEASED
, and
the permissions that are defined by that template are automatically
applied to the object. If a security template has been previously
applied to a versionable object, the permissions in the automatically
applied versioning template replace the previously applied permissions.
A
user or group with permission to modify an object's security (AccessRight.WRITE_ACL
)
can change an object's security by explicitly applying any of the
enabled SecurityTemplate
objects that are contained
in the SecurityPolicy
object.
Enabling and Disabling Templates
You can optionally disable an individual
template in the SecurityPolicy
object. Disabling
a template sets its IsEnabled property to false
.
A disabled template remains a part of its SecurityPolicy
object
container, but cannot be applied to an object. Disabling a template
is useful when you are testing or developing security templates that
make up a security policy.
Enabled templates of the appropriate type are applied to an object in the following circumstances:
- Automatically when you create an object instance whose class has a default security policy.
- Automatically when a versionable object undergoes a versioning state change.
- When you explicitly call an object's
applySecurityTemplate
method. - When you explicitly call an object's
changeClass
method.
Applying a Security Template
When
the SecurityPolicy property of a versionable object is set for the
first time or changed to refer to a different SecurityPolicy
object,
the SecurityPolicy
object is searched for a template
that corresponds to the current version status of the document, and
the template is applied (that is, the permissions that are defined
in the template are assigned to the object).
An application
can modify the existing security on an object by calling the applySecurityTemplate
method
on the Document
, CustomObject
, or Folder
interfaces.
This method applies an individual security template, which is specified
by the applyStateId
parameter, to the object. Using
the parameter value, the method locates the SecurityTemplate
object
whose ApplyStateId property corresponds to the value contained in
the parameter.
When the method locates the template, it applies it to the object (that is, the permissions that are defined in the template are assigned to the object). Permissions from the template are applied to the object in the following order:
- Old permissions that are inherited from the object's security policy are deleted.
- If the associated
SecurityPolicy
object's PreserveDirectPermissions property is set tofalse
, the method deletes noninherited permissions (that is, those permissions that have been directly set on the object) and retains only inherited permissions; if set totrue
, the method retains the noninherited (directly set) permissions. - New permissions from the
SecurityTemplate
are added to existing permissions that were inherited from the object's security parent and to any existing noninherited permissions.
This topic is shared by ICS, Filenet 5.5.10. As of: 2023-05-10