DLP Kit Development

Data Loss Prevention (DLP) Kit is a system solution provided to prevent leakage of sensitive data. It provides a file format called DLP. A DLP file consists of the original file in ciphertext and the authorization credential, and ".dlp" is added to the end of the original file name (including the file name extension), for example, test.docx.dlp.

A DLP file can be accessed only after a device-cloud authentication (network connection required) is successful. The permissions for accessing a DLP file include the following:

  • Read-only: The user can only view the file.
  • Edit: The user can read and write the file, but cannot change the permission on the file.
  • Full control: The user can read and write the file, change the permission on the file, and restore the plaintext of the file.

When an app accesses a DLP file, the system automatically installs a DLP sandbox app for the app. As a twin app of the app, the sandbox app inherits data and configuration from the app, but is isolated from the app. The twin app is running in a DLP sandbox, which is restricted from external access to prevent data leakage. Each time a DLP file is opened, a sandbox app is generated. The sandbox apps are also isolated from each other. When an app is closed, its sandbox app will be automatically uninstalled and the temporary data generated in the sandbox directory will be cleared.

Normally, the app is unaware of the sandbox and accesses the file in plaintext, like accessing a common file. However, the DLP sandbox restricts the app from accessing external resources (such as the network, clipboard, screenshot capturing, screen recording, and Bluetooth). For better user experience, you need to make adaptation for your app. For example, for a read-only file, you'd better hide the Save button and disable automatic network connection.

Sandbox Restrictions

For an app in the DLP sandbox state, the permissions granted to the app are restricted based on the permission on the DLP file.

App Permission Description Read Only Edit/Full Control
ohos.permission.USE_BLUETOOTH Allows an app to use Bluetooth. Unavailable Unavailable
ohos.permission.INTERNET Allows an app to access the Internet. Unavailable Unavailable
ohos.permission.DISTRIBUTED_DATASYNC Allows an app to exchange user data (such as images, music, videos, and app data) with another device. Unavailable Unavailable
ohos.permission.WRITE_MEDIA Allows an app to read and write media files, such as images, videos, and audio clips. Unavailable Available
ohos.permission.NFC_TAG Allows an app to use NFC. Unavailable Available

Available APIs

API Description
isDLPFile(fd: number): Promise<boolean>
isDLPFile(fd: number, callback: AsyncCallback<boolean>): void
Checks whether a file is a DLP file.
getDLPPermissionInfo(): Promise<DLPPermissionInfo>
getDLPPermissionInfo(callback: AsyncCallback<DLPPermissionInfo>): void
Obtains the DLP permission information of this sandbox app.
getOriginalFileName(fileName: string): string Obtains the original name of a DLP file.
getDLPSuffix(): string Obtains the file name extension of this DLP file.
on(type: 'openDLPFile', listener: Callback<AccessedDLPFileInfo>): void Subscribes to the file open event of DLP files. The app will be notified when a DLP file is opened.
off(type: 'openDLPFile', listener?: Callback<AccessedDLPFileInfo>): void Unsubscribes from the file open event of DLP files.
isInSandbox(): Promise<boolean>
isInSandbox(callback: AsyncCallback<boolean>): void
Checks whether this app is running in a sandbox.
getDLPSupportedFileTypes(): Promise<Array<string>>
getDLPSupportedFileTypes(callback: AsyncCallback<Array<string>>): void
Obtains the file name extension types that can be appended with .dlp.
setRetentionState(docUris: Array<string>): Promise<void>
setRetentionState(docUris: Array<string>, callback: AsyncCallback<void>): void
Sets the sandbox app retention state. If the retention state is set for a DLP file, the sandbox app will not be automatically uninstalled when the DLP file is closed.
cancelRetentionState(docUris: Array<string>): Promise<void>
cancelRetentionState(docUris: Array<string>, callback: AsyncCallback<void>): void
Cancels the sandbox app retention state.
getRetentionSandboxList(bundleName?: string): Promise<Array<RetentionSandboxInfo>>
getRetentionSandboxList(bundleName: string, callback: AsyncCallback<Array<RetentionSandboxInfo>>): void
getRetentionSandboxList(callback: AsyncCallback<Array<RetentionSandboxInfo>>): void
Obtains the sandbox apps in the retention state.
getDLPFileAccessRecords(): Promise<Array<AccessedDLPFileInfo>>
getDLPFileAccessRecords(callback: AsyncCallback<Array<AccessedDLPFileInfo>>): void
Obtains the DLP files that are accessed recently.
setSandboxAppConfig(configInfo: string): Promise<void> Sets sandbox app configuration.
getSandboxAppConfig(): Promise<string> Obtains the sandbox app configuration.
cleanSandboxAppConfig(): Promise<void> Clears the sandbox app configuration.
startDLPManagerForResult(context: common.UIAbilityContext, want: Want): Promise<DLPManagerResult>
Starts the DLP manager app on the current UIAbility page in borderless mode (available only for the stage model).

