Access Management in brX GraphQL Service

Overview

Each request to the brX GraphQL Service must include an access token. The Access Manager component in the brX GraphQL Service reads and validates this token to authorize requests for store visitors.

JSON Web Encryption (JWE) and Keystore Management

The Access Manager delegates authentication and authorization to the implementation specific to your Commerce Backend Platform. The brX GraphQL Service does not store visitor or session data. After the Commerce Backend Platform authenticates the visitor, the Access Manager wraps all session-related information in an encrypted JSON object and returns it to the client as the access token. This object is encrypted using the JWE standard.

Configure the keystore entry in your .env file as shown below:

JWK_KEYSTORE={"keys":[{"kty":"<KEY_TYPE (e.g. oct)>","kid":"<KEY_ID>","k":"<KEY_VALUE>"}]}

The keystore format follows the structure defined by the cisco/node-jose library.

Note: You can specify multiple keys in the keystore, but only the first entry is used for encryption.
All nodes in your cluster must use the same value for the JWK_KEYSTORE property, with the identical key sequence. The decryption process does not depend on key order.

Generating a JWK Keystore

You can generate the keystore JSON string using either the command line with the node-jose-tools library or by writing a custom script with the cisco/node-jose library.

Option 1: Generate a JWK Keystore Using the Command Line

To generate a JWK Keystore with node-jose-tools:

$ npm install -g node-jose-tools $ jose newkey -s 256 -t oct {"kty":"oct","kid":"_tkK4V3_7vqmCWb1JOKUCRUwh_iGFe_WGIB8wDJ4lD4","k":"WzviGv-8uVE8ZPvfdh-od9Wer4nVjuqY4GdpJA5BlVo"}

Copy the output and set it as the value of the JWK_KEYSTORE environment variable.

For advanced options, see node-jose-tools documentation.

Option 2: Generate a JWK Keystore Using a Custom Script

You can also generate a JWK Keystore by writing a script with the cisco/node-jose library. Create a .js file (for example, ~/tmp/genkeystore.js) with the following content:

// // Example script to generate a JWS keystore using node-jose library (https://github.com/cisco/node-jose). // // Usage: node ./genkeystore.js // var jose = require('node-jose'); // Create an empty keystore. var keystore = jose.JWK.createKeyStore(); // Generate a new key and add it to the keystore. Find more advanced options in https://github.com/cisco/node-jose. keystore.generate('oct', 256).then(function(key) { keystore.add(key); // Print out the keystore in JSON. console.log(`JWK_KEYSTORE=${JSON.stringify(keystore.toJSON(true))}`); });

Run the script as follows:

$ npm install node-jose $ node ./genkeystore.js JWK_KEYSTORE={"keys":[{"kty":"oct","kid":"1-LS7ZwQjRSQaGQjk7bGQoF7FW5C6nr9rOVwxMZ6290","k":"NVt6ylQvjaizeahZ16czCQDMx8bfSKoEaFStRbf2OgI"}]}

Copy the output and add it to your .env file.

For more options, refer to the node-jose documentation.

Key Rotation

To rotate the encryption key, prepend the new key to the keys array:

JWK_KEYSTORE={"keys":[{"kty":"KEY_TYPE","kid":"NEW_KEY_ID","k":"NEW_KEY_VALUE"},{"kty":"KEY_TYPE","kid":"KEY_ID","k":"KEY_VALUE"}]}

The new key must be the first entry. Do not remove existing keys immediately. This approach ensures:

  • New session data is encrypted with the new key.
  • Session data encrypted with old keys can still be decrypted.

After updating the keystore, restart all GraphQL Service nodes.

Authentication in the brX GraphQL Service

Before making requests to the brX GraphQL Service, the client application must authenticate. The service supports customer-based authentication using customer credentials. There are two authentication scopes:

  • Anonymous
  • Customer Credentials

Anonymous Authentication

Anonymous authentication provides limited, public access to the brX GraphQL Service. The following diagram shows the anonymous authentication flow, starting from the client application (such as a SPA) and interacting with the commerce backend authorization server (for example, OAuth2).

[Anonymous authentication flow between SPA, GraphQL service, and commerce backend

Diagram: The diagram illustrates the authentication flow from a React SPA, through a JS client and Auth component, into backend services (Express and Access Manager), and finally to the commerce backend authorization system. The client requests anonymous access via the GraphQL service, which coordinates with access management and the commerce backend to obtain authorization data.](/binaries/content/gallery/connect/library/solutions/commerce-starterstore/graphql-service/auth-public.svg)

