Guidelines for Testing Profile Visibility Controls

Note: These guidelines are still being drafted and when finalized will be published in our developer documentation. This information is subject to change. We wanted to get this information to you as soon as possible, even in draft state, to help better prepare you for testing.

We here at Atlassian believe in working openly, because when work is open we unleash the full potential in every team. In order to be open and work more openly, users need to be able to trust that they have control over their personal data.

Introducing new profile visibility control settings

We are introducing new profile visibility controls which will allow users to hide or unhide parts of their Atlassian Account profile. Fields that are currently returned in the user object today, like email address, may not show up (or may be empty), depending upon the user’s profile visibility control settings.

Timeline for changes

We intend to launch new profile visibility control settings through Atlassian Account to Jira Cloud, Confluence Cloud, and Bitbucket Cloud in late-May.

We are providing a window to test your app with profile visibility control settings prior to launch. This window will begin on March 11, 2019 and end on 2019-05-16T07:00:00Z.

In order to begin testing your app you will need to have a (a) cloud developer instance set up that responds to profile visibility control settings and (b) Atlassian Accounts that have the new profile visibility control screen exposed. In addition, apps that require email address for core functionality will need to submit their use case and be approved to use a new API for exposing email address.

How to set-up your test environments

Start a new cloud developer instance. You can start a free cloud developer instance here.

After you’ve created a developer environment you’ll need to raise a request with our Developer Support team to finish set-up.

Include accountIDs for test users in your request.

These users will be shown the new profile visibility control settings screen in their Atlassian Account, however, the profile visibility controls will only work on the test instances that you’ve identified in your Developer Support ticket.

If you are using a free developer instance you will be limited to testing with 5 users. App users will count as one of those users. Before adding users see the test scenarios described below in order to determine who you should add to your test environment.

How to find accountIDs

To get the account ID of users on your test instance:

  1. Navigate to User Management

  1. Scroll down to see the list of users on your instance
  2. Click Show details
  3. View URL - The URL contains the accountID for the user you are viewing after /users/.

Note: Account IDs can have different formats, so don’t worry if the one you’re looking at is different from the screenshot provided.

We recommend testing the install flow.

How to install your app

If you are not already familiar with installing your app in developer mode please follow the steps below:

  1. Navigate to the in product Marketplace

    In Jira “Jira Settings” > “Apps”
    In Confluence “Settings”

  2. Click “Manage apps”

  3. Find upload app (if not available check Settings to ensure you’ve enabled developer mode)

Test cases

You can add up to 5 users (including your app) to one of the free developer instances we provide. You’ll want to add at least one additional user from your team so that you can test the following scenarios:

  • Viewing yourself
  • Viewing another user
  • Viewing an app user

Other types of users not available for testing that you should be aware of:

  • Customers - You’ll see this in the accountType field as “customer”. This is a JSD user without an Atlassian Account.
  • Deactivated users - You’ll see this in the active field as “inactive”. This type of user is inactive but we haven’t deleted their personal information yet. This user does not have access to Atlassian systems and therefore can’t be assigned or at mentioned.
  • Deleted users - You’ll see this in the active field as “inactive”. We’ve processed data deletion for this user already. Similar to deactivated users, these users can’t be assigned or at mentioned. If you’d like to test the deletion process we’d recommend that you use a test account since data deletion is irreversible. Data deletion is processed 14 days after request to allow time for the user to change their mind.

Default settings

When you go to your Atlassian Account profile through that developer instance, you should see the new profile visibility controls and default settings on the privacy tab.

If you have a personal account, these default settings are:

Profile field “Anyone” (Public) “Only you” (Private)
Name :white_check_mark: :white_check_mark:
Avatar :white_check_mark: :white_check_mark:
Job Title :white_check_mark: :white_check_mark:
Organization :white_check_mark: :white_check_mark:
Timezone :white_check_mark: :white_check_mark:
Location :white_check_mark: :white_check_mark:
Email address :x: :white_check_mark:

If you have a managed account, you will see an additional level of visibility called “Organization”. Organization represents people with whom you work with. Note: Only ~1% of all Atlassian Accounts are managed accounts, although that percentage may increase over time.

Profile field “Anyone” (Public) Organization “Only you” (Private)
Name :white_check_mark: :white_check_mark: :white_check_mark:
Avatar :x: :white_check_mark: :white_check_mark:
Job Title :white_check_mark: :white_check_mark: :white_check_mark:
Organization :x: :white_check_mark: :white_check_mark:
Timezone :x: :white_check_mark: :white_check_mark:
Location :x: :white_check_mark: :white_check_mark:
Email address :x: :x: :white_check_mark:
What's a managed account?

Managed Accounts are Atlassian Accounts that have email addresses associated with a claimed domain.

Default settings applied to apps

Apps will only have access to certain public profile fields through our public cloud REST APIs. We do provide one public Javascript API which allows access to the current user’s timezone despite that user’s profile settings. As mentioned earlier, we also plan to provide an additional API which allows access to email address pending approval of app use case.

A version of name and avatar will always be public and available through Jira and Confluence REST APIs. This means that when a user chooses to hide their name and/or avatar we replace the values of those fields with a masked version.

Some fields presented in the profile visibility control screen are not present in Jira and Confluence REST APIs even if set to public. These fields are Job Title, Department, and Organization. These fields are visible on the user’s profile page presented by Atlassian Account which is why they are included in profile visibility controls.

Examples

Default users in Jira

Default settings for a user with a personal account
{
self: "...",
accountId: "1-128 character string - may contain "-" or ":" characters",
avatarUrls: {
        16x16: "will always be provided containing either an identifying avatar or a masked version"
        24x24: "Same as above"
        32x32: "Same as above"
        48x48: "Same as above"
displayName: "string value will always be provided containing either a full name or the user's public name",
active: true,
timeZone: "will provide the user's timezone ID (e.g. America / Los Angeles)",
locale: "will provide the user's locale language tag (e.g. en-US)",
groups: {
      size: 3,
      items: []
},
applicationRoles: {
     size: 3,
     items: []
},
accountType: "atlassian",
expand: "groups, applicationRoles"
}

Default settings for a user with a managed account
{
self: "...",
accountId: "1-128 character string - may contain "-" or ":" characters",
avatarUrls: {
        16x16: "will always be provided containing either an identifying avatar or a masked version"
        24x24: "Same as above"
        32x32: "Same as above"
        48x48: "Same as above"
displayName: "string value will always be provided containing either a full name or the user's public name",
active: true,
groups: {
      size: 3,
      items: []
},
applicationRoles: {
     size: 3,
     items: []
},
accountType: "atlassian",
expand: "groups, applicationRoles"
}

:warning: Field values disappear when hidden.

Default settings for a user with a deleted account
self: "...",
accountId: "1-128 character string - may contain "-" or ":" characters",
avatarUrls: {
        16x16: "will always be provided containing either an identifying avatar or a masked version"
        24x24: "Same as above"
        32x32: "Same as above"
        48x48: "Same as above"
displayName: "string value will always be provided containing the user's last known public name or "Former user" ",
active: false,
groups: {
      size: 0,
      items: []
},
applicationRoles: {
     size: 0,
     items: []
},
accountType: "atlassian",
expand: "groups, applicationRoles"
}

:warning: active field changes from true to false. Groups and roles that the deleted user belonged to are no longer associated with that accountID.

Default users in Confluence

Default settings for a user with a personal account
{
type: "known",
accountId: "1-128 character string - may contain "-" or ":" characters",
accountType: "atlassian", 
email: "",
publicName: "string value will always be provided containing the user's public name",
zoneInfo: "Will provide the user's timezone ID (e.g. America / Los Angeles)",
locale: "Will provide the user's locale language tag (e.g. en-US)",
active: true,
profilePicture: {
        path: "will always be provided containing either an identifying avatar or a masked version"
        width: 48,
        height: 48,
        isDefault: true
},
displayName: "string value will always be provided containing either a full name or the user's public name",
_expandable: {
       operations:"...",
       details:"...",
       personalSpace:"...",
},
_links: {
      self: "...",
      base:"...",
      context: "...",
},
}

:warning: Both public name and display name fields are always present. Display name will be replaced with public name if the user chooses to hide their full name. Fields that are hidden will return “”. zoneInfo field may change to timeZone to align with naming conventions presented in the Jira API.

Default settings for a user with a managed account
{
type: "known",
accountId: "1-128 character string - may contain "-" or ":" characters",
accountType: "atlassian", 
email: "",
publicName: "string value will always be provided containing the user's public name",
zoneInfo: "",
locale: "",
active: true,
profilePicture: {
        path: "string value will contain a masked version of the avatar"
        width: 48,
        height: 48,
        isDefault: true
},
displayName: "string value will always be provided containing the user's public name",
_expandable: {
       operations:"...",
       details:"...",
       personalSpace:"...",
},
_links: {
      self: "...",
      base:"...",
      context: "...",
},
}

:warning: Both public name and display name fields are always present. Display name will be replaced with public name if the user chooses to hide their full name. Fields that are hidden will return “”. zoneInfo field may change to timeZone to align with naming conventions presented in the Jira API.

Default settings for a user with a deleted account
{
type: "known",
accountId: "1-128 character string - may contain "-" or ":" characters",
accountType: "atlassian", 
email: "",
publicName: "unknown",
zoneInfo: "",
locale: "",
active: false,
profilePicture: {
        path: "string value will contain a URL to a default anonymous avatar."
        width: 48,
        height: 48,
        isDefault: true
},
displayName: "string value will always be provided containing either user's last known public name or "Former User" ",
_expandable: {
       operations:"...",
       details:"...",
       personalSpace:"...",
},
_links: {
      self: "...",
      base:"...",
      context: "...",
},
}

:warning: active field changes from true to false. publicName field changes from always public value to unknown. zoneInfo field may change to timeZone to align with naming conventions presented in the Jira API.

Interacting with App Users

App users or add-on users are created by apps. You may want to be able to distinguish actions performed by an app from an action performed by an app user. The accountType field will be able to tell you if the action is performed by an actual user (“atlassian” or “customer” (for JSD)) or an “app”). Webhooks, post functions, and user objects should all contain accountType information.

Changing your profile settings

When you modify your own profile via your Atlassian Account, you should see fields that you’ve set to “Private” or “Collaborator” disappear from the user object. Alternatively, if you change field visibility to public you’ll see those fields appear in the user object.

Examples

Variations in the Jira user object

All fields are unhidden
{
self: "string",
accountId: "1-128 character string - may contain "-" or ":" characters",
emailAddress: "will provide the user's email address"
avatarUrls: {
        16x16: "string will always be provided containing either a URL to either an identifying avatar or a masked version"
        24x24: "Same as above"
        32x32: "Same as above"
        48x48: "Same as above"
displayName: "string value will always be provided containing either a full name or the user's public name",
active: true,
timeZone: "will provide the user's timezone ID (e.g. America / Los Angeles)",
locale: "will provide the user's locale languageID (e.g. en-US)",
groups: {
      size: 3,
      items: []
},
applicationRoles: {
     size: 3,
     items: []
},
accountType: "atlassian",
expand: "groups, applicationRoles"
}

All fields are hidden
{
self: "string",
accountId: "1-128 character string - may contain "-" or ":" characters",
avatarUrls: {
        16x16: "will always be provided containing either an identifying avatar or a masked version"
        24x24: "Same as above"
        32x32: "Same as above"
        48x48: "Same as above"
displayName: "string value will always be provided containing either a full name or the user's public name",
active: true,
groups: {
      size: 3,
      items: []
},
applicationRoles: {
     size: 3,
     items: []
},
accountType: "atlassian",
expand: "groups, applicationRoles"
}

:warning: Field values disappear when hidden.

Variations in the Confluence user object

All fields are unhidden
{
type: "known",
accountId: "1-128 character string - may contain "-" or ":" characters",
accountType: "atlassian", 
email: "will provide the user's email address",
publicName: "string value will always be provided containing the user's public name",
zoneInfo: "will provide the user's timezone ID (e.g. America / Los Angeles)",
locale: "will provide the user's locale language tag (e.g. en-US)",
active: true,
profilePicture: {
        path: "will always be provided containing either an identifying avatar or a masked version"
        width: 48,
        height: 48,
        isDefault: true
},
displayName: "string value will always be provided containing either a full name or the user's public name",
_expandable: {
       operations:"",
       details:"",
       personalSpace:"",
},
_links: {
      self: "string",
      base:"string",
      context: "string",
},
}

:warning: Both public name and display name fields are always present. Display name will be replaced with public name if the user chooses to hide their full name. zoneInfo field may change to timeZone to align with naming conventions presented in the Jira API.

All fields are hidden
{
type: "known",
accountId: "1-128 character string - may contain "-" or ":" characters",
accountType: "atlassian", 
email: "",
publicName: "string value will always be provided containing the user's public name",
zoneInfo: "",
locale: "",
active: true,
profilePicture: {
        path: "will always be provided containing either an identifying avatar or a masked version"
        width: 48,
        height: 48,
        isDefault: true
},
displayName: "string value will always be provided containing either a full name or the user's public name",
_expandable: {
       operations:"...",
       details:"...",
       personalSpace:"...",
},
_links: {
      self: "...",
      base:"...",
      context: "...",
},
}

:warning: Both public name and display name fields are always present. Display name will be replaced with public name if the user chooses to hide their full name. Fields that are hidden will return “”. zoneInfo field may change to timeZone to align with naming conventions presented in the Jira API.

Designing user interactions

How to differentiate users in the UI

We recommend using the combination of name + avatar (profilePicture) to differentiate users throughout the UI. The combination of these fields will always be available and will help avoid confusers where users have similar names or avatars.

Never use email address in the UI to help differentiate users because email address is hidden by default for all account types. Apps that have been approved use the Email API should also avoid exposing email address despite having access to it because other apps installed or users may not have permissions to view user email addresses.

We also recommend never using accountID in the UI because its intentionally opaque (and likely will be long and hard to read).

How to display stored JQL queries

We recommend using the following AtlasKit component to display JQL with the current version of the user’s displayName in place of the accountID when displaying JQL.

AtlasKit component under development. Please see ACJIRA-1710 for more details.

Raising issues with Atlassian

4 Likes

@akassab

apps that require email address for core functionality will need to submit their use case and be approved to use a new API for exposing email address. The new email API will be available on March 15, 2019.

Is there any more information on what this approval process will entail/what are approved use cases? We develop a mail handler app for Jira cloud which of course requires access to the email addresses of Jira users to send them email. Losing any access to email addresses would make our app non-viable.

Hi @reece - Check out these ‘hot off the press’ Guidelines for requesting access to email address !

With the Timezone API no longer being guaranteed to return something useful, is there an endpoint we can use to find the default TZ for a given instance to use as a sane default?

AP.user.getTimeZone and Ap.user.getLocale will always provide the current user’s timezone and locale regardless of profile visibility control settings.

In our case, we need to know the TZ of other users, not the current user. We don’t want to assume that other users are in the same TZ as the current user, we would rather use the Instance default (but can’t find that in any existing API today).

@akassab unfortunately, workflow post-functions don’t run on the browser and thus don’t have access to the JavaScript API to get the timezone of the current user. How are we supposed to access the current user’s timezone from post-functions / webhooks?

In that case I don’t think anything like that exists. I raised a new feature request in ACJIRA for that scenario. See ACJIRA-1800.

@david2 - This is a known issue unfortunately. We removed user timezone and user locale from context parameters for the same reason we likely won’t reintroduce them to webhooks.

@akassab, is it possible then to pass the Jira default locale and timezone. Actually that would be handy for all of the pre-gdpr locations, passing the Jira locale and timezone.

I don’t see any immediate issues with that from a privacy perspective. I raised in ACJIRA-1800.

@akassab, originally the users locale and timezone was passed in the JWT Token. Since that has now been removed can we get the defaults passed instead. That way we wouldn’t need to do a call to Jira for formatting dates etc.

Thank
Paul

Hi,
It seems that the email address has been removed from the API, but the profile screens to control visibility are not ready yet. This has cause great pan, production outages and frustrated customers for several App developers/vendors. Really wish that the new controls were already in place before removing the email address. There must be a good reason to hastily remove the email address without providing the associated screens with it.