Last updatedJul 16, 2019

User privacy guide for app developers

Early Access


Please note that this guide has been released for early access. The APIs referenced are still under development and are subject to change.


This guide describes how app developers can comply with user privacy requirements, as detailed by the General Data Protection Regulation (GDPR). On this page, you'll find information on your responsibilities as an app developer for Atlassian and instructions on how to meet these responsibilities.

In addition to this guide, you should read Data privacy guidelines for general guidelines on user privacy and Marketplace apps.

GDPR responsibilities for app developers

The GDPR governs the processing of personal data of individuals by an individual, company, or organization. As an app developer, you must ensure that your apps comply with the GDPR when handling the personal data for users. This includes:

  • Right to erasure (also known as Right to be Forgotten): If your app stores the personal data for a user and the user requests for their data to be erased, your app must erase the data.
  • Right to rectification: If your app stores the personal data for a user and the user changes their data, your app must either erase or update the data.
  • Right to be informed: You must inform users if you collect and use their personal data.

In order to comply with these requirements, we recommend that your apps do not store any user personal data and always retrieve current user data at the time of use using Atlassian APIs. This is the simplest and most reliable solution, as you don't need to worry about managing and reporting user personal data for your apps. If you choose this approach, you don't need to read the rest of this guide.

However, if you choose to store user personal data with your apps, Atlassian has built the following capabilities to help you comply with the GDPR:

  • The new Personal data reporting API lets you to report the user accounts that your apps are storing personal data for.
  • The reported data is made available to every user on their Atlassian Account profile, so that they can see which apps are storing their personal data.
  • For each user account reported, the Personal data reporting API returns whether each user's personal data must be erased or refreshed. You must erase or refresh the personal data for your apps accordingly.

Read the following sections on reporting data and storing data to learn how to use these capabilities.

Reporting user personal data for your apps

As an app developer, you are required to periodically report the user personal data that your apps are storing. You must report for each accountId (which is a short hand reference to an Atlassian Account ID). An accountId uniquely identifies a user across all Atlassian products. It is 1-128 characters long and may contain alphanumeric characters as well as - and : characters. Note that you must use accountIds to report personal data usage, even if the API permits other identifiers.

At a high level, this is how to do reporting for your apps:

  1. Compile the list of user accounts that your apps are storing personal data for.
  2. Use the polling resources for the Personal data reporting API to report the user accounts for your apps. See the reference documentation below for details.
  3. Based on the response, you may need to update or erase the personal data for users accordingly.
  4. Repeat this process periodically, as specified by the cycle period.

The cycle period defines the required period of time between sending reports for a given accountId. You can think about it as the maximum allowable staleness of reported data that is persisted in Atlassian. By default, the cycle period is 15 days. However, the polling resources may return a different cycle period (in the Cycle-Period header) that you must follow instead. Note that you should not send reports more frequently than the cycle period for each account, which helps limit the load on servers. This is enforced by rate limiting on the polling resources.

When setting up reporting for your apps, also consider the following recommendations:

  • Understand your reporting obligations: All apps storing personal data must report user personal data, using the Personal data reporting API.
    Your apps do not need to report when they proactively erase personal data for a user. Atlassian will apply a time to live (TTL) on the data reported by apps. This means an app may be listed in a user's profile for some period after the app has ceased storing personal data for that user.
  • Cater for interruptions: The polling iteration period is the period over which an app will iterate over all the accountIds to send reports for personal data usage. The longer the polling iteration period, the more likely the polling will be interrupted by events such as server restarts and app updates.
    This means that apps need to keep track of where they are within a poll period and have a means of resuming a poll cycle from this information. If this is too complex to implement, consider using a shorter polling iteration period instead.
  • Schedule around potential conflicts: Consider that scheduled actions by apps generally take place at particular times of the day, such as midnight or at the top of each hour. Don't schedule polling requests for your apps for specific times, so that there are not conflicts with other apps.
  • Handle account additions and deletions: The iteration logic for your apps must handle account additions and deletions. This will mean adjusting the polling rate and/or batch sizes.

Storing user personal data for your apps

In addition to reporting user personal data for your apps, you must ensure that you are storing user personal data for your apps correctly:

  • Track the age of personal data: Apps must track the age of the personal data retrieved from Atlassian. This must be sent in reports so that Atlassian can determine if the personal data is stale. If an app stores multiple aspects of personal data for an account, the age must correspond to the oldest time that the personal data was retrieved at.
  • Store a single copy of personal data: It is imperative that apps are able to report personal data usage accurately and reliably. To ensure that all personal data is erased when necessary, we recommend that the app only stores a single copy of the personal data within this address space and retrieves it when necessary. The obvious choice for an address space is a persistent store such as a database table that supports efficient querying by accountId.
  • Erase personal data when uninstalled: When an app is uninstalled, or consent is revoked in the case of 3LO, it should erase personal data that will no longer be needed.

Testing

The following accountIds should be used by vendors for testing:

  • Active: 5be24ad8b1653240376955d2
  • Closed: 5be24ba3f91c106033269289

There is no fixed accountId that can be used to test for the updated case.

