Skip to content

Execute Privacy Requests

What is a Privacy Request?

A Privacy Request represents a request to perform an action on a user's identity data. The Request object itself identifies the user by email address, phone number, social security number, or other identifiable information. The data that will be affected and how it's affected is described in a Policy object that's associated with the Request.

For more information on policies, see the Configuring Policies guide.

Submit a Privacy Request

You submit a Privacy Request by calling the Submit a Privacy Request operation. Here, we submit a request to apply the a-demo-policy Policy to all target data in the Identity Graph that can be generated from the email address identity@example.com and the phone number +1 (123) 456 7891. Privacy Requests are executed immediately by default. This setting may be changed in the fidesops.toml configuration file.

POST /api/v1/privacy-request
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
[
  {
    "external_id": "a-user-defined-id",
    "requested_at": "2021-10-31T16:00:00.000Z",
    "policy_key": "a-demo-policy",
    "identity": {
      "email": "identity@example.com",
      "phone_number": "+1 (123) 456 7891"
    }
  }
]
  • external_id is an optional identifier of your own invention that lets you track the Privacy Request. See How-To: Report on Privacy Requests for more information.

  • requested_at (Optional) is an ISO8601 timestamp that specifies the moment that the request was submitted. Defaults to the created_at time if not specified.

  • policy_key identifies the Policy object to which this request will be applied. See How-To: Configure Request Policies for more information.

  • identities is an array of objects that contain data that identify the users whose data will be affected by the Policy. Each object identifies a single user by AND'ing the object's properties.

  • This request will submit a Privacy Request for execution that applies the a-demo-policy Policy to all target data in the Identity Graph that can be generated from the email address identity@example.com or the phone number +1 (123) 456 7891.

  • Specifying a external_id enables us to track this Privacy Request with that external_id later on. See How-To: Report on Privacy Requests for more information.
  • policy_key should correspond to a previously configured Policy object. See How-To: Configure Request Policies for more information.

A full list of attributes available to set on the Privacy Request can be found in the API docs.

Subject Identity Verification

To have users verify their identity before their Privacy Request is executed, set the subject_identity_verification_required variable in your fidesops.toml to TRUE. You must also set up an EmailConfig that lets fidesops send automated emails to your users.

When a user submits a PrivacyRequest, they will be emailed a six-digit code. They must supply that verification code to fidesops to continue privacy request execution. Until the Privacy Request identity is verified, it will have a status of: identity_unverified.

POST api/v1/privacy-request/{privacy_request_id}/verify
1
{"code": "<verification code here>"}

Request Notifications

By default, emails will be sent to users at various points in the request lifecycle.

To change this default behavior for any email type, set the variables under the notifications category in your fidesops.toml.

You must also set up an EmailConfig that lets fidesops send automated emails to your users. If using a custom privacy center, ensure that you intake an email identity, which is required for email notifications throughout fidesops.

Request Receipt

An email will be sent to users to notify them that their privacy request has been received.

Request Completion

Upon access request completion, an email will be sent to users to notify them of request completion, along with a link to download their data, if applicable.

Note

For security purposes, the data package download link is a one-time link and expires in 24 hrs by default. To change TTL, update the subject_request_download_link_ttl_seconds variable in your fidesops.toml.

Request Review

An email will be sent to users to notify them when their privacy request has been reviewed. If the privacy request was rejected, the email will include rejection reason.

Approve and deny Privacy Requests

To review Privacy Requests before they are executed, set the require_manual_request_approval variable in your fidesops.toml to TRUE.

To process Privacy Requests, send a list of Privacy Request IDs to the approve or deny endpoints. Both endpoints support processing requests in bulk.

PATCH api/v1/privacy-request/administrate/approve
1
2
3
4
5
6
{
  "request_ids":[
    "pri_2d181f15-486d-4bcf-a871-f50ed9f95673",
    "pri_2d181f15-486d-4bcf-a871-f50ed9f95673"
  ]
}

An optional denial reason can be provided when denying a Privacy Request:

PATCH api/v1/privacy-request/administrate/deny
1
2
3
4
5
6
7
{
  "request_ids":[
    "pri_2d181f15-486d-4bcf-a871-f50ed9f95673",
    "pri_2d181f15-486d-4bcf-a871-f50ed9f95673"
  ],
  "reason": "Requests denied because they're duplicates"
}

Monitor Privacy Requests

Privacy Requests can be monitored at any time throughout their execution by submitting any of the following requests:

GET api/v1/privacy-request?request_id=<privacy_request_id>

GET api/v1/privacy-request?external_id=<external_id>

For more detailed examples and further Privacy Request filtering in fidesops, see Reporting on Privacy Requests.

Restart failed Privacy Requests

To restart a failed Privacy Request from the failed collection, submit a request to:

POST /api/v1/privacy-request/<privacy_request_id>/retry

with an empty request body.

Integrate the Privacy Request flow into existing support tools

Alongside generic API interoperability, fidesops provides a direct integration with the OneTrust's DSAR automation flow.

  • Generic API interoperability: Third party services can be authorized by creating additional OAuth clients. Tokens obtained from OAuth clients can be managed and revoked at any time. See authenticating with OAuth for more information.

  • OneTrust: fidesops can be configured to act as (or as part of) the fulfillment layer in OneTrust's Data Subject Request automation flow. See the OneTrust integration guide for more information.

Encryption

You can optionally encrypt your access request results by supplying an encryption_key string in the request body: We will use the supplied encryption_key to encrypt the contents of your JSON and CSV results using an AES-256 algorithm in GCM mode. When converted to bytes, your encryption_key must be 16 bytes long. The data we return will have the nonce concatenated to the encrypted data.

POST /privacy-request
1
2
3
4
5
6
7
8
[
    {
        "requested_at": "2021-08-30T16:09:37.359Z",
        "identity": {"email": "customer-1@example.com"},
        "policy_key": "my_access_policy",
        "encryption_key": "test--encryption"
    }
]

Decrypt access request results

If you specified an encryption key, we encrypted the access result data using your key and an internally-generated nonce with an AES 256 algorithm in GCM mode. The return value is a 12-byte nonce plus the encrypted data that is all b64encoded together.

1
2
3
+------------------+-------------------+
| nonce (12 bytes) | message (N bytes) |
+------------------+-------------------+

For example, pretend you specified an encryption key of test--encryption, and the resulting data was uploaded to S3 in a JSON file: GPUiK9tq5k/HfBnSN+J+OvLXZ+GCisapdI2KGP7A1WK+dz1XHef+hWb/SjszdqdNVGvziyY6GF5KIrvrXgxjZuaAvgU='. You will need to implement something similar to the snippet below on your end to decrypt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import json
import base64
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

encrypted: str = "GPUiK9tq5k/HfBnSN+J+OvLXZ+GCisapdI2KGP7A1WK+dz1XHef+hWb/SjszdqdNVGvziyY6GF5KIrvrXgxjZuaAvgU=" 
encryption_key: str = "test--encryption".encode("utf-8")  # Only you know this

encrypted_combined: bytes = base64.b64decode(encrypted)
nonce: bytes = encrypted_combined[0:12]
encrypted_message: bytes = encrypted_combined[12:]
gcm = AESGCM(encryption_key)

decrypted_bytes: bytes = gcm.decrypt(nonce, encrypted_message, nonce)
decrypted_str: str = decrypted_bytes.decode("utf-8")

json.loads(decrypted_str)
1
>>> {"street": "test street", "state": "NY"}

If CSV data was uploaded, each CSV in the zipfile was encrypted using a different nonce, so you'll need to follow a similar process for each csv file.

Back to top