Last updatedJun 9, 2021

Rate this page:

Security for Connect apps

Security for Connect apps has two key parts:

  • Authentication tells the host product the identity of your app or integration.
  • Authorization determines what actions your app can take within the host product.

Authentication

Connect apps use JWT (JSON Web Tokens) for authentication. At installation time, the Connect app and the host product exchange a security context containing a shared secret used to create and validate JWT tokens for use in API calls.

The use of JWT tokens guarantees that:

  • The Atlassian product can verify it is talking to the app, and vice versa (authenticity).
  • None of the query parameters of the HTTP request, nor the path (excluding the context path), nor the HTTP method, were altered in transit (integrity).

This technology is built into the supported Connect libraries. If you use the Atlassian-supported Connect client frameworks, most security operations are handled for you. See the README files for more information:

Otherwise, you'll need to construct and manage JWT tokens yourself. See Understanding JWT for Connect apps for details.

Authorization

Atlassian Connect apps can use two types of authorization:

  • Authorization via scopes and app users: Scopes are permissions that are defined in the app descriptor. The app has its own app user with permissions controlled by the admin. The set of allowed actions is the intersection of the scopes and the permissions of the app user. This is the normal authorization method, which you should use unless you need to make server-to-server requests on behalf of a user.
  • Authorization with user impersonation: User impersonation allows your integration to access Atlassian APIs on a user's behalf. You should only use this method when your app needs to make server-to-server requests on behalf of a user.

Authorization via scopes and app users

This method relies on two types of authorization:

  • Static authorization via scopes
  • Runtime authorization via app users

You define scopes in the app descriptor to specify the maximum set of actions that an app may perform: read, write, etc. This security level is enforced by Connect and cannot be bypassed by app implementations. To learn more, see Scopes.

How scopes and permissions work together

The set of actions that an app is capable of performing is the intersection of the statically defined scopes and the permissions of the user assigned to the request. This means that requests can be rejected because the assigned user lacks the required permissions. Therefore, your app should always defensively detect HTTP 403 forbidden responses from the product.

Every app is assigned its own app user in a Cloud instance. In general, server-to-server requests are made by the app user. Client-side requests are made as the current user in the browser session, and are supported via the AP.request() method.

If the app needs to act on behalf of the user, you can make server-to-server requests using OAuth 2.0 user impersonation (see next section).

Connect apps cannot access private personal data by using OAuth 2.0 JWT or AP.request().

Authorization with user impersonation

User impersonation allows your integration to access Atlassian APIs on a user's behalf. This is provided via the JWT Bearer token authorization grant type for OAuth 2.0, which is also known as two-legged OAuth with impersonation (2LOi). At a high level, this method works by the app exchanging a JWT for an OAuth 2.0 access token (provided by the application). The access token can be used to make server-to-server calls, on behalf of the user, to the application's API.

To learn more, read User impersonation for Connect apps.

Implementation

Here's how to use authentication and authorization in your app:

  1. In the app descriptor, declare that the app uses JWT as the authentication mechanism.
  2. Implement an installation callback endpoint and add a reference to it in the app descriptor.
  3. In the app descriptor, declare any scopes needed by the endpoints your app will access.

When the installation callback is called at app install time, the host product passes in a security context that your app uses to validate incoming requests and sign outgoing requests. If you use the Atlassian-supported Connect frameworks, this is handled for you.

The following sections describe how this works in more detail.

The app descriptor

Authentication and authorization rely on elements in the app descriptor.

To make your Connect app authenticate securely with the host Atlassian product, make sure the following elements are in the app descriptor:

  • authentication:type: the authentication type, which is always jwt
  • lifecycle:installed: a callback endpoint to call at installation time

To request authorization to perform specific categories of actions in the host product, add the scopes element and the scopes you need. For a list of available scopes, see Scopes.

For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
    "baseUrl": "http://localhost:3000",
    "key": "atlassian-connect-app",
    "authentication": {
        "type": "jwt"
    },
    "lifecycle": {
        "installed": "/app-installed-callback"
    },
    "scopes": [
        "read", "write"
    ],
    "modules": {} // etc
}

Installation data

When the app is installed, the Atlassian product passes your callback a security context that contains important information that you must store in your app in order to sign and verify future requests.

For details on the contents of the payload, see the lifecycle attribute documentation.

Your installation callback must execute synchronously.

Upon successful registration, the installation callback must return either a 200 OK or 204 No Content response code. Otherwise, the operation will fail and the installation will be marked as incomplete.

REST API requests

When communicating server-to-server with the Atlassian host product, your app uses a JWT token to access protected resources, including most of the REST APIs. When you use the Atlassian-supported Connect frameworks, this is handled for you.

If you're not using the frameworks, you can use JWT libraries to construct a token. See Creating a JWT token and the Atlassian-supported claims that you need to construct.

Validating incoming requests

Requests to your endpoints from the host product are signed with JWT tokens. If you use the Atlassian-supported Connect frameworks, this is handled for you.

If you're not using the frameworks, you'll have to decode and verify all incoming requests from an Atlassian product to your service. For more details, see Decoding and verifying a JWT and the Atlassian-supported claims that you need to validate.

Signed installation callback requests

When your app is first installed, the shared secret is exchanged for the first time. It is then available to sign callbacks on subsequent installations. The best way to see how JWT tokens work with your lifecycle events is to use the Connect inspector to create a temporary app, install it in your cloud development environmen, and watch the lifecycle events.

Use caseShared secret used to sign
First installNone; no JWT token. Because there was no previously shared secret, the recipient cannot validate a JWT token. This means that you should anticipate that there will be no Authorization header present.
Second and subsequent installsThe shared secret sent in the preceding installed callback.
Uninstall, enable, and disableThe shared secret sent in the preceding installed callback.
First install after being uninstalledThe shared secret sent in the preceding installed callback. This enables apps to allow the new installation to access previous tenant data (if any exists).
A valid signature demonstrates that the sender is in possession of the shared secret from when the old tenant data was accessed.

About the shared secret

Because all JWT tokens are secured by your app's shared secret, it is required that you keep it secure and safe.

Ensure the following:

  • As few people as possible have access to the shared secret
  • The shared secret is encrypted at rest
  • Only send the shared secret over an encrypted connection (eg. HTTPS over TLS)

Rate this page: