Securing the Infinity Process Platform Engine

This section summarizes the configuration issues when integrating Infinity Process Platform into an existing security infrastructure. For an in-depth discussion of the underlying concepts, see the Programming Guide.

Note: Server side properties described in the configurations below are meant to be set in the server side carnot.properties. Client side properties have to be set in the client side carnot.properties.

Authentication and Authorization Choices

Authentication

Authentication can be done in one of the following modes:

The following table summarizes the different authentication options.

  Custom Registry Spring Local Mode Client Bean Factory
Internal Login no yes no
JAAS Login yes yes no

Authorization

Authorization in Infinity Process Platform, i.e. the assignment of participants (roles/organizations) to users is normally stored in the audit trail. If an external user registry is used the authorization information has to be replicated from the external registry every time a login is done. This role mapping logic has to be implemented by providing an implementation of the

org.eclipse.stardust.engine.core.spi.security.DynamicParticipantSynchronizationProvider

interface. The details for implementing a synchronization provider can be found in the Programming Guide.

Authentication and Authorization Modes

The modes for authentication and authorization are both internal per default. They can be changed in the server-side carnot.properties file via the following properties:

In case the Security.Authorization.Mode has been set to a different value then internal, authorization will be external. The Synchronization provider needs to be in place and configured. If Security.Authentication.Mode has been set to a different value then internal, authentication will be external and the Login Provider needs to be in place and configured.

The following scenarios are possible:

Authentication Authorization Behavior
internal internal Users and grants are handled completely internally.
internal external Users are handled internally, grants are handled externally.
external internal Users are handled externally, grants are handled internally.
external external Users and grants are handled completely externally.

Note
A SynchronizationProvider ist always required as soon as Authentication OR Authorization are configured in any external mode.

Internal Authentication

Internal authentication mode is turned on by default when no security related properties are explicitly set. It always uses the audit trail database as authentication and authorization source. You can document the use of internal authentication explicitly by setting the following property on the server:

Security.Authentication.Mode = internal

The following table summarizes other server side configuration options for internal authentication:

Property Range/Default Value Remarks
Security.Authentication.Mode String / internal internal authentication mode
Security.Authentication.MaximumNumberLoginRetries integer / 3 A re-login try threshold. If exceeded the account is temporarily disabled
Security.Authentication.InvalidationTimeInMinutes integer / 1 min The time an account is disabled after unsuccessful login

Deploying Stateless Beans

Please note that in case you like to perform a stateless deployment for internal authentication you have to adjust some settings in your deployment descriptor. Please refer to the section Stateless Bean Deployment for Internal Authentication of the chapter Deploying Infinity Process Platform Components to an EJB Application Server in the Deployment Guide for detailed information.

JAAS Authentication

Server Configuration

Server side JAAS Authentication is set by:

 Security.Authentication.Mode = jaas

Additionally, you have to provide the following properties:

Property Range / Default Value Remarks
Security.Authentication.
ConfigurationName
String / - The JAAS login configuration name
Security.Authentication.PrincipalClass String / - The class name of the principal to use from the returned JAAS Subject

You also have to set up a login configuration in the server configuration itself. Please refer to your application server security documentation for detailed information on how to do this. Note, that the exact method of authentication tried depends on the credentials present in the JAAS subject and the JAAS configuration set by the application.

Client Configuration

The JAAS authentication mode is transparent to the client. No configuration is necessary.

Participant Synchronization

Participant synchronization has to be done if authentication is done against an authentication source different from the audit trail database. The Infinity Process Platform Process Engine then has to synchronize the participant mappings at login time. The configuration to be provided is the name of the SynchronizationProvider to use, and probably provider specific settings:

 Security.Authorization.SynchronizationProvider = classname

To control the frequency of participant synchronization, Infinity Process Platform evaluates the property:

 Security.Authorization.SynchronizationStrategy = classname

The strategy implementation has to be an implementation of the interface:

 org.eclipse.stardust.engine.core.spi.security.DynamicParticipantSynchronizationStrategy  

By implementing this interface it is possible to tell the engine if a specific dynamic participant's external representation is likely to have been, thus requiring a new synchronization operation. By default the class:

 org.eclipse.stardust.engine.core.spi.security.TimebasedSynchronizationStrategy