Invalid API calls and regression testing

Atlassian will be monitoring correct usage of the API detailed in this guide. For example, our systems will detect the case of apps repeatedly checking the status of a closed account beyond a reasonable time frame. For this reason, repeated/regression testing of the closed account case should only be done using the closed test account provided above since we have blacklisted this accountId from our anomaly detection logic.

Personal data reporting API reference

The Personal data reporting API is a RESTful API that allows apps to report the user accounts for which they are storing personal data. For flexibility and efficiency, the API allows multiple accounts to be reported on in a single request.

The Personal data reporting API has two polling resources: one for reporting for Connect apps and another for reporting for OAuth 2.0 authorization code grants (3LO) apps:

These resources are described in detail below.

Report accounts for Connect apps

POST /rest/atlassian-connect/latest/report-accounts

Reports a list of user accounts and gets information on whether the personal data for each account needs to be updated or erased.
Authentication: JWT authentication. See the Authentication section of the REST API.

Parameters

This operation has no parameters.

Request

Content type: application/json
Each request allows up to 90 accounts to be reported on. For each account, the accountId and time that the personal data was retrieved must be provided. The time format is defined by RFC 3339, section 5.6.

Example request (application/json):

1
2
3
4
5
6
7
8
9
10
11
12
{
"accounts": [{
    "accountId": "account-id-a",
    "updatedAt": "2017-05-27T16:22:09.000Z"
  }, {
    "accountId": "account-id-b",
    "updatedAt": "2017-04-27T16:23:32.000Z"
  }, {
    "accountId": "account-id-c",
    "updatedAt": "2017-02-27T16:22:11.000Z"
  }]
}

Responses

  • 200 (Content type: application/json): The request is successful and one or more personal data erasure actions are required. The information is contained in an accounts array where each object identifies the accountId and whether the reason for the erasure is due to the closure of the account or invalidation of the app's copy of personal data due to the some update. In the case of the latter, the app is permitted to re-request personal data.

Example response (application/json):

1
2
3
4
5
6
7
8
9
{
  "accounts": [{
    "accountId": "account-id-a",
    "status": "closed"
  }, {
    "accountId": "account-id-c",
    "status": "updated"
  }]
}
  • 204: The request is successful and no action by the app is required, with respect to the accounts sent in the request.
  • 400: The request was malformed in some way. A body may be present, giving additional information.

Example response (application/json):

1
2
3
4
{
  "errorType": "string",
  "errorMessage": "string"
}
  • 403: The request is forbidden.
  • 429: Rate limiting applies. The app must follow the rate limiting directives provided in response headers.
  • 500: An internal server error occurred. A body may be present, giving additional information.

Example response (application/json):

1
2
3
4
{
  "errorType": "string",
  "errorMessage": "string"
}
  • 503: The service is currently unavailable. The service may be unavailable during initial development or due to an outage of an upstream dependency.

Report accounts for OAuth 2.0 authorization code grants (3LO) apps

POST https://api.atlassian.com/app/report-accounts/

Reports a list of user accounts and gets information on whether the personal data for each account needs to be updated or erased. This resource is for OAuth 2.0 authorization code grants (3LO) apps only.

Note, to use this API you must add the Personal data reporting API to your app from the APIs and features page in app management.

Authentication: OAuth 2.0 authorization code grants.

Parameters

This operation has no parameters.

Request

Content type: application/json
Each request allows up to 90 accounts to be reported on. For each account, the accountId and time that the personal data was retrieved must be provided. The time format is defined by RFC 3339, section 5.6.

Example request (application/json):

1
2
3
4
5
6
7
8
9
10
11
12
{
"accounts": [{
    "accountId": "account-id-a",
    "updatedAt": "2018-10-25T23:08:51.382Z"
  }, {
    "accountId": "account-id-b",
    "updatedAt": "2018-10-25T23:14:44.231Z"
  }, {
    "accountId": "account-id-c",
    "updatedAt": "2018-12-01T02:44:21.020Z"
  }]
}

Responses

  • 200 (Content type: application/json): The request is successful and one or more personal data erasure actions are required. The information is contained in an accounts array where each object identifies the accountId and whether the reason for the erasure is due to the closure of the account or invalidation of the app's copy of personal data due to the some update. In the case of the latter, the app is permitted to re-request personal data.

    Example response (application/json):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
      "accounts": [{
        "accountId": "account-id-a",
        "status": "closed"
      }, {
        "accountId": "account-id-c",
        "status": "updated"
      }]
    }
  • 204: The request is successful and no action by the app is required with respect to the accounts sent in the request.

  • 400: The request was malformed in some way. The response body contains an error message.

    Example response (application/json):

    1
    2
    3
    4
    {
      "errorType": "string",
      "errorMessage": "string"
    }
  • 429: Rate limiting applies. Delay by the time period specified in the Retry-After header (in seconds) before making the API call again.

  • 500: An internal server error occurred. The response body contains an error message.

    Example response (application/json):

    1
    2
    3
    4
    {
      "errorType": "string",
      "errorMessage": "string"
    }
  • 503: The service is unavailable.