#Authorization and authentication

#Overview

This guide will give you information about OAuth 2.0 and the OpenID concept that you will need when starting the development of your App.

By following the “getting started” sections below, we will walk you through each of these concepts in a step by step process.

If you simply want to bootstrap an App with predefined authorization scopes to start your development, follow our Sample Apps.

#Authorization vs authentication

Authorization is the process of giving permissions to apps. Akeneo users authorize apps to access data in Akeneo Product Cloud. For example, an app might be authorized to access product and asset data in Akeneo Product Cloud.

Authentication is the process of verifying the identity of the user or the app. To keep transactions safe and secure, all apps connecting with Akeneo API must authenticate when making API requests.

#Types of authorization and authentication methods

  • Akeneo Product Cloud uses OAuth 2.0 to manage app authorizations.
  • Any app can use the OpenID Connect protocol to authenticate users coming from Akeneo Product Cloud.

#OAuth 2.0

OAuth 2.0 is the industry-standard protocol for authorizing or giving permissions to apps. This differs from authentication, which is the process of verifying the identity of the user or the app.

#The OAuth 2.0 flow

Akeneo uses OAuth 2.0’s authorization code grant flow to issue access tokens on behalf of users. The OAuth flow is used so that Akeneo users can authorize Akeneo apps to access data in Akeneo Product Cloud. For example, an app might be authorized to access product and asset data in a store.

The following diagram illustrates the OAuth flow based on the actions of the Akeneo user, your app, and Akeneo Product Cloud:

Schéma OAuth flow

#Getting started with OAuth 2.0

Apps created in the Akeneo App Store must obtain authorization using the OAuth 2.0 specification to use Akeneo’s API resources. This guide shows you how to authorize an app using OAuth 2.0.

#What you'll learn

After you've completed this tutorial, you'll be able to authorize an app created in the Akeneo App Store using OAuth 2.0.

#Requirements

#Step 1: Generate API credentials

The first step is to retrieve a Client id and a Client secret, which you get when you create an app. These API credentials identify your app during the authorization process.

If you've already created an app and generated API credentials, then proceed to step 2.

If you start developing your app, we advise you to use a custom app. To do so:

  1. In the top right corner, click on Create an App
  2. Fill in all the required information: Activate URL and Callback URL Custom app creation screen
  3. Then click on Create
  4. Copy/paste credentials in your app configuration file Custom app credentials screen
  5. And click on Done
  6. Your custom App appears on the App Store page

Your app is good to go?
Connect to the App Portal and follow the Create an app record documentation.

#Step 2: Ask for authorizations

Before an app can access data, a user must grant authorizations and permissions to the app. It happens when a user clicks the Connect button to connect your app.

After a user clicks on Connect, they are redirected to the activation URL you provided. The Akeneo Product Cloud URL they come from is in the query you receive.


    https://my-app.example.com/oauth/activate?pim_url=https%3A%2F%2Fmy-pim.cloud.akeneo.com
    

When you are ready to do so, you must start the Authorization Request.

Like any other OAuth 2.0 application, you have to redirect the user to the Authorization Server (Akeneo Product Cloud) with the following parameters:

Query parameter Description
response_type Required. Must always be "code"
client_id Required. The client id you get from the Akeneo App Store
scope Optional. A space-separated list of scopes. For example, to write products and read assets, use scope=write_products read_assets. Any permission to write a resource includes the permission to read it.
state Recommended.

    https://my-pim.cloud.akeneo.com/connect/apps/v1/authorize?
        response_type=code&
        client_id=[OAUTH_CLIENT_ID]&
        scope=[REQUESTED_SCOPES]&
        state=[STATE]
    

To discover all the authorization scopes, please refer to the Authorization and authentication scopes section.

To protect your App from cross-site request forgery, you should send a random string in the state parameter.

When the user arrives at this URL, Akeneo shows the following prompt to receive authorization from the user: Wizard authorization step

When the user ends the connection process, they are redirected to the app callback URL with the following parameters:


    https://my-app.example.com/oauth/callback?
        code=[AUTHORIZATION_CODE]&
        state=[STATE]
    

If you used a state to protect your App from cross-site request forgery, you must validate that the received state is identical.

#Step 3: Get a permanent access token

Now that you have received an authorization code, you can exchange this code against an access token.

The PIM expects the following parameters in the request:

  • client_id (required)
  • code (required)
  • grant_type (required, must always be "authorization_code")
  • code_identifier (required)
  • code_challenge (required)

#What's the Code Challenge?

To validate the App identity, Akeneo PIM requires a unique code challenge for each Access Token Request, instead of the usual client secret.
The code challenge is composed of 2 keys:

  • code_identifier: high-entropy cryptographic random string
  • code_challenge: sha256 hash of the concatenation of code_identifier and client_secret