is used, which itself by default synchronizes any participant only every 10 seconds. This delay may be configured by setting the properties:

 Security.Authorization.TimebasedSynchronizationStrategy.UserSyncTimeout

and

 Security.Authorization.TimebasedSynchronizationStrategy.UserGroupSyncTimeout

to the desired number of seconds.

If you want to invalidate a user or usergroup, which does not exist in external registry, you can set the following property:

Security.Authorization.InvalidateNonexistingParticipants

The validTo property of the non-existing user or usergroup will then be set to current date.

To enable tracing for user or usergroup synchronization with external registry evaluate the following property:

Security.Authorization.TraceSynchronization

Participant synchronization is transparent to Infinity Process Platform clients. It only has to be configured on the server side.

Java 2 Security

If you want to enforce Java 2 Security in your application server you have to relax somehow the permissions mandated in the J2EE specification to allow access to Infinity Process Platform resources. Also, Infinity Process Platform uses advanced Java reflection you have to permit.

Here are the permissions you have to set to operate Infinity:

 java.io.FilePermission "carnot-engine.jar" "read";

to read resources from the Infinity Process Platform jar:

 permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
 permission java.lang.RuntimePermission "accessDeclaredMembers";

to allow advanced Java reflection.

Dependent on the JAXP implementation your application server is using you may need additional permissions, like

permission:

 java.io.FilePermission "xalan.jar", "read";

If you intend to use Infinity Process Platform mail functionality (notifications or triggers) you also have to relax the permissions to get access to JDK specific mail resources.

Security Example Implementations

Infinity Process Platform provides security examples with source code for example implementations. Refer to the Examples section for details.

LDAP Synchronization Example

Infinity provides an LDAP synchronization example, which is useful if you have to synchronize against an LDAP repository and if you can express the user-to-participant mapping by an LDAP search filter.

You can download this example here:

This provider can be configured using the following properties:

Property Range/
Default Value
Remarks
LDAPSynchronization.ServerName Hostname / - The host name of the LDAP server to connect
LDAPSynchronization.ServerPort Port number / 389 The port number to connect
LDAPSynchronization.RootDN LDAP distinguished name The distinguished name where all operations are relative to
LDAPSynchronization.BindMode 'anonymous' or 'dedicated' /'anonymous' Flag indicating whether to connect anonymously
LDAPSynchronization.BindUserDN String User DN to use for connecting if bind mode is dedicated
LDAPSynchronization.BindPassword String Password to use for connecting if bind mode is dedicated
LDAPSynchronization.SearchTimeLimit Integer /
0 (unlimited)
The time limit for searches in milliseconds
LDAPSynchronization.UserFilter LDAP search filter The search filter to get user information for a principal name. The wildcard %v is used to include the principal name.
LDAPSynchronization.ParticipantFilter LDAP search filter The search filter to get the participants for a principal name. The wildcard %v is used to include the principal name.
LDAPSynchronization.
ParticipantNamingAttribute
LDAP attribute name/'cn' The attribute name for getting the Infinity Process Platform participant ID from a found participant

As an example here is a configuration which:

Security.Authorization.SynchronizationProvider = org.eclipse.stardust.examples.authorization.ldap.LDAPSynchronizationProvider
LDAPSynchronization.ServerName=ldap.de.carnot.ag LDAPSynchronization.RootDN=dc=de,dc=carnot,dc=ag,dc=test LDAPSynchronization.UserFilter="(&(uid=%v)(objectclass=inetOrgPerson)) LDAPSynchronization.ParticipantFilter=(&(objectClass=groupOfUniqueNames)(uniqueMember=uid=%v*))

WebLogic Example

For a WebLogic authentication example, download the following zip file:

This example provides a secure session factory for WebLogic, that you can use by setting the property Secure.Session.Factory in your carnot.properties file:

Secure.Session.Factory = org.eclipse.stardust.examples.authentication.weblogic.WeblogicSecureSessionFactory

WebSphere Example

For a WebSphere authentication example, download the following zip file:

This example provides a secure session factory and a credential provider for WebSphere, that you can use by setting the properties Secure.Session.Factory and Credential.Provider in your carnot.properties file:

Credential.Provider = org.eclipse.stardust.examples.authentication.websphere.WASCredentialProvider
Secure.Session.Factory = org.eclipse.stardust.examples.authentication.websphere.WASSecureSessionFactory

Setting Application Permissions

Predefined Permissions

The following table shows the service operations provided by Infinity depending on the model element and the permission to be used:

Model Element Permission/Default Participant Service Operations concerned
Model Deploy and Modify Process Model/Administrator AdministrationService.deployModel(String model, int predecessorOID)
AdministrationService.deployModel(String model, String configuration, int predecessorOID, Date validFrom, Date validTo, String comment, boolean disabled, boolean ignoreWarnings) (deprecated)
AdministrationService.deployModel(List<DeploymentElement> paramList, DeploymentOptions paramDeploymentOptions)
AdministrationService.overwriteModel(String model, int modelOID) (deprecated)
AdministrationService.overwriteModel(String model, String configuration, int modelOID, Date validFrom, Date validTo, String comment, boolean disabled, boolean ignoreWarnings) (deprecated)
AdministrationService.overwriteModel(DeploymentElement deploymentElement, int modelOID, DeploymentOptions options)
Model Modify Audit Trail Content/Administrator AdministrationService.cleanupRuntime(boolean keepUsers)
AdministrationService.cleanupRuntimeAndModels()
AdministrationService.setPasswordRules(PasswordRules rules)
AdministrationService.deleteProcesses(List<Long> piOids)
AdministrationService.startProcess(long modelOID, String id, Map<String, ?> data, boolean synchronously)
AdministrationService.createProcessInstanceLinkType(String id, String description)
Model Modify Audit Trail Statistics AdministrationService.writeLogEntry(LogType logType, ContextKind contextType, long contextOid, String message, Throwable throwable)

WorkflowService.writeLogEntry(LogType logType, ContextKind contextType, long contextOid, String message, Throwable throwable)
Model Run Recovery/Administrator AdministrationService.recoverProcessInstance(long oid)
AdministrationService.recoverProcessInstances(List<Long> oids)
AdministrationService.recoverRuntimeEnvironment()
Model Manage Daemons/Administrator AdministrationService.getDaemon(String daemonType, boolean acknowledge)
AdministrationService.startDaemon(String daemonType, boolean acknowledge)
AdministrationService.stopDaemon(String daemonType, boolean acknowledge)
AdministrationService.getAllDaemons(boolean acknowledge)
Model Control Process Engine/Administrator AdministrationService.flushCashes
Model Obtain Audit Trail Statistics/Administrator AdministrationService.getAuditTrailHealthReport()
AdministrationService.getAuditTrailHealthReport(boolean countOnly)
QueryService.getLogEntriesCount(LogEntryQuery query)
QueryService.findFirstLogEntry(LogEntryQuery query)
QueryService.getAllLogEntries(LogEntryQuery query)
Model Obtain User Data/Administrator QueryService.getAllUserGroups(UserGroupQuery query)
QueryService.getAllUsers(UserQuery query)
QueryService.getUserGroupsCount(UserGroupQuery query)
QueryService.getUsersCount(UserQuery query)
QueryService.findFirstUser(UserQuery query)
QueryService.findFirstUserGroup(UserGroupQuery query)

