The OpenEdge Database includes robust multi-tenant support that manages physical access to tenant data through the means of a user identity and domain that can be controlled by an ABL application. This multi-tenant support allows an ABL application to serve multiple tenants within a single database. However, as an ABL developer, you need to make sure that access to multi-tenant data is managed properly to guarantee that tenant data remains available only to authorized users.

Each database connection has the concept of a current user identity. The database connection's current user identity on a multi-tenant database is associated with a tenancy and establishes all authorization to a tenant's private data. The database connection physically prevents access to another tenant's data until the connection’s current user identity is changed to another tenant.

In an ABL application, a client-principal object is used by the application to assert the current user identity for authorization to database tenant data. When that ABL business application is operating in a multi-session PAS for OpenEdge server, any one ABL session can be executing requests from different tenant users. The ABL application is responsible for maintaining synchronization between the database connection’s current user identity and the authenticated client identity for whom the application is executing a request.

An OpenEdge SQL database connection operates on the same principal, whereby the database connection’s current user identity is established when the SQL application client connects to the database with a user identity, an OpenEdge security domain specification, and a password. The SQL server’s database connection identity is retained for the lifetime of the connection, and only the tenant data that is authorized through the user identity can be accessed. The SQL application developer does not require synchronizing the database connection's current user identity and the tenant user for whom the database is connected.

The Safe User ID feature assists the PAS for OpenEdge's ABL application developer in maintaining the synchronization between the database's current user identity and the client for whom the tenant data is being accessed.

How coding errors can lead to tenant data bleed

The key factor in maintaining the integrity of access to tenant data is carefully managing the identity of the current user of the connection to the multi-tenant database. In a multi-tenant environment, the identity of the current user is associated with a tenancy. Managing the current user identity of the database connection regulates the physical access to tenant data that the ABL application code is authorized to access.

The phenomenon in which one's tenant's data becomes available to a user of a different tenant is referred to as tenant data bleed. An OpenEdge database connection prevents data bleed in most scenarios. However, if an ABL application has coding flaws in its identity management of the current OpenEdge database user identity, the ABL application can be the source where bleeding tenant data originates. Most of the ABL application data bleed scenarios stem from not correctly setting the multi-tenant database connection's user identity before accessing tenant data.

When the ABL application establishes a new current user identity in a database connection, three things occur:

  1. The multi-tenant database’s buffers are cleared of previously loaded tenant-specific data. Shared non-tenant tables or buffers for non-multi-tenant tables are not cleared.
  2. The access to physical tenant data in the database is authorized according to the user's tenancy.
  3. Access to tables and fields in the database is governed by the user's tenant authentication privileges.

The following coding errors have the potential to expose tenant data to unauthorized users:

  • A safe user identity is not established for database connections at application startup.

    For internal processes, an ABL application often needs to have access to shared non-tenant data that is stored in the OpenEdge database, without inadvertently having access to any specific user’s tenant data. Setting a safe user identity prevents any user identity failure from leaving the database connection in an undetermined state.

    The best practice of setting a safe user identity at database connection time, or at any time in the application’s lifecycle, prevents accidental inclusion of private tenant data during the application startup or re-initialization.

  • The database connection's current user identity is not initialized prior to accessing tenant data.

    When the PAS for OpenEdge ABL application session executes a client request, the user’s tenant identity is retained from what was set in the previous client request. When the current request’s user tenant identity and the current user identity of the database connection do not match, and the ABL application accesses the multi-tenant database, data bleed can occur.

    For example, User1@XYZ was the last user of the database connection in the previous client request. A subsequent request on the same connection is made by User2@ABC. If the user identity of the connection has not been changed to the current request user, User2@ABC could possibly see User1@XYZ’s tenant data.

    This situation can happen in an ABL application's Activate event procedure, or in any common initialization that executes at the beginning of each client request. In the event that the authentication fails, the previously connected user can be used if the proper error handling code is not provided by the ABL application.

    The best practice is for the ABL application to ensure that all code paths leading from the initiation of a client’s request has initialized the database connection’s current user identity, without errors, before any and all tenant data operations.

What is a safe user?