Here is a PHP example:

$codeIdentifier = bin2hex(random_bytes(30));
    $codeChallenge = hash('sha256', $codeIdentifier . '[CLIENT_SECRET]');
    

#Token Request

From your server, you must make the following request to the PIM REST API on the endpoint /connect/apps/v1/oauth2/token:

POST /connect/apps/v1/oauth2/token HTTP/1.1
    Host: my-pim.cloud.akeneo.com
    Content-Type: application/x-www-form-urlencoded
    
    client_id=[OAUTH_CLIENT_ID]&code_identifier=[CODE_IDENTIFIER]&code_challenge=[CODE_CHALLENGE]
    &code=[AUTHORIZATION_CODE]&grant_type=authorization_code
    

#Token Success Response

If your Access Token Request is accepted, you will receive a JSON response with the token:

{
      "access_token": "Y2YyYjM1ZjMyMmZlZmE5Yzg0OTNiYjRjZTJjNjk0ZTUxYTE0NWI5Zm",
      "token_type": "bearer",
      "scope": "read_products write_products"
    }
    

You must store the access token securely. If you need to ask for a new one, you have to go through the same steps and wait for the PIM user to manually grant you a new access token.

An Access Token given to an App has no expiration date. However, be aware that it can be revoked at any moment by a PIM user.

#Token Error Response

If your Access Token Request is refused, you will receive a JSON response with the error.

For example, if your app doesn’t retrieve its access token within a 30 seconds delay, you will receive the following error, which indicates that your code is no longer valid.

{
        "error": "invalid_grant",
        "error_description": "Code has expired"
    }
    

Check the OAuth 2.0 spec for the possible error codes.

#Step 4: Make authenticated requests

After your app has obtained an API access token, it can make authenticated requests to the REST API.

These requests are accompanied by a header Authorization: Bearer {access_token} where {access_token} is replaced with the permanent token.

The following examples show how to retrieve a list of products using the REST API.

#Next steps

#Getting started with OpenID Connect

When building your public App, you can use the OpenID Connect protocol to authenticate users coming from an Akeneo Product Cloud.

OpenID Connect is a simple identity layer on top of the OAuth 2.0 protocol. Basically, with OpenID Connect, you use the same process as for Authorization, but you request an additional scope and you receive, alongside the Access Token, an ID Token containing the information of the current user.

This is an optional feature in Apps, you can also use your own Authentication. Learn more about the OpenID Connect protocol.

App authentication diagram

#What you'll learn

After you've completed this tutorial, you'll be able to authenticate users coming from Akeneo Product Cloud using OpenID Connect.

#Requirements

#Why use OpenID for your App

OpenID feature is a facilitator:

  • To the user who can log into the App directly by clicking “Open App” in the Connected Apps section of the PIM without any authentication form to complete
  • To your App building experience as the PIM user's information (last name, first name, email) are retrieved automatically
    • You can use those data in the UI to personalize some parts of your App. Example: “Welcome Peter”

Advice / Attention points

  • Never trust the “first name”, “last name” or “email” value as a golden record, any user can update this data, and most importantly the email is not verified by Akeneo PIM.
  • The sub claim is the value you need to use to identify a specific User in the PIM.
    • This value respects the OpenID spec, it is a PPID.

Pairwise pseudonymous identifiers (PPIDs) are defined in the OpenID Connect standard for representing users with opaque and random identifiers that are unique to different clients for increased user privacy.

#Step 1: Ask for authentication scopes

When a user connects to your app for the first time, and you want to authenticate them, you must ask for OpenID scopes during the Authorization request.

https://my-pim.cloud.akeneo.com/connect/apps/v1/authorize?
            response_type=code&
            client_id=[OAUTH_CLIENT_ID]&
            scope=openid email profile read_products write_products&
            state=[STATE]
    

If a user tries to access your App from their Akeneo Product Cloud, and you want to authenticate them, start an Authorization request, even if you already are connected to their Akeneo Product Cloud.

During this new Authorization Request, you must request all the scopes your App needs, including the Authorization scopes, in addition to the OpenID scopes.

#Step 2: Extract user information

At the end of the OAuth 2.0 process, if your Access Token Request is accepted, you will receive a JSON response with both tokens:

{
      "access_token": "Y2YyYjM1ZjMyMmZlZmE5Yzg0OTNiYjRjZTJjNjk0ZTUxYTE0NWI5Zm",
      "token_type": "bearer",
      "scope": "openid email profile read_products write_products",
      "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwOi8vM.XcmmANmSC2RHqWOI"
    }
    