UserService.getUser(String account)
UserService.getUser(String realm, String account)
UserService.getUser(long userOID)
UserService.getUserGroup(String id)
UserService.getUserGroup(long oid)
UserService.getUserRealms()
Model Modify User Data/Administrator UserService.modifyUser(User user)
UserService.modifyUser(User user, boolean generatePassword)
UserService.createUser(String account, String firstName, String lastName, String description, String password, String eMail, Date validFrom, Date validTo)
UserService.createUser(String realm, String account, String firstName, String lastName, String description, String password, String eMail, Date validFrom, Date validTo)
UserService.invalidateUser(String account)
UserService.invalidateUser(String realm, String account)
UserService.createUserGroup(String id, String name, String description, Date validFrom, Date validTo)
UserService.modifyUserGroup(UserGroup userGroup)
UserService.invalidateUserGroup(String id)
UserService.invalidateUserGroup(long oid)
UserService.createUserRealm(String id, String name, String description)
UserService.dropUserRealm(String id)
Model Obtain Model Data/All QueryService.getProcessDefinition(long modelOID, String id)
QueryService.getProcessDefinition(String id)
QueryService.getProcessDefinitions(ProcessDefinitionQuery query)
QueryService.getModel(long modelOID)
QueryService.getModel(long modelOID, boolean computeAliveness)
QueryService.getModels(DeployedModelQuery query)
QueryService.getModelAsXML(long modelOID)
QueryService.getModelDescription(long modelOID)
QueryService.getActiveModel() (deprecated)
QueryService.getActiveModelDescription()
QueryService.getAllData(DataQuery query)
QueryService.getAllProcessDefinitions()
QueryService.getAllProcessDefinitions(long modelOID)
QueryService.getAllAliveModelDescriptions()
QueryService.getAllParticipants()
QueryService.getAllParticipants(long modelOID)
QueryService.getParticipant(long modelOID, String id)
QueryService.getAllModelDescriptions()
QueryService.wasRedeployed(long modelOid, int revision)
QueryService.getParticipant(String id)
QueryService.getSchemaDefinition(long modelOID, String id)

WorkflowService.getStartableProcessDefinitions()
WorkflowService.getModel() (deprecated)
Model Read Departments AdministrationService.getDepartment(long oid)

QueryService.findAllDepartments(DepartmentInfo department, OrganizationInfo organization)
Model Spawn Subprocess Instance WorkflowService.spawnSubprocessInstance(long parentProcessInstanceOid, String spawnProcessID, boolean copyData, Map<String, ? > data)
WorkflowService.spawnSubprocessInstances(long parentProcessInstanceOid, List<SubprocessSpawnInfo> subprocessSpawnInfo)
Model Spawn Peer Process Instance WorkflowService.spawnPeerProcessInstance(long processInstanceOid, String spawnProcessID, boolean copyData, Map<String, ? extends Serializable> data, boolean abortProcessInstance, String comment)
WorkflowService.spawnPeerProcessInstance(long processInstanceOid, String spawnProcessID, SpawnOptions options)
Model Join Process Instance WorkflowService.joinProcessInstance(long processInstanceOid, long targetProcessInstanceOid, String comment)
Model Create Case WorkflowService.createCase(String name, String description, long[] memberOids)
Model Save own User Scope Preferences AdministrationService.savePreferences(Preferences preferences)
AdministrationService.savePreferences(List<Preferences> preferenceList)
Model Save own Partition Scope Preferences AdministrationService.saveConfigurationVariables(ConfigurationVariables configurationVariables, boolean force)
AdministrationService.setGlobalPermissions(RuntimePermissions permissions)
Model Modify Departments AdministrationService.createDepartment(String id, String name, String description, DepartmentInfo parent, OrganizationInfo organization)
AdministrationService.modifyDepartment(long oid, String name, String description)
AdministrationService.removeDepartment(long oid)
Model Deploy Runtime Artifact AdministrationService.deployRuntimeArtifact(RuntimeArtifact runtimeArtifact)
AdministrationService.overwriteRuntimeArtifact(long oid, RuntimeArtifact runtimeArtifact)
AdministrationService.deleteRuntimeArtifact(long oid)
Model Read Runtime Artifact AdministrationService.getRuntimeArtifact(long oid)
AdministrationService.getSupportedRuntimeArtifactTypes()

QueryService.getRuntimeArtifact(long oid)
QueryService.getRuntimeArtifacts(DeployedRuntimeArtifactQuery query)
Model Manage Deputies UserService.getDeputies(UserInfo user)
UserService.getUsersBeingDeputyFor(UserInfo deputyUser)
UserService.addDeputy(UserInfo user, UserInfo deputyUser, DeputyOptions options)
UserService.modifyDeputy(UserInfo user, UserInfo deputyUser, DeputyOptions options)
UserService.removeDeputy(UserInfo user, UserInfo deputyUser)
Process Definition Start Process/All WorkflowService.startProcess(String id, Map data, boolean synchronously)
WorkflowService.startProcess(String id, StartOptions options)
Process Definition Abort Process Instances/Administrator AdministrationService.abortProcessInstance(long oid)
WorkflowService.abortProcessInstance(long processInstanceOID)
Process Definition Read Process Instance Data/Administrator QueryService.getAllProcessInstances(ProcessInstanceQuery query)
QueryService.findFirstProcessInstance(ProcessInstanceQuery query)
QueryService.getProcessInstancesCount(ProcessInstanceQuery query)

