Application Packaging Standard

Last updated 18-Mar-2019

Personal Data

General Data Protection Regulation (GDPR) of the European Union (EU) declares the protection of natural persons with relation to the processing and movement of personal data as a fundamental right of everyone.

The platform takes care of personal data in accordance with GDPR. However, some personal data can be also processed and stored by APS applications and original cloud applications integrated with the platform.

That is why, an APS application that is supposed to store and process personal data in the GDPR territorial scope must do it in compliance with the Lawfulness of processing declared in GDPR and implement a set of GDPR-related operations as presented in this document.

GDPR APS Type

A GDPR-compliant APS application must implement the GDPRSupport APS type. This must be declared in the same APS type that also implements the Application APS type as in the following example:

"implements": [
   "http://aps-standard.org/types/core/application/1.0",
   "http://www.odin.com/gdpr-support/1.0"
],

The respective APS connector must define the methods to implement the operations declared in the GDPRSupport APS type. The following sections contain examples of those methods valid if running in the APS PHP framework.

Right to Access Personal Data

Operations

The platform and integrated applications can contain personal data as properties of users and personal accounts.

Note

In the platform, a customer can be of two types: personal account or company. You specify it when creating or editing a customer in the BSS provider control panel.

There are a number of cases when data subjects can request their personal data, for example:

For those purposes, an APS application must implement the following operations:

  • groups - returns a set of keys used to identify a person or a personal account in the application. The keys are arranged into groups. For example, one of the groups can be “contacts” containing the “email”, “phoneOffice”, and “phoneMobile” keys.
  • userInfo - returns a set of keys with values assigned to a requested user.
  • accountInfo - returns a set of keys with values assigned to a requested personal account.

Note

The PHP code presented in the examples below is based on PHP Framework, whose version is not less than 7.4-104.

Groups of Personal Data

If an APS application stores personal data, it must classify the data as groups of properties. Every group must have its own ID and contain several keys, each identifying a property. The APS connector must return all those groups to the APS controller when the latter calls the groups() method defined in the APS connector.

In the following example, the groups() method returns three groups (names, contacts, and address), each containing several keys:

/**
* @verb(GET)
* @path("/groups")
* @return("http://www.odin.com/gdpr-support/1.0#Group[]")
*/
public function groups()
{
   return array(
       array(
           'groupId' => 'name',
           'description' => 'Full name',
           'keys' => array(
               array(
                   'keyId' => 'firstName',
                   'keyDescription' => 'First name'
               ),
               array(
                   'keyId' => 'middleName',
                   'keyDescription' => 'Middle name(s)'
               ),
               array(
                   'keyId' => 'lastName',
                   'keyDescription' => 'Last name'
               )
           )
       ),
       array(
           'groupId' => 'contacts',
           'description' => 'Phone, mail, and IM contacts',
           'keys' => array(
               array(
                   'keyId' => 'emailCorporate',
                   'keyDescription' => 'Corporate email address'
               ),
               array(
                   'keyId' => 'phoneOffice',
                   'keyDescription' => 'Office phone'
               ),
               array(
                   'keyId' => 'phoneMobile',
                   'keyDescription' => 'Mobile phone'
               )
           )
       ),

       array(
           'groupId' => 'address',
           'description' => 'Postal address',
           'keys' => array(
               array(
                   'keyId' => 'street',
                   'keyDescription' => 'Street address'
               ),
               array(
                   'keyId' => 'city',
                   'keyDescription' => 'City name'
               ),
               array(
                   'keyId' => 'state',
                   'keyDescription' => 'State name'
               ),
               array(
                   'keyId' => 'country',
                   'keyDescription' => 'Full postal address'
               )
           )
       )
   );
}

User and Account Information

Every personal property assigned to a user or account and stored in the application must be mapped to a key specified in one of the groups. To get all personal data assigned to a user or personal account stored in the application, the APS controller calls the userInfo(UUID) or accountInfo(UUID) operation respectively. The input of the operation is the APS ID of a requested resource (user or account respectively).

In the following example, the userInfo($uuid) PHP method returns some personal data assigned to a requested user:

/**
* @verb(GET)
* @path("/userInfo")
* @param(string,query)
* @return("http://www.odin.com/gdpr-support/1.0#GDPRIdentity")
*/
public function userInfo($uuid)
{
   $identity = new stdClass();
   $identity->uuid = $uuid;

   // App specific - collect all personal data in a set named $user in the example below

   $info = array(
       array(
           'groupId' => 'name',
           'key' => 'firstName',
           'value' => $user->givenName
       ),
       array(
           'groupId' => 'name',
           'key' => 'lastName',
           'value' => $user->familyName
       ),
       array(
           'groupId' => 'contacts',
           'key' => 'emailCorporate',
           'value' => $user->email
       ),
       array(
           'groupId' => 'contacts',
           'key' => 'phoneOffice',
           'value' => $user->telWork
       ),
       array(
           'groupId' => 'contacts',
           'key' => 'phoneMobile',
           'value' => $user->telCell
       ),
       array(
           'groupId' => 'address',
           'key' => 'street',
           'value' => $user->addressPostal->streetAddress
       ),
       array(
           'groupId' => 'address',
           'key' => 'city',
           'value' => $user->addressPostal->locality
       ),
       array(
           'groupId' => 'address',
           'key' => 'state',
           'value' => $user->addressPostal->region
       ),
       array(
           'groupId' => 'address',
           'key' => 'country',
           'value' => $user->addressPostal->countryName
       )

   );
   $identity->info = $info;
   return $identity;
}

In a case when an application does not store APS IDs and identifies users by another property, for example, by email address, the application can send back its request to the APS controller to retrieve the needed property. For example, it can get the email address of the requested user by using the following code that includes a request to the APS controller:

$apsc = \APS\Request::getController();
try { $user = $apsc->getResource($uuid); }
catch(Exception $e) {
     return "";
}
$email = $user->email;

In the above example, the try and catch pair excludes an unexpected termination of the method in a case when the application has no rights to the specified user or for any other reasons.

Right to Be Forgotten

In compliance with the right to be forgotten, the platform creates a periodic task to erase personal data of requested users and personal accounts from the platform and from the GDPR compliant applications.

../../../_images/gdpr-periodic-task.png

The task will request the APS applications to run the corresponding methods responsible for the considered right:

  • forgetUser - does some GDPR compliant actions to erase personal data from a requested user.
  • forgetAccount - does some GDPR compliant actions to erase personal data from a requested account.

The following is a structure of the forgetUser($user) method in PHP:

/**
* @verb(POST)
* @path("/forgetUser")
* @param(object,body)
* @return("http://www.odin.com/gdpr-support/1.0#Result")
*/
public function forgetUser($user)
{
   $info = new stdClass();

   // Some code that erases personal data...

   $info->status = true;
   $info->message = "All personal data was erased for the specified user."
   return $info;
}

Activation of GDPR Operations

Allowed Operations

The provider control panel contains a page that allows the provider’s GDPR officer to run the following operations:

  • Request for personal data of a specified user or personal account.
  • Erase personal data of a specified user or personal account.

The built-in GDPR manager allows the GDPR officer to erase personal data if the following conditions are met:

Resource Conditions
Service user
Disabled
No services assigned
Staff member
Disabled
No services assigned
Personal account
Disabled (must be canceled or put on hold in BSS)
One user - disabled staff member
No subscriptions
No domains
No brands

Resources with Personal Data

In the provider control panel, the resources are identified by internal digital ID. The built-in GDPR manager works with the following types of resources:

Probably, you noticed that the IDs are unique only within the scope of a list. It means, the same ID can be assigned to a resource in every of the mentioned above lists. The GDPR manager will process personal data of all the resources matching a requested ID.

Typical Operations

The following is a typical life-cycle of GDPR operations.

  1. Navigate to Services > Data Protection, where you can activate GDPR operations.

    ../../../_images/get-info.png
  2. To get personal data, enter the digital ID of a user or personal account and click Search. The platform will request the APS controller to poll the GDPR compatible applications for the resources identified by the specified ID. If the requested ID belongs to a user, the APS controller will send the following requests:

    GET <base-URL>/<app-service>/<appResource-APS-ID>/groups
    
    GET <base-URL>/<app-service>/<appResource-APS-ID>/userInfo?<userResource-APS-ID>
    

    For example:

    GET https://endpoint.isv1.apsdemo.org/vpsdemo/clouds/5bfa3afb-1996-45d1-b27f-9d3e833e68e9/groups
    
    GET https://endpoint.isv1.apsdemo.org/vpsdemo/clouds/5bfa3afb-1996-45d1-b27f-9d3e833e68e9/userInfo?uuid=044c0c17-5a95-0388-079d-743ba7a70dc1
    

    In the following response, the requested user is Enabled (active):

    ../../../_images/eric-active.png

    The panel shows the data returned by APS applications and the data stored in the platform itself.

  3. The previous step showed that you cannot remove personal data from an active user. For that purpose, the user must be disabled:

    ../../../_images/eric-disabled-cannot-remove.png

    However, if a service (an application resource) is still assigned to a disabled user, you cannot remove the user’s personal data either. You should use the customer control panel to find out the services assigned to the user:

    ../../../_images/eric-disabled-service.png
  4. Only after the user is disabled and does not have any application resource assigned, the provider can request removal of the user’s personal data. For this purpose, click Erase Personal Data:

    ../../../_images/eric-disabled-can-remove.png

    For every personal data group, you can either delay the erasure of personal data or require it in the next run of the periodic task:

    ../../../_images/eric-removal-1-now.png

    The requested user ID will be added to the periodic task mentioned earlier in this document. The periodic task, when activated will force the APS controller to call the forgetUser operation and pass to it the user APS ID and a list of personal data group IDs whose properties must be erased:

    POST <base-URL>/<app-service>/<appResource-APS-ID>/forgetUser
    
    { "uuid": "<userResource-APS-ID", "email":"<email-address>", "groupIds":["<group IDs>"] }
    

    For example:

    POST /user-gdpr/clouds/5bfa3afb-1996-45d1-b27f-9d3e833e68e9/forgetUser
    
    {"uuid":"044c0c17-5a95-0388-079d-743ba7a70dc1","email":"ms@aps.test","groupIds":["users_data","marketing_data"]}
    

    Note

    Do not expect the operation to run immediately as it will only be scheduled.

  5. On successful completion of the last operation, the user’s personal data does not show up anymore:

    ../../../_images/eric-removed.png