#Decoding the ID Token

An ID Token is a JWT composed of 3 parts encoded independently in base64: header.payload.signature.

We recommend using one of the libraries listed here with support for RS256 to decode it and retrieve the values inside the payload.

It's not recommended to try to decode and verify the ID Token yourself.

#Payload

Once you've decoded the payload, it will look like this:

{
      "iss": "https://my-pim.cloud.akeneo.com",
      "jti": "c76d558d-d10a-4bac-b320-12c22e36b3db",
      "sub": "c6acd619-8a08-46c2-9a5e-41a175d9149d",
      "aud": "206f450e-09a1-44ed-a0b3-9dd80f980ace",
      "iat": 1643029678.467703,
      "exp": 1643033278.467703,
      "email": "john.doe@example.com",
      "email_verified": false,
      "firstname": "John",
      "lastname": "Doe"
    }
    
Field Description
iss URL of the token issuer
jti Unique identifier for the token
sub Unique user id
aud Id of the OAuth 2.0 client
iat Timestamp of token creation
exp Timestamp of token expiration
email (optional) Email of the user
email_verified (optional) Boolean to indicate email validity
firstname (optional) Firstname of the user
lastname (optional) Lastname of the user

Additional information (email, firstname, lastname, ...) are only present if you requested the corresponding authentication scopes and those were approved by the user.

email, firstname and lastname are values that can be edited on Akeneo PIM and are not verified by Akeneo (email_verified is always false as a result). The only value that will truly identify a user is their unique user id in the subject claim (sub).

#Signature

The ID Token sent by Akeneo PIM contains a signature, and you must verify it to guarantee that the payload has not be tampered with.

To validate the signature, you must retrieve the public key available at the URL {PIM}/connect/apps/v1/openid/public-key.

Then, follow the instructions of the library you are using.

The pair of private/public keys are regenerated regularly for security reasons. You should always retrieve the latest public key when validating a signature.

#Next steps

#Authorization and authentication scopes

In this part of the documentation, you'll find all the available scopes. These are the scopes you send in the authorization and authentication requests.

#Available authorization scopes

Scope Grants access to
read_products Read products
write_products Write products
delete_products Remove products
read_catalog_structure Read attributes, attribute groups, families and family variants
write_catalog_structure Write attributes, attribute groups, families and family variants
read_attribute_options Read attribute options
write_attribute_options Write attribute options
read_categories Read categories
write_categories Write categories
read_channel_localization Read locales and currencies
read_channel_settings Read channels
write_channel_settings Write channels
read_association_types Read association types
write_association_types Write association types
read_catalogs Read app catalogs
write_catalogs Write app catalogs
delete_catalogs Remove app catalogs
read_asset_families EE Read asset families
write_asset_families EE Write assets families
read_assets EE Read assets
write_assets EE Write assets
delete_assets EE Remove assets
read_reference_entities EE Read reference entities
write_reference_entities EE Write reference entities
read_reference_entity_records EE Read reference entity records
write_reference_entity_records EE Write reference entity records

#Available authentication scopes

Scope Grants access to
openid Read user id
profile Read user first name and last name (from PIM user profile)
email Read user email (from PIM user profile)

#Update Authorization and authentication scopes

It's possible to update the access scopes of an already connected app. The access scope update process requires app users to consent to new scopes addition.

#Update the list of required scopes

If your app needs to change the access scopes, it must initiate a new authorization request with all access scopes needed, even the access scopes that are already granted. This new authorization request follows the usual OAuth 2.0 protocol and will end with a new Access Token that reflects updated scopes.

Some users are not allowed to grant new access scopes in the Akeneo PIM.
You should not force users to go through the Authorization process if you haven't received the new access scopes, you could end up in an infinite loop. Consequently, your App must be able to function as usual without the new access scopes.

More information on our Help Center: Who can manage and open Apps?

#Notify a PIM your app requires an authorization update

Through Akeneo REST API, connected apps can notify Akeneo PIM users who can manage your app that the authorization scopes your app requires have changed.

To do so, use the following POST method, with parameters below:

https://my-pim.cloud.akeneo.com/connect/apps/v1/scopes/update?scopes=[REQUESTED_SCOPES]
    

Requirements:

  • scopes: query parameter to specify app new scope list as a space-separated string
  • Authorization: Bearer [AccessToken]: header to authenticate your app
  • Content-Type: application/json: header for the response format

The notification will warn them and entice them to open your app so that you can initiate an authorization request with the entire list of required scopes.

Updated scopes - PIM notification

Please, be aware that this endpoint does not update any access scopes.
It is only meant to provide a way for an app to warn Akeneo PIM.