WorkflowService.getProcessInstance(long processInstanceOID)
WorkflowService.getInDataPath(long processInstanceOID, String id)
WorkflowService.getInDataPaths(long processInstanceOID, Set<String> ids)
WorkflowService.setOutDataPath(long processInstanceOID, String id, Object object)
WorkflowService.setOutDataPaths(long processInstanceOID, Map<String, ?> values)
WorkflowService.getProcessResults(long oid)
Process Definition Modify Process Instances AdministrationService.setProcessInstancePriority(long oid, int priority)
AdministrationService.setProcessInstancePriority(long oid, int priority, boolean propagateToSubProcesses)
Process Definition Modify Process Attributes WorkflowService.setProcessInstanceAttributes(ProcessInstanceAttributes attributes)
Process Definition Manage Event Handlers/Administrator WorkflowService.getProcessInstanceEventHandler(long processInstanceOID, String handler)
WorkflowService.bindProcessEventHandler(long processInstanceOID, EventHandlerBinding eventHandler)
WorkflowService.bindProcessEventHandler(long processInstanceOID, String handler)
WorkflowService.unbindProcessEventHandler(long processInstanceOID, String handler)
Process Definition Modify Case WorkflowService.joinCase(long caseOid, long[] memberOids)
WorkflowService.leaveCase(long caseOid, long[] memberOids)
WorkflowService.mergeCases(long targetCaseOid, long[] sourceCaseOids, String comment)
Data Read Data Values/All QueryService.getAllBusinessObjects(BusinessObjectQuery query)
Data Modify Data Values QueryService.createBusinessObjectInstance(String qualifiedBusinessObjectId, Object initialValue)
QueryService.updateBusinessObjectInstance(String qualifiedBusinessObjectId, Object newValue)
QueryService.deleteBusinessObjectInstance(String qualifiedBusinessObjectId, Object primaryKey)
Data Modify DMS Data DocumentManagementService.createDocument(String folderId, DocumentInfo document)
DocumentManagementService.createDocument(String folderId, DocumentInfo document, byte[] content, String encoding)
DocumentManagementService.versionDocument(String documentId, String versionLabel)
DocumentManagementService.versionDocument(String documentId, String versionComment, String versionLabel)
DocumentManagementService.removeDocumentVersion(String documentId, String documentRevisionId)
DocumentManagementService.moveDocument(final String documentId, final String targetPath)
DocumentManagementService.updateDocument(Document document, boolean createNewRevision, String versionLabel, boolean keepLocked)
DocumentManagementService.updateDocument(Document document, boolean createNewRevision, String versionComment, String versionLabel, boolean keepLocked)
DocumentManagementService.updateDocument(Document document, byte[] content, String encoding, boolean createNewRevision, String versionLabel, boolean keepLocked)
DocumentManagementService.updateDocument(Document document, byte[] content, String encoding, boolean createNewRevision, String versionComment, String versionLabel, boolean keepLocked)
DocumentManagementService.requestDocumentContentUpload(String documentId)
DocumentManagementService.removeDocument(String documentId)
DocumentManagementService.createFolder(String parentFolderId, FolderInfo folder)
DocumentManagementService.updateFolder(Folder folder)
DocumentManagementService.removeFolder(String folderId, boolean recursive)
DocumentManagementService.setPolicy(String resourceId, AccessControlPolicy policy)
DocumentManagementService.migrateRepository(int batchSize, boolean evaluateTotalCount)
DocumentManagementService.migrateRepository(int batchSize, boolean evaluateTotalCount, String repositoryId)
Activity Perform Activity Permission/Implicitly via performer assignment WorkflowService.getActivityInstance(long activityInstanceOID)
WorkflowService.activate(long activityInstanceOID)
WorkflowService.activateAndComplete(long activityInstanceOID, String context, Map outData)
WorkflowService.activateAndComplete(long activityInstanceOID, String context, Map outData, int flags)
WorkflowService.activateNextActivityInstance(long activityInstanceOID)
WorkflowService.activateNextActivityInstanceForProcessInstance(long processInstanceOID)
WorkflowService.complete(long activityInstanceOID, String context, Map outData)
WorkflowService.complete(long activityInstanceOID, String context, Map outData, int flags)
WorkflowService.getInDataValue(long activityInstanceOID, String context, String id)
WorkflowService.getInDataValues(long activityInstanceOID, String context, Set<String> ids)
WorkflowService.performAdHocTransition(long activityInstanceOid, TransitionTarget target, boolean complete)
WorkflowService.suspend(long activityInstanceOID, ContextData outData)
WorkflowService.suspendToDefaultPerformer(long activityInstanceOID)
WorkflowService.suspendToDefaultPerformer(long activityInstanceOID, String context, Map outData)
WorkflowService.suspendToUser(long activityInstanceOID)
WorkflowService.suspendToUser(long activityInstanceOID, String context, Map outData)
WorkflowService.suspendToParticipant(long activityInstanceOID, String participant)
WorkflowService.suspendToParticipant(long activityInstanceOID, String participant, String context, Map outData)
WorkflowService.suspendToParticipant(long activityInstanceOID, ParticipantInfo participant, ContextData outData)
WorkflowService.suspendToUser(long activityInstanceOID, long userOID)
WorkflowService.suspendToUser(long activityInstanceOID, long userOID, String context, Map outData)
Activity Delegation to other users WorkflowService.delegateToDefaultPerformer(long activityInstanceOID)
WorkflowService.delegateToParticipant(long activityInstanceOID, String performer)
WorkflowService.delegateToParticipant(long activityInstanceOID, ParticipantInfo participant)
WorkflowService.delegateToUser(long activityInstanceOID, long userOID)
WorkflowService.hibernate(long activityInstanceOID)
WorkflowService.hibernate(long activityInstanceOID)
Activity Manage Event Handlers/Administrator WorkflowService.getActivityInstanceEventHandler(long activityInstanceOID, String handler)
WorkflowService.bindActivityEventHandler(long activityInstanceOID, EventHandlerBinding eventHandler)
WorkflowService.bindActivityEventHandler(long activityInstanceOID, String handler)
WorkflowService.unbindActivityEventHandler(long activityInstanceOID, String handler)
Activity Read Activity Instance Data/All QueryService.findFirstActivityInstance(ActivityInstanceQuery query)
QueryService.getAllActivityInstances(ActivityInstanceQuery query)
QueryService.getActivityInstancesCount(ActivityInstanceQuery query)
QueryService.getAuditTrail(long processInstanceOID)

