ActivID Appliance Capabilities for GDPR Compliance

Right to Access and Data Portability

As part of the GDPR-compliance, organizations must be able to provide all user-specific data stored by ActivID Appliance when requested by that user.

To fulfill a user’s ‘right to access’ request, the relevant data must be extracted and then packaged so that it is made available to the end user. This section explains how to retrieve the user’s data using the ActivID Appliance REST APIs.

A sample (java code) is available on the ActivID Appliance Companion delivery disk (SDK/Samples/GDPR/gdpr-right-to-access-sample.zip) to illustrate how to perform the same programmatically. It exports all user data in readable JSON format. For usage instructions, refer to the sample’s readme.

Note: The ActivID Appliance consoles do not provide an integrated functionality to extract this data.
Prerequisites: The application must have permission to access the user’s data, specifically the Read User Details permission set for the user’s group.

The following information is returned:

  • User identification
  • User group
  • User roles
  • User consent to external (OpenID) applications (ATR_OICST)
  • List of authenticator references
  • List of device references
  • List of credential references
  • List of audit log events for the user (only includes the events already online; it does not include events from audit log archives).

For further information about the APIs, Getting Started with the ActivID Appliance OpenID API and Getting Started with the ActivID Appliance SCIM API

  1. Use the OpenID Connect API authn/token endpoint to authenticate the application and get an access_token:
  2. Copy

    Sample authentication request:

    POST https://[base-server-url]/{tenant}/authn/token HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    grant_type=client_credentials&client_id=ftadmin&client_secret=password03&scope=openid
    Copy

    Sample authentication response:

    HTTP/1.1 200 OK
    Content-Type: application/json;charset=UTF-8
    Content-Length: 756
    {
        "access_token": "DacOCAAAAWQYACyNrqu2eacHTZlbEBa6RYnFh0EE",
        "id_token": "eyJraWQiOiIxNTE3ODQzNjUwMT...OQ",
        "context": {"LEVEL_OF_ASSURANCE": "2"},
        "token_type": "Bearer",
        "expires_in": 14400
    }
  3. Call the SCIM API Users endpoint (/v2/Users/.search) to retrieve the user’s (in this example, myUser1) information.
  4. Copy

    Sample SCIM search user request:

    POST https://[base-server-url]/scim/{tenant}/v2/Users/.search HTTP/1.1
    Content-Type: application/scim+json
    Authorization: Bearer DacOCAAAAWQYACyNrqu2eacHTZlbEBa6RYnFh0EE
    Content-Length: 202
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:SearchRequest"],
        "filter": "externalId eq myUser1*",
        "sortBy": "id",
        "sortOrder": "descending",
        "startIndex": 0,
        "count": 100
    }
    Copy

    Sample SCIM search user response:

    HTTP/1.1 200 OK
    Content-Type: application/scim+json;charset=utf-8
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
        "totalResults": 1,
        "resources": [{
            "schemas": [
                "urn:ietf:params:scim:schemas:core:2.0:User",
                "urn:hid:scim:api:idp:2.0:UserDevice",
                "urn:hid:scim:api:idp:2.0:UserAttribute",
                "urn:hid:scim:api:idp:2.0:UserAuthenticator"
            ],
            "id": "11443",
            "externalId": "myUser1",
            "meta": {
                "resourceType": "User",
                "created": "2018-06-18T22:00:00Z",
                "location": "https://[base-server-url]/scim/{tenant}/v2/Users/11443",
                "version": "1"
            },
            "userName": "myUser1",
            "name": {
                "familyName": "U1LastName",
                "givenName": "U1FirstName"
            },
            "displayName": "U1FirstName U1LastName",
            "active": true,
            "emails": [{
                "value": "myUser1@company.com"
            }],
            "phoneNumbers": [{
                "value": "0101010101"
            }],
            "groups": [{
                "type": "Group",
                "display": "Consumer Online Banking",
                "value": "USG_CUST1",
                "$ref": "https://[base-server-url]/scim/{tenant}/v2/Groups/USG_CUST1"
            }],
            "roles": [],
            "urn:hid:scim:api:idp:2.0:UserAttribute": {
                "attributes": [{
                    "name": "DOB",
                    "type": "string",
                    "value": "20/06/2000",
                    "readOnly": false
                },
                {
                    "name": "ATR_MOBILE",
                    "type": "string",
                    "value": "0101010101",
                    "readOnly": false
                },
                {
                    "name": "LASTNAME",
                    "type": "string",
                    "value": "U1LastName",
                    "readOnly": false
                },
                {
                    "name": "FIRSTNAME",
                    "type": "string",
                    "value": "U1FirstName",
                    "readOnly": false
                },
                {
                    "name": "ATR_EMAIL",
                    "type": "string",
                    "value": "myUser1@company.com",
                    "readOnly": false
                },
                {
                    "name": "ATR_OICST",
                    "type": "string",
                    "value": "myApplication1:ATR_EMAIL,FIRSTNAME,LASTNAME,roles,ATR_MOBILE,groupids,ADDRESS",
                    "readOnly": false
                }]
            },
            "urn:hid:scim:api:idp:2.0:UserAuthenticator": {
                "authenticators": [{
                    "display": "AT_CUSTOTP",
                    "value": "11443.AT_CUSTOTP",
                    "$ref": "https://[base-server-url]/scim/{tenant}/v2/Authenticator/11443.AT_CUSTOTP"
                },
                {
                    "display": "AT_TDS",
                    "value": "11443.AT_TDS",
                    "$ref": "https://[base-server-url]/scim/{tenant}/v2/Authenticator/11443.AT_TDS"
                },
                {
                    "display": "AT_PASA",
                    "value": "11443.AT_PASA",
                    "$ref": "https://[base-server-url]/scim/{tenant}/v2/Authenticator/11443.AT_PASA"
                },
                {
                    "display": "AT_SMK",
                    "value": "11443.AT_SMK",
                    "$ref": "https://[base-server-url]/scim/{tenant}/v2/Authenticator/11443.AT_SMK"
                },
                {
                    "display": "AT_CUSTPW",
                    "value": "11443.AT_CUSTPW",
                    "$ref": "https://[base-server-url]/scim/{tenant}/v2/Authenticator/11443.AT_CUSTPW"
                }]
            },
            "urn:hid:scim:api:idp:2.0:UserDevice": {
                "devices": [{
                    "display": "ef0cbb2c-553a-4389-b528-dee5e360d277",
                    "value": "11446",
                    "$ref": "https://[base-server-url]/scim/{tenant}/v2/Device/11446"
                }]
            }
        }]
    }
  5. For each authenticator/device/credential reference, call the corresponding SCIM endpoint to get the detailed information.
  6. For example, to retrieve the information for the user’s customer static password authenticator:

    Copy
    GET https://[base-server-url]/scim/{tenant}/v2/Authenticator/11443.AT_CUSTPW HTTP/1.1
    Authorization: Bearer DacOCAAAAWQYACyNrqu2eacHTZlbEBa6RYnFh0EE
    Copy

    Returns:

    HTTP/1.1 200 OK
    Content-Type: application/scim+json;charset=utf-8
    {
        "schemas": [
            "urn:hid:scim:api:idp:2.0:Authenticator",
            "urn:hid:scim:api:idp:2.0:Password"],
        "id": "11443.AT_CUSTPW",
        "externalId": "myUser1",
        "meta": {
            "resourceType": "Authenticator",
            "created": "2019-06-19T12:19:00Z",
            "location": "https://[base-server-url]/scim/{tenant}/v2/Authenticator/11443.AT_CUSTPW",
            "version": "1"
        },
        "status": {
            "status": "ENABLED",
            "active": true,
            "expiryDate": "2024-06-18T12:19:00Z",
            "startDate": "2019-06-19T12:19:00Z"
        },
        "owner": {
            "type": "User",
            "display": "myUser1",
            "value": "11443",
            "$ref": "https://[base-server-url]/scim/{tenant}/v2/Users/11443"
        },
        "statistics": {
            "consecutiveFailed": "0",
            "consecutiveSuccess": "1",
            "lastSuccessfulChannel": "CH_SSP",
            "lastSuccessfulDate": "2018-06-19T12:19:39Z",
            "maximumNumberOfUsages": "1",
            "totalFailed": "0",
            "totalSuccess": "1"
        },
        "policy": {
            "display": "AT_CUSTPW",
            "value": "AT_CUSTPW",
            "$ref": "https://[base-server-url]/scim/{tenant}/v2/Policy/Authenticator/AT_CUSTPW"
        },
        "urn:hid:scim:api:idp:2.0:Password": {
            "username": "myUser1"
        }
    }
  7. Call the SCIM Event endpoint (/v2/Event/.search) to retrieve the audit log entries for the user.
  8. Copy

    Sample request:

    POST https://[base-server-url]/scim/{tenant}/v2/Event/.search HTTP/1.1
    Content-Type: application/scim+json
    Authorization: Bearer DacOCAAAAWQYACyNrqu2eacHTZlbEBa6RYnFh0EE
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:SearchRequest"],
        "filter": "resourceUris eq https://[base-server-url]/scim/{tenant}/v2/Users/11443",
        "count": 100
    }
    Copy

    Sample response as a list of JWT entries (shortened below for illustration purposes):

    HTTP/1.1 200 OK
    Content-Type: application/scim+json;charset=utf-8
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:EventList"],
        "eventTokens": [
            "eyJhbGciOiJub25..0VTUyJ9fQ.",
            "eyJhbGciOiJub25..J9fQ.",
            "eyJhbGciOiJub25l..iUkVTUE9OU0VfU1VDQ0VTUyJ9fQ.",
            "eyJhbGciOiJ0NFU....1MifX0.",
            "eyJhbGciOiJTUy...J9fQ.",
            "eyJhbGciOiJub25lI...In19.",
            "eyJhbGciOiJub25lI...yJ9fQ.",
            "eyJhbGciOiJub25lI..VUNDRVNTIn19.",
            "eyJhbGciOiJub25lIn...ifX0.",
            "eyJhbGciOiJub25l..fX0.",
            "eyJhbGciOiJub25lI...0NFU1MifX0.",
            "eyJhbGciOiJub25l...MifX0.",
            "eyJhbGciOiJub25lIn...0NFU1MifX0.",
            "eyJhbGciOiJub25lIn0....SRVNQT05TRV9TVUNDRVNTIn19.",
            "eyJhbGciOiJub25lIn0.ey..DRVNTIn19.",
            "eyJhbGciOiJub25lIn0.eyJ...TIn19.",
            "eyJhbGciOiJub25lIn0.eyJzY..VTUyJ9fQ.",
            "eyJhbGciOiJub25lIn0.eyJzY2..Q0NFU1MifX0.",
            "eyJhbGciOiJub25lIn0.eyJzY2h...TlNFX1NVQ0NFU1MifX0.",
            "eyJhbGciOiJub25lIn0.eyJzY2hlMifX0.",
            "eyJhbGciOiJub25lIn0.eyJzY2hlU1MifX0.",
            "eyJ...VzIjoiUkVTUE9OU0VfU1VDQ0VTUyJ9fQ.",
            "eyJhb......TIn19."
        ]
    }
  9. Parse each entry (JWT object) to get the displayable data.
  10. For example, parse the following JWT entry (using https://jwt.io/):

    Copy
    eyJhbGciOiJub25lIn0.eyJzY2hlbWFzIjpbInVybjppZXRmOnBhcmFtczpzY2ltOnNjaGVtYXM6bm90aWZ5OjIuMDpFdmVudCJdLCJpZCI6IkRFTU9ISURBUFAyXzEuOC41MiIsIm1ldGEiOnsicmVzb3VyY2VUeXBlIjoiRXZlbnQiLCJjcmVhdGVkIjoiMjAxOC0wNi0xOVQxMjoyMDoxOVoiLCJsb2NhdGlvbiI6Imh0dHBzOi8vZGVtb2hpZGFwcDIuYWN0aXZpZC1hcy5jb206ODQ0NS9zY2ltL09OTElORUJBTksvdjIvRXZlbnQvREVNT0hJREFQUDJfMS44LjUyIiwidmVyc2lvbiI6IjEifSwicmVzb3VyY2VVcmlzIjpbXSwidHlwZSI6InByaW1hcnlBdXRoZW50aWNhdGVEZXZpY2UiLCJhdHRyaWJ1dGVzIjpbImV2ZW50SWQiLCJkaXJlY3RVc2VyIiwic2VyaWFsTnVtYmVyIiwiY2hhbm5lbCIsImNvcnJlbGF0aW9uVHlwZSIsInBhbHNpIiwiZXZlbnRUeXBlIiwiYWxzaSIsIm1lc3NhZ2UiLCJyZXNwb25zZSIsImNvcnJlbGF0aW9uSWQiLCJhdXRoZW50aWNhdGlvblR5cGUiLCJob3N0QWRkcmVzcyIsInBhcmFtZXRlcnMiLCJzdGF0dXMiXSwidmFsdWVzIjp7ImV2ZW50SWQiOiJwcmltYXJ5QXV0aGVudGljYXRlRGV2aWNlIiwiZGlyZWN0VXNlciI6IjExNDQzIiwic2VyaWFsTnVtYmVyIjoiMTE0NDciLCJjaGFubmVsIjoiQ0hfVERTUFJPViIsImNvcnJlbGF0aW9uVHlwZSI6bnVsbCwicGFsc2kiOm51bGwsImV2ZW50VHlwZSI6bnVsbCwiYWxzaSI6ImNlODAxZWM0MWMxMTdiYzc1MmY5MmY5YzcwMGE5NTY4NmRiNTc2ODUxOTFmMTYzNTJiMzU1ODIyYjQ2YzQ4N2QiLCJtZXNzYWdlIjpudWxsLCJyZXNwb25zZSI6IlNVQ0NFU1MiLCJjb3JyZWxhdGlvbklkIjpudWxsLCJhdXRoZW50aWNhdGlvblR5cGUiOiJNb2JpbGUgUmVnaXN0cmF0aW9uIGF1dGhlbnRpY2F0aW9uIiwiaG9zdEFkZHJlc3MiOm51bGwsInBhcmFtZXRlcnMiOiJ7XCJBVENcIjpcIkFUX1REU09PQlwiLFwiREFNXCI6XCIxXCIsXCJEVENcIjpcIkRUX1REU09PQlwiLFwiQWN0aW9uXCI6XCJwcmltYXJ5QXV0aGVudGljYXRlRGV2aWNlXCIsXCJEU0RcIjpcIm51bGxcIixcIklTTlwiOlwibnVsbFwiLFwiQU5TXCI6XCJmYWxzZVwiLFwiQVJQXCI6XCJcIn0iLCJzdGF0dXMiOiJSRVNQT05TRV9TVUNDRVNTIn19.

    The entry decodes to the following (that is, the authentication at start of the HID Approve device registration process):

    Copy
    {
        "schemas": ["urn:ietf:params:scim:schemas:notify:2.0:Event"],
        "id": "DEMOHIDAPP2_1.8.52",
        "meta": {
            "resourceType": "Event",
            "created": "2018-06-19T12:20:19Z",
            "location": "https://[base-server-url]/scim/{tenant}/v2/Event/DEMOHIDAPP2_1.8.52",
            "version": "1"
        },
        "resourceUris": [],
        "type": "primaryAuthenticateDevice",
        "attributes": [ "eventId", "directUser", "serialNumber", "channel", "correlationType", "palsi", "eventType", "alsi", "message", "response", "correlationId", "authenticationType", "hostAddress", "parameters", "status" ],
        "values": {
            "eventId": "primaryAuthenticateDevice",
            "directUser": "11443",
            "serialNumber": "11447",
            "channel": "CH_TDSPROV",
            "correlationType": null,
            "palsi": null,
            "eventType": null,
            "alsi": "ce801ec41c117bc752f92f9c700a95686db57685191f16352b355822b46c487d",
            "message": null,
            "response": "SUCCESS",
            "correlationId": null,
            "authenticationType": "Mobile Registration authentication",
            "hostAddress": null,
            "parameters": "{\"ATC\":\"AT_TDSOOB\",\"DAM\":\"1\",\"DTC\":\"DT_TDSOOB\",\"Action\":\"primaryAuthenticateDevice\",\"DSD\":\"null\",\"ISN\":\"null\",\"ANS\":\"false\",\"ARP\":\"\"}",
        "status": "RESPONSE_SUCCESS"
        }
    }

You can then package all the extracted information for the user. The delivered sample dumps the extracted data to a file using the JSON format.

Obtaining User Consent

ActivID Appliance provides an embedded mechanism to capture the consent of the user (data subject) when an application requires access to their personal data.

Note:  
  • This feature is optional. Alternatively, the Data Controller can comply with the GDPR requirements by requesting access to the subject’s personal data outside of ActivID Appliance interfaces.
  • End users cannot review/update/delete their consent to applications using the ActivID Appliance consoles.
Important: This mechanism is only available for applications using the ActivID OAuth/OpenID Connect API authentication endpoint.
  • The user consent to external (OpenID) applications is stored in the ATR_OICST user attribute.
  • The user consent capture can be deactivated by OpenID application.

The user can view their captured consent by requesting access to their data. The consent is the value of the ATR_OICST attribute. For example, the following shows the captured consent that the user has given to the OPENID application myApplication1:

Copy
{
    "name": "ATR_OICST",
    "type": "string",
    "value": "myApplication1:ATR_EMAIL,FIRSTNAME,LASTNAME,roles,ATR_MOBILE,groupids,ADDRESS",
    "readOnly": false
}

For further details about user claims and consent capture, see Enabling OpenID Connect Claims and Prompting User for Consent.

Right to be Forgotten

Also known as Data Erasure, the right to be forgotten entitles the Data Subject to have their personal data deleted by Data Controllers. The right to be forgotten also enables them to halt or cease further distribution and use of the data by third parties.

In the context of ActivID Appliance, the user’s ‘right to be forgotten’ can be exercised in two different ways:

  • The delete user function will erase all operational data from the ActivID Appliance database, except the table containing the mapping PII data/replacement token values (see Anonymizing Data in the Audit Log). Therefore, you can still search the Audit trail for this user.
  • The forget user functionality will erase the mapping PII data/replacement token values. Therefore, the events for this user in the audit trail (online or archive audit trail files) cannot be linked to the user anymore (as the tokens cannot be converted back to user PII values).
  • Note: Audit log tokenization must be enabled (default setting). If it is disabled, the Forget user feature is not applicable and will have no effect.

Both operations can be applied using the:

Deciding whether to use only ‘deleteUser’ or also ‘forgetUser’ depends on the legal context in which the Data Controller operates (for instance, if legal archiving constraints apply to the audit trail, it is recommended that the Data Controller verifies the application of ‘forgetUser’ by the legal department).