To request anonymous access data, use the following command:

curl -i \ -d '{}' \ -H 'Content-Type: application/json' \ -H 'connector: <CONNECTOR_ID>' \ https://<BRX_GRAPHQL_SERVICE_HOST>/signin

Customer Authentication

Customer authentication is used when the client provides customer credentials. The diagram below shows the high-level interaction flow for customer authentication. In this flow, customer credentials are included in the sign-in request.

[Customer authentication flow between React SPA, JS client, and backend services

Diagram: This diagram shows the authentication flow from a React SPA, through a JS client and Auth component, to backend services (Express and Access Manager), and onward to the commerce backend. Requests move from the frontend through authentication layers to backend access management and commerce systems.](/binaries/content/gallery/connect/library/solutions/commerce-starterstore/graphql-service/auth-customer.svg)

To request customer-related access data, use the following command:

curl -i \ -d '{"username":"<USERNAME>", "password":"<PASSWORD>", "authHint": { "oldCartId": "ANONYMOUS_CART_ID", "mergeWithExistingCustomerCart": "true OR false"} }' \ -H 'Content-Type: application/json' \ -H 'connector: <CONNECTOR_ID>' \ -H 'authorization: Bearer <ANONYMOUS_ACCESS_TOKEN>' \ https://<BRX_GRAPHQL_SERVICE_HOST>/signin

The sign-in process typically includes two steps, depending on the commerce backend APIs:

  1. Authenticate against the authorization server (such as OAuth2). The server validates the credentials and, if successful, returns access data (such as tokens) to the brX GraphQL Service.
  2. Send a sign-in request to the Commerce Backend REST API. This step allows the backend to transfer anonymous interaction data (such as an anonymous cart) to the new customer session.

Additional information required for these steps includes:

  • The authorization header, containing the anonymous user access token.
  • The authHint property, which may include oldCartId and mergeWithExistingCustomerCart options.

Authentication Hint

The sign-in operation can include extra visitor information in the authHint property. This data is useful for tracking anonymous interactions. The authHint property supports two items: oldCartId and mergeWithExistingCustomerCart. The following combinations are possible:

  • If both the authorization header and oldCartId are provided:
    • If mergeWithExistingCustomerCart is true, the anonymous cart is merged with the latest active customer cart.
    • If mergeWithExistingCustomerCart is false, the anonymous cart replaces the latest active customer cart.
    • If mergeWithExistingCustomerCart is not specified, the default is true.
  • If oldCartId is not provided, the anonymous cart is ignored.

Sign-out

The brX GraphQL Service provides a sign-out operation to end an authenticated customer session with the commerce backend:

curl -i -d '{}' \ -H 'Content-Type: application/json' \ -H 'connector: <CONNECTOR_ID>' \ -H 'authorization: Bearer <ACCESS_TOKEN>' \ https://<BRX_GRAPHQL_SERVICE_HOST>/signout

On success, the response includes new access data for a new anonymous session. If the commerce backend supports session revocation, the connector may also revoke the previous customer session's access token.

Refreshing Access Token

By default, the access token refresh option is disabled starting with version 14.3.0. To enable it, set the TOKEN_REFRESH_ENABLED environment variable to true.

The Access Manager implementation for your Commerce Backend Platform may issue access tokens as encrypted JSON objects containing temporary session data that require periodic refresh.

For example, if you use OAuth2-based authorization, the JSON object should include:

  • An access token (for the visitor session)
  • A refresh token (for the visitor session)

Both tokens may expire. When the access token expires, requests using it will fail. To refresh the access token, send a "refresh" request:

curl -i -d '{"type":"refresh"}' \ -H 'Content-Type: application/json' \ -H 'connector: <CONNECTOR_ID>' \ -H 'authorization: Bearer <ACCESS_TOKEN>' \ https://<BRX_GRAPHQL_SERVICE_HOST>/signin

The following diagram shows the interaction flow for refreshing an access token. In this example, the visitor performs an operation (such as adding to cart) after the access data has expired.

[Token refresh interaction flow across SPA, GraphQL, and commerce services

Diagram: This diagram illustrates the flow for refreshing expired access data during a visitor action. Participants include the React SPA, Apollo, Express, Access Manager, and commerce backend services. The flow shows requests moving from the frontend through backend components to commerce services, returning refreshed access information so the original operation can continue.](/binaries/content/gallery/connect/library/solutions/commerce-starterstore/graphql-service/auth-token-refresh.svg)

Share Feedback
Page: /frontend/commerce-accelerator/brx-graphql-service/access-management
Section: Frontend
Category *