WorkflowService.getActivityInstance(long oid)
Activity Modify Attributes WorkflowService.setActivityInstanceAttributes(ActivityInstanceAttributes attributes)
Activity Abort Activity Instances WorkflowService.abortActivityInstance(long oid)
WorkflowService.abortActivityInstance(long oid, AbortScope abortScope)
Workitem Perform Activity WorkflowService.activateNextActivityInstance(WorklistQuery query)
Workitem ReadActivityInstanceData WorkflowService.getWorklist(WorklistQuery paramWorklistQuery)

For a detailed description on the permissions for specific services, refer to chapter Declarative Security Usage in Infinity Process Platform Services API in the Programming Guide.

Service Methods restricted to OWNER

The grant OWNER is either the user, the user group, or the model participant that is currently assigned as performer of an activity instance. The following methods of the WorkflowService are restricted to the OWNER by the means of the activity.performActivity permission, which is fixed and cannot be changed by the modeler:

If the current user does not qualify as an OWNER of the activity instance, an AccessForbiddenException will be thrown.

The following two methods require the current user to become the OWNER of the next activity instance:

If that is not possible, because the permission is denied, a value of null is returned and no authorization specific exception will be thrown.

Service Methods restricted to Administrator

The method AdministrationService.forceCompletion is restricted to the Administrator by the means of the activity.performActivity permission, which is fixed and cannot be changed by the modeler.

If the current user does not qualify as an Administrator, an AccessForbiddenException will be thrown.