Some regions have data deletion regulations that require publishers to provide
users of their content a means of requesting deletion of their data. If your
Real-time Bidding integration uses first-party identifiers and receives
inventory from regions having data deletion regulations, Google recommends that
you integrate with [IAB's Data Deletion Request Framework](https://iabtechlab.com/standards/data-deletion-request-framework/).

When a user chooses to delete their identifiers from a publisher's app or site,
the Data Deletion Request Framework lets the publisher propagate a data
deletion request. The publisher sends a data deletion request to exchanges,
which can propagate the data deletion request to you. When you receive a data
deletion request, you must propagate the request to entities that you have
shared the publisher's first-party data with. For example, if you have an Open
Bidding integration, you must propagate the request to bidders on your exchange
that the first-party data has been shared with.

This guide covers initial setup of your Data Deletion Request Framework
integration with the Google exchange, and provides an overview of the Data
Deletion Request Framework workflow within the context of the Google
exchange. For additional guidance, see
[Data Deletion Request Framework](https://github.com/InteractiveAdvertisingBureau/Data-Subject-Rights/blob/main/Data%20Deletion%20Request%20Framework.md#data-deletion-request-framework).

## Set up your integration

To begin receiving data deletion requests from Google, you must register a
domain with Google that you want associated with your account, and host a
`dsrdelete.json` file at the root of your registered domain. To register your
domain with Google, contact your account manager. The `dsrdelete.json` file
serves several purposes, for example:

- Identifying the endpoint where Google sends data deletion requests.
- Listing your supported identifiers and how they are formatted.
- Specifying your public keys conforming to the JSON Web Key (JWK) standard, which other parties use to verify the authenticity of propagated data deletion requests or acknowledgements you send.

For details on the `drsdelete.json` file, such as the required and optional
fields you can populate, see [Discovery](https://github.com/InteractiveAdvertisingBureau/Data-Subject-Rights/blob/main/Data%20Deletion%20Request%20Framework.md#discovery).

Your endpoint specified in the `dsrdelete.json` file must receive and respond
to incoming data deletion requests. Google recommends using a cryptographic
library for your chosen programming language to verify the requests you
receive and sign the acknowledgements you send.

The following example sets a `dsrdelete.json` file with an endpoint,
identifiers, and public key:

    {
        "endpoint": "https://www.doubleclick.net/iab-ddrf",
        "identifiers": [
            { "id": 1, "type": "ppuid", "format": "plaintext" },
            { "id": 2, "type": "ifv", "format": "plaintext" },
            { "id": 3, "type": "sco", "format": "plaintext" }
        ],
        "publicKey": [
            {
                "kty": "EC",
                "crv": "P-256",
                "x": "_OPPeKSEdi3_JEHla93vOGTx8VD01ozhyYxwQzYCVLs",
                "y": "_XHufu2A_hbN5Uj4Wm7JPHE7ly0_4cmqntmz93pweys",
                "kid": "yUa3wQ",
                "use": "sig",
                "alg": "ES256"
            }
        ],
        "vendorScriptRequirement": false
    }

## Receive a data deletion request

Google propagates data deletion requests from publishers to you when all of the
following conditions are met:

- You host a valid `dsrdelete.json` file at a domain registered with Google.
- The publisher sends a data deletion request for an identifier to Google.
- Google determines that the publisher identifier sent in the data deletion request was shared with you.

When you receive a data deletion request, you are responsible for deleting the
specified data. You must also continue to propagate the data deletion request
to other data partners with whom you have shared the first-party publisher
data. Google supports data deletion requests for the following identifiers:

- `ppuid`: Publisher-provided identifiers.
- `sco`: Publisher first-party identifiers for web.
- `ifv`: Publisher first-party identifiers for iOS devices.

Google sends the data deletion request as an HTTP POST request to the endpoint
specified in your `dsrdelete.json` file. The body of the data deletion request
contains a [JSON Web Token (JWT)](https://www.rfc-editor.org/rfc/rfc7519) composed of
the following parts:

- A [JOSE Header](https://datatracker.ietf.org/doc/html/rfc7515#section-4) describing the encryption algorithm.
- A JWS Payload containing the deletion request.
- A JWS Signature to verify the authenticity of the request.

Google encodes the header, payload, and signature in base64, and formats these
items as follows:

    WEB_SAFE_BASE64_ENCODED_HEADER.WEB_SAFE_BASE64_ENCODED_PAYLOAD.WEB_SAFE_BASE64_ENCODED_SIGNATURE

To learn more about the distinct JWTs used in the data deletion framework, see
[JSON Web Token (JWT) Implementation](https://github.com/InteractiveAdvertisingBureau/Data-Subject-Rights/blob/main/Data%20Deletion%20Request%20Framework.md#json-web-token-jwt-implementation).
The data deletion request you receive from Google is a Request JWT (rqJWT),
which includes the Identity JWT (idJWT) that the publisher sent when requesting
the deletion.

### Find validation details in header

The header is a JSON object that describes the algorithm you must use to
produce a hash of the request, which is necessary for verifying the request's
authenticity. If the issuer has multiple private keys they can use to
produce a signature, the header also identifies which of the issuer's public
keys you can use to validate the signature.

The following example is a decoded header showing that you can use the RSA256
algorithm with key ID `abc123` to validate the signature:

    {
        "typ": "JWT",
        "alg": "RS256",
        "kid": "abc123"
    }

### Authenticate the request

You can verify that Google sent the data deletion requests with the public key
in the Google `dsrdelete.json` file. The Google `dsrdelete.json` file is hosted
at [https://static.doubleclick.net/dsrdelete.json](https://static.doubleclick.net/dsrdelete.json)

To verify the authenticity of the data deletion request, follow these steps:

1. Compute the hash of the header and payload using the algorithm identified in
   the header. The data passed to your hashing function must use the following
   structure:

       WEB_SAFE_BASE64_ENCODED_HEADER.WEB_SAFE_BASE64_ENCODED_PAYLOAD

2. Use the public key specified in the issuer's `dsrdelete.json` file to
   decrypt the decoded signature.

3. Compare the hash you generated in step one with the decrypted value from the
   signature. If these items match, the data deletion request is authentic.

### Parse the deletion request payload

After you have verified the authenticity of the data deletion request, you must
parse the payload to verify which identifier to delete. The decoded payload is
an rqJWT token. For details, see [rqJWT: Requester "request" JWT](https://github.com/InteractiveAdvertisingBureau/Data-Subject-Rights/blob/main/Data%20Deletion%20Request%20Framework.md#rqjwt-requester-request-jwt).

The following example shows a decoded payload as an rqJWT token and includes
optional parameters:

    {
        "optionalParameters": "{\"gamNetworkCode\":\"311057\"}",
        "sub": "{\n    \"identifierValue\": \"crvBtLjLqNUiafwXZiyukLD4Tf6mMUYhBdQaPZ0pjyd\",\n    \"identifierType\": \"ppid\",\n    \"identifierFormat\": \"plaintext\"\n  }",
        "iat": 1756257951,
        "version": "1.0",
        "iss": "test_publisher",
        "idJWT": "eyJhbGciOiJFUzI1NiIsImtpZCI6IkVodWR1USIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0ZXN0X3B1Ymxpc2hlciIsInN1YiI6IntcbiAgICBcImlkZW50aWZpZXJWYWx1ZVwiOiBcImNydkJ0TGpMcU5VaWFmd1haaXl1a0xENFRmNm1NVVloQmRRYVBaMHBqeWRcIixcbiAgICBcImlkZW50aWZpZXJUeXBlXCI6IFwicHBpZFwiLFxuICAgIFwiaWRlbnRpZmllckZvcm1hdFwiOiBcInBsYWludGV4dFwiXG4gIH0iLCJpYXQiOjE3NTYyNTc5NTEsInZlcnNpb24iOiIxLjAifQ.Dh17fv1sxKMnkOa7HOWfVdsIYo8BBy2p9SkDTSfZoW6ypMdl_5wDYtUIYEfuX3n6UbwMoH0WVgGQnFQraMH6XQ"
    }

The data deletion request includes the `sub` field, which contains a JSON
string indicating that the publisher is requesting deletion of a PPID with the
value `crvBtLjLqNUiafwXZiyukLD4Tf6mMUYhBdQaPZ0pjyd`. The rqJWT token includes
the encoded idJWT token. For details, see
[idJWT: Issuer "identifier" JWT](https://github.com/InteractiveAdvertisingBureau/Data-Subject-Rights/blob/main/Data%20Deletion%20Request%20Framework.md#idjwt-issuer-identifier-jwt).

## Propagate the data deletion request

You must propagate the data deletion request to any data partners with whom you
have shared the specified identifiers. For example, if you are integrated with
Open Bidding, you must propagate the data deletion request to bidders on your
exchange that the first-party identifier has been shared with. This process
requires you to send data partners a rqJWT token. The rqJWT token must contain
the relevant identifiers, formatted based on the configurations in the data
partner's `dsrdelete.json` file. Additionally, the rqJWT token must include
your signature generated with your private key.

## Acknowledge the data deletion request

To acknowledge that you have received and acted on the data deletion request,
send an Acknowledgement JWT to the endpoint Google specifies in the
`dsrdelete.json` file. For details, see
[acJWT: Recipient "acknowledgement" JWT](https://github.com/InteractiveAdvertisingBureau/Data-Subject-Rights/blob/main/Data%20Deletion%20Request%20Framework.md#acjwt-recipient-acknowledgement-jwt).

Your response's HTTP status code depends on the following outcome:

- **Success** : Return `HTTP 202` if the request was successfully received, parsed, and acted upon.
- **Failure** : Return `HTTP 400` if the request wasn't successfully received, parsed, and acted upon.

The request body must include an acJWT token with a payload that populates the
`raResultCode` field with an integer result code. You can optionally provide
descriptive text about the result in the `raResultString` field. The acJWT
token must include your signature generated with your private key.

To learn more about result codes supported in the Data Deletion Request
Framework, see [Result Codes](https://github.com/InteractiveAdvertisingBureau/Data-Subject-Rights/blob/main/Data%20Deletion%20Request%20Framework.md#result-codes).

### Build the acJWT token header

Populate the header based on the hash function and public key you intend the
recipient to use when verifying your signature. The unencoded header in the
following example indicates that you intend the recipient to use the ES256
algorithm to generate the hash, and that the recipient must use the public key
with key ID `EhuduQ` from your `dsrdelete.json` file when decrypting your
signature.

    {
        "alg": "ES256",
        "typ": "JWT",
        "kid": "EhuduQ"
    }

### Build the acJWT token payload

Populate the payload based on the outcome of the deletion request, and populate
the `rqJWT` field with the encoded form of the rqJWT token you are
acknowledging. The following example specifies a `raResultCode` field with the
value `0` to indicate that the operation is successful:

    {
        "version": "1.0",
        "jti": "965492b2-74e5-409a-90f4-f041902db05f",
        "raResultString": "",
        "iat": 1756408212,
        "iss": "doubleclick.net",
        "raResultCode": 0,
        "rqJWT": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkVodWR1USJ9.eyJvcHRpb25hbFBhcmFtZXRlcnMiOiJ7XCJnYW1OZXR3b3JrQ29kZVwiOlwiMzExMDU3XCJ9Iiwic3ViIjoie1xuICAgIFwiaWRlbnRpZmllclZhbHVlXCI6IFwiY3J2QnRMakxxTlVpYWZ3WFppeXVrTEQ0VGY2bU1VWWhCZFFhUFowcGp5ZFwiLFxuICAgIFwiaWRlbnRpZmllclR5cGVcIjogXCJwcGlkXCIsXG4gICAgXCJpZGVudGlmaWVyRm9ybWF0XCI6IFwicGxhaW50ZXh0XCJcbiAgfSIsImlhdCI6MTc1NjI1Nzk1MSwidmVyc2lvbiI6IjEuMCIsImlzcyI6InRlc3RfcHVibGlzaGVyIiwiaWRKV1QiOiJleUpoYkdjaU9pSkZVekkxTmlJc0ltdHBaQ0k2SWtWb2RXUjFVU0lzSW5SNWNDSTZJa3BYVkNKOS5leUpwYzNNaU9pSjBaWE4wWDNCMVlteHBjMmhsY2lJc0luTjFZaUk2SW50Y2JpQWdJQ0JjSW1sa1pXNTBhV1pwWlhKV1lXeDFaVndpT2lCY0ltTnlka0owVEdwTWNVNVZhV0ZtZDFoYWFYbDFhMHhFTkZSbU5tMU5WVmxvUW1SUllWQmFNSEJxZVdSY0lpeGNiaUFnSUNCY0ltbGtaVzUwYVdacFpYSlVlWEJsWENJNklGd2ljSEJwWkZ3aUxGeHVJQ0FnSUZ3aWFXUmxiblJwWm1sbGNrWnZjbTFoZEZ3aU9pQmNJbkJzWVdsdWRHVjRkRndpWEc0Z0lIMGlMQ0pwWVhRaU9qRTNOVFl5TlRjNU5URXNJblpsY25OcGIyNGlPaUl4TGpBaWZRLkRoMTdmdjFzeEtNbmtPYTdIT1dmVmRzSVlvOEJCeTJwOVNrRFRTZlpvVzZ5cE1kbF81d0RZdFVJWUVmdVgzbjZVYndNb0gwV1ZnR1FuRlFyYU1INlhRIn0.zZnuUsUDzkARg31RzkhLOJCSXD5jPca8qff5IqyYrrRITgRgm29T__6gC3oOOK5RAcd_AFFYWzE8onx6Kj1w8A"
    }