A safe user is an identity that has no tenant data access and has required access privileges to shared data. Ideally the safe user should be a placeholder identity that is defined in the user account store that is used by the PAS for OpenEdge instance in which the ABL application executes.

When an administrator wants to apply a safe user identity to a client’s session because the client is running a multi-tenant application, the administrator needs to control the identity that is used when a client request arrives. The identity that is used to connect the database at client startup should be the safe user, because this identity is used to set the agent session for this client request and will cause the agent to be reset to this safe user identity on any subsequent requests from the client session.

The database administrator is responsible for defining the identity of the safe user and ensuring its continuous availability for the lifetime of the running ABL application.. Designating the safe user has the following requirements:

  • The safe user identity will be used for all new database connection's initial user identity by using the -U/-P connection parameters.
  • The safe user must not have access to any non-blank tenant data.
  • The default blank user-id may not be used as a safe user.
  • A tenant or super-tenant user may not be used as a safe user because the safe user must not have access to any specific tenant data. (Note that the Safe User ID feature is for PAS for OpenEdge servers, and running as a super-tenant is highly discouraged.)
  • The safe user identity cannot be changed programmatically by the ABL application. The safe user identity is established when the database connection is made and remains unchanged for the lifetime of that connection. You can disconnect and reconnect to the database using a different identity by using the -U parameter, but once connected, the safe user identity remains until that database is disconnected.

When Safe User ID is configured on a multi-tenant database, the identity that is used to create the initial database connection is designated as the safe user. Therefore, the database administrator is responsible for ensuring that the safe user identity is always used when the initial database connection is created.

If you change the Safe User ID configuration in any way (for example, disable it, change the policy, and so on), that change does not take effect until you reconnect to the database.

After the Safe User ID is established by the DBA at initial database connection time, the ABL application is responsible for ensuring that it consistently uses the same safe user identity for any subsequent re-connections to the database.

For details about configuring the Safe User ID feature, see Configure Safe User ID in a multi-tenant database in Introduction to Database Multi-tenancy.

How Safe User ID protects tenant data

When the Safe User ID feature is enabled in a multi-tenant database, the identity of the initial database connection's current user user is automatically stored as the safe user identity and cannot be changed until the database is disconnected and reconnected. The database connection automatically sets its current user identity to this store safe user identity at either the beginning of the ABL session’s next client request or end of its current client request, according to the Safe User ID feature’s configuration.

By switching to a safe user at these events, any unhandled failure in establishing a new tenant user identity by the ABL application as part of the new client request cannot accidentally continue and access the tenant data using the identity retained from the previous request’s tenant.

As an added safety measure, if the safe user cannot be set as the database connection’s current user identity at any time, the database connection becomes locked. A locked condition does not permit access to any tenant data until a viable user identity can be set in the database connection. A locked condition can be detected by the ABL application so that it can choose the appropriate recovery process. To establish a new, viable safe user, the database must be disconnected and reconnected so that the safe user identity is the result of a database user login.

Note: The Safe User ID feature applies to only to PAS for OpenEdge clients of a multi-tenant database. Batch, GUI, character-based UI, and SQL clients do not implement this feature.

What happens during a client invocation

For each client request that is handled by an ABL application, the AVM executes any configured Activate and Deactivate event procedures at the beginning and completion of the request, respectively. The Activate and Deactivate event procedures encapsulate logic that executes automatically.

The Activate and Deactivate event procedures are executed whenever a PAS for OpenEdge agent receives a request of any kind during an agent session, irrespective of the session, application, or request type that is being executed by the agent. However, the safe user identity that is applied during the activation or deactivation of a request that is handled by an agent originates from a database connection that is initially started from a client that uses a connection to a database that is configured with the Safe User ID feature.

Coding the Activate and Deactivate event procedures in the ABL application is optional, but these procedures provide the appropriate place to perform whatever initialization, error handling, and cleanup operations are necessary with respect to executing the client request. Those event procedures also become appropriate points in a client request’s execution to have the database connection set the stored safe user identity.

For details about coding the Activate and Deactivate event procedures, see Programmatically use Safe User ID.

For other best practices in protecting tenant data, see Additional coding best practices.