How to Develop

  1. Import the dlpPermission module.

    import dlpPermission from '@ohos.dlpPermission';
    
  2. Open a DLP file. The system automatically installs a DLP sandbox app for your app.
    Add the following code to your app:

    async OpenDlpFile(dlpUri: string, fileName: string, fd: number) {
      let want:Want = {
        "action": "ohos.want.action.viewData",
        "bundleName": "com.example.example_bundle_name",
        "abilityName": "exampleAbility",
        "uri": dlpUri,
        "parameters": {
          "fileName": {
            "name": fileName
          },
          "keyFd": {
            "type": "FD",
            "value": fd
          }
        }
      }
    
      try {
        console.log('openDLPFile:' + JSON.stringify(want));
        console.log('openDLPFile: delegator:' + JSON.stringify(this.context));
        this.context.startAbility(want);
      } catch (err) {
        console.error('openDLPFile startAbility failed', (err as BusinessError).code, (err as BusinessError).message);
        return;
      }
    }
    

    Add ohos.want.action.viewData to the module.json5 file.

      "skills":[
        {
          "entities":[
            ...
          ],
          "actions":[
            ...
            "ohos.want.action.viewData"
          ]
        }
      ]
    
  3. Check whether the app is running in a sandbox.

    dlpPermission.isInSandbox().then((data)=> {
      console.log('isInSandbox, result: ' + JSON.stringify(data));
    }).catch((err:BusinessError) => {
      console.log('isInSandbox: ' + JSON.stringify(err));
    });
    
  4. Obtain the permissions on the file. The permissions of the DLP sandbox app vary with the user's permission on the file. For more information, see Sandbox Restrictions.

    dlpPermission.getDLPPermissionInfo().then((data)=> {
      console.log('getDLPPermissionInfo, result: ' + JSON.stringify(data));
    }).catch((err:BusinessError) => {
      console.log('getDLPPermissionInfo: ' + JSON.stringify(err));
    });
    
  5. Obtain information about the file name extension types that support the DLP solution. Based on the information obtained, you can learn what types of files can be used to generate DLP files.

    dlpPermission.getDLPSupportedFileTypes((err, result) => {
      console.log('getDLPSupportedFileTypes: ' + JSON.stringify(err));
      console.log('getDLPSupportedFileTypes: ' + JSON.stringify(result));
    });
    
  6. Check whether the opened file is a DLP file.

    import dlpPermission from '@ohos.dlpPermission';
    import fs from '@ohos.file.fs';
    import { BusinessError } from '@ohos.base';
    
    let uri = "file://docs/storage/Users/currentUser/Desktop/test.txt.dlp";
    let file = fs.openSync(uri);
    try {
      let res = dlpPermission.isDLPFile(file.fd);  // Check whether the file is a DLP file.
      console.info('res', res);
    } catch (err) {
      console.error('error', (err as BusinessError).code, (err as BusinessError).message); // Throw an error if the operation fails.
    }
    fs.closeSync(file);
    
  7. Subscribe to or unsubscribe from the DLP file open event.

    event(info: dlpPermission.AccessedDLPFileInfo) {
      console.info('openDlpFile event', info.uri, info.lastOpenTime)
    }
    unSubscribe() {
      try {
        dlpPermission.off('openDLPFile', this.event); // Unsubscribe from the file open event.
      } catch (err) {
        console.error('error', (err as BusinessError).code, (err as BusinessError).message); // Throw an error if the operation fails.
      }
    }
    subscribe() {
      try {
        dlpPermission.on ('openDLPFile' , this.event); // Subscribe to the DLP file open event.
      } catch (err) {
        console.error('error', (err as BusinessError).code, (err as BusinessError).message); // Throw an error if the operation fails.
      }
    }
    onCreate() {
     this.subscribe();
    }
    onDestroy() {
     this.unSubscribe();
    }
    
  8. Obtain information about the DLP files that are recently accessed.

    async getDLPFileAccessRecords() {
      try {
        let res:Array<dlpPermission.AccessedDLPFileInfo> = await dlpPermission.getDLPFileAccessRecords(); // Obtain the list of recently accessed DLP files.
        console.info('res', JSON.stringify(res))
      } catch (err) {
        console.error('error', (err as BusinessError).code, (err as BusinessError).message); // Throw an error if the operation fails.
      }
    }
    
  9. Obtain information about the DLP sandbox apps in the retention state.

    async getRetentionSandboxList() {
      try {
        let res:Array<dlpPermission.RetentionSandboxInfo> = await dlpPermission.getRetentionSandboxList(); // Obtain the sandbox apps in the retention state.
        console.info('res', JSON.stringify(res))
      } catch (err) {
        console.error('error', (err as BusinessError).code, (err as BusinessError).message); // Throw an error if the operation fails.
      }
    }
    
  10. Set sandbox app configuration.

    async setSandboxAppConfig() {
      try {
        await dlpPermission.setSandboxAppConfig('configInfo'); // Set sandbox app configuration.
      } catch (err) {
        console.error('error', (err as BusinessError).code, (err as BusinessError).message); // Throw an error if the operation fails.
      }
    }
    
  11. Clear the sandbox app configuration.

    async cleanSandboxAppConfig() {
      try {
        await dlpPermission.cleanSandboxAppConfig(); // Clear the sandbox app configuration.
      } catch (err) {
        console.error('error', (err as BusinessError).code, (err as BusinessError).message); // Throw an error if the operation fails.
      }
    }
    
  12. Obtain the sandbox app configuration.

    async getSandboxAppConfig() {
      try {
        let res:string = await dlpPermission.getSandboxAppConfig(); // Obtain the sandbox app configuration.
        console.info('res', JSON.stringify(res))
      } catch (err) {
        console.error('error', (err as BusinessError).code, (err as BusinessError).message); // Throw an error if the operation fails.
      }
    }
    
  13. Start the DLP manager app in borderless mode. This API can be called only in the UIAbility context and supports only the stage model.

    import dlpPermission from '@ohos.dlpPermission';
    import common from '@ohos.app.ability.common';
    import AbilityConstant from '@ohos.app.ability.AbilityConstant';
    import UIAbility from '@ohos.app.ability.UIAbility'
    import Want from '@ohos.app.ability.Want';
    import { BusinessError } from '@ohos.base';
    
    try {
      let context = getContext () as common.UIAbilityContext; // Obtain the UIAbility context.
      let want: Want = {
        "uri": "file://docs/storage/Users/currentUser/Desktop/1.txt",
        "parameters": {
          "displayName": "1.txt"
        }
      }; // Request parameters.
      dlpPermission.startDLPManagerForResult(context, want).then((res) => {
        console.info('res.resultCode', res.resultCode);
        console.info('res.want', JSON.stringify(res.want));
      }); // Start the DLP manager app.
    } catch (err) {
      console.error('error', err.code, err.message); // Report an error upon a failure.
    }