Preparing APIs for subscribers Last updated 17-Dec-2024

Preparing APIs for subscribers

DSAPI APIM uses plans, applications, and subscriptions to govern API exposure. A published Gateway API is visible in the Developer Portal but cannot be consumed without a published plan. A Keyless plan can be consumed immediately, but all other authentication types require the API consumer to register an application and subscribe to a published plan. This system promotes granular control over API access.

For more information about preparing your APIs for subscribers, see the following articles:

Applying Plans to you APIs

Introduction

To expose your API to internal or external consumers, it must have at least one plan. A plan provides a service and access layer on top of your API that specifies access limits, subscription validation modes, and other configurations to tailor it to an application. Example access scenarios APIM can manage with plans include:

  • Read-only access and limited request traffic for potential customers to discover and try out your APIs
  • Premium access with public resources and access limits for your partners
  • Unlimited access to your internal enterprise applications

High-level plan diagram

Each plan must include at least one security type by which subscribers can be authenticated. A security type is a policy integrated directly into a plan. Once a plan is created, the security type can not be changed. However, you can add additional security at the API or plan level with policies.

The sections below describe:

Create a plan

To create a plan:

  1. Log in to your APIM Console

  2. Select APIs from the left nav

  3. Select your API

  4. Select Consumers from the inner left nav

  5. Under the Plans header tab, click + Add new plan and select your plan security type:

    Add a new plan

  6. Configure the general plan settings:

    Configure general plan settings

    • Name: Enter a name for your plan
    • Description: Enter a description of your plan
    • Characteristics: Define labels used to tag your plan
    • Page of General Conditions: Select a published Documentation page whose terms must be accepted by the user to finalize the subscription process
    • Toggle Auto validate subscription ON to accept all subscriptions to a plan without the API publisher's approval
    • Toggle Consumer must provide a comment when subscribing to the plan ON to require an explanation for the subscription request, with the option to leave a Custom message to display to consumer
    • Sharding tags: Selectively deploy the plan to particular APIs using available sharding tags
    • Groups excluded: Prevent specified user groups from accessing your plan
  7. Click Next

  8. Define the security configuration details appropriate to and required by your selected security type, e.g., OAuth2.

    OAuth2 configuration

  9. Select any plan restrictions:

    Select plan restrictions

    • Rate limiting: Intended to help avoid unmanageable spikes in traffic by limiting the number of requests an application can make in a given time period.
    • Quota: Limits the number of requests an application can make in a given time period. Generally used to tier access to APIs based on subscription level.
    • Resource Filtering: Limits access to API resources according to whitelist and/or blacklist rules.
  10. Click Create

Plan stages

A plan can exist in one of four stages: STAGING, PUBLISHED, DEPRECATED, and CLOSED:

This is the draft mode of a plan, where it can be configured but won’t be accessible to users.
API consumers can view a published plan on the Developer Portal. Once subscribed, they can use it to consume the API. A published plan can still be edited.
A deprecated plan won’t be available on the Developer Portal and API consumers won’t be able to subscribe to it. This cannot be undone. Existing subscriptions are not impacted, giving current API consumers time to migrate without breaking their application.
Once a plan is closed, all associated subscriptions are closed. API consumers subscribed to this plan won’t be able to use the API. This cannot be undone.

Depending on the stage it's in, a plan can be edited, published, deprecated, or closed via the icons associated with it:

To edit a plan, click on the pencil icon:

Edit a plan

To publish a plan, click on the icon of a cloud with an arrow:

Publish a plan

Once a plan has been published, it must be redeployed.

To deprecate a plan, click on the icon of a cloud with an 'x':

Deprecate a plan

To close a plan, click on the 'x' icon:

Close a plan

Plan selection rules

APIM automatically routes each API request to the correct plan. The plan selection workflow parses all published plans in the following order: JWT, OAuth2, API Key, Keyless.

This workflow only applies to v4 APIs and v2 APIs in emulation mode.

The parsing rules for each plan type are detailed below:

  • Retrieve JWT from the Authorization header or query parameters
  • Ignore an empty Authorization header or any type other than Bearer
  • An empty Bearer token is considered invalid
  • Retrieve OAuth2 from the Authorization header or query parameters
  • Ignore an empty Authorization header or any type other than Bearer
  • An empty Bearer token is considered invalid
  • Retrieve the API key from the request header or query parameters (default header: X-DSAPI-Api-Key; default query parameter: api-key)
  • An empty Bearer token is considered invalid
  • Will ignore any type of security (API key, Bearer token, etc.)
  • If another plan has detected a security token, valid or invalid, all flows assigned to the Keyless plan will be ignored
    • If an API has multiple plans of different types and the incoming request contains a token or an API key that does not match any of the existing plans, then the Keyless plan will not be activated and the user will receive a generic 401 response without any details

The parsed plan is selected for execution if all the following conditions are met:

  • The request contains a token corresponding to the plan type (e.g., an X-DSAPI-Api-Key header for an API Key plan)
  • The plan condition rule is valid or not set
  • There is an active subscription matching the incoming request

mTLS

You can apply mTLS plans to only v4 APIs

The mTLS authentication type enforces the use of a client certificate to connect to an API. For more information about mTLS, see the following articles:

mTLS plans overview

The mTLS authentication type enforces the use of a client certificate to connect to an API. The client certificate is added to an application, and then a subscription is created for that application. At runtime, the gateway checks that an incoming request contains a client certificate matching one associated with an application that has an active subscription.

You can use the mTLS with or without TLS enabled between the client and the gateway. The gateway server can require client authentication, which uses the truststore at the server level to determine which clients to trust. The mTLS plan checks the client certificate with the gateway-level TLS. The client certificate is either found in either of the following locations:

  • The TLS session between the client and the gateway
  • In a pre-specified header in plaintext, base64-encoded.

This can be done if a load balancer is placed in front of the gateway that terminates TLS. For more information about the configuration, See configuration.

Limitations

mTLS plans have the following limitations:

  • You can apply mTLS plans to only v4 APIs.
  • You cannot use mTLS plans in DSAPI Cloud.
  • Only one client certificate can be added per application. This means that to rotate certificates for an application, you need to pause the application’s subscriptions or schedule a maintenance window to avoid traffic for that API.
  • Applications do not provide a warning that certificates are going to expire.

Adding a Client Certificate to an Application

To subscribe to an mTLS plan, the client must add a certificate to their application. To add a certification to an application, complete the following steps:

  1. In the console, navigate to Applications, and then click a specific application.
  2. For that application, click the setting the Tls Configuration. The client certificate is pasted in base64-encoded format.
Screenshot showing Tls configuration

Screenshot showing Tls configuration

Multiple applications in the same APIM instance must not share client certificates. You cannot save an application’s configuration if the added client certificate is already present for another application.

When you add a client certificate to an application, the gateway adds this application to its truststore. At runtime, the gateway checks whether the truststore has a certificate that matches an application with a valid subscription for the API.

Calling an API with mTLS

Before you begin

  • You must have the client certificate
  • You must have the private key

Procedure

  • To call an API with mTLS, use the following command:
$ curl –-cert  <client.cer> --key <client.key> https://my-gateway.com/mtls-api
    
  • Replace <client.cer> and <client.key> with the name of the files where you have stored your client certificate and the file where you have stored the client key.

Also, this requires that your client trusts the certificate sent by the gateway.

Terminating TLS in front of the Gateway

From DSAPI APIM 4.5 onwards, when the certificates have been processed by NGINX, API Management only supports extracting client certificates from headers in plaintext.

To run a load balancer in front of the gateway like NGINX, and then terminate TLS at the load balancer. The load balancer forwards traffic to the gateway in plaintext. To use the mTLS plan in this situation, you can set a gateway configuration. For example:

http:
      # ...
      ssl:
        clientAuthHeader:
          name: X-DSAPI-Client-Cert
    

When executing an mTLS plan, the gateway checks if TLS is enabled. If it is enabled, the gateway uses the certificate from the TLS handshake , which occurs before plan selection. If TLS is not enabled, it checks for the certificate in the header. If the header contains a valid base64-encoded plaintext certificate matching a certificate for a subscribed application, the request will succeed.


Ensure that when you use this option that only trusted parties can set this header. If using a load balancer, it must be solely responsible for setting this header. In this setup, the gateway should only be directly accessible through the load balancer.

Types of plans

Plans provide a service and access layer on top of your API that specifies access limits, subscription validation modes, and other configurations to tailor it to an application. Here are the plans that you can apply to your APIs:

Keyless

Introduction

A Keyless (public) plan does not require authentication and allows public access to an API. By default, keyless plans offer no security and are most useful for quickly and easily exposing your API to external users.

Configuration

A Keyless plan does not require configuration other than general plan settings and restrictions.

Due to not requiring a subscription and the lack of a consumer identifier token, Keyless consumers are set as unknown application in the API analytics section.

You can configure basic authentication for Keyless plans by associating a Basic Authentication policy that uses either an LDAP or inline resource.

API Key

Introduction

The API key authentication type enforces verification of API keys during request processing, allowing only applications with approved API keys to access an API. This plan type ensures that API keys are valid, i.e., not revoked or expired, and are approved to consume the specific resources associated with the API.

Configuration

An API Key plan offers only basic security, acting more like a unique identifier than a security token.

API Key configuration
  • Propagate API Key to upstream API: Toggle ON to ensure the request to the backend API includes the API key header sent by the API consumer. This is useful for backend APIs that already have integrated API key authentication.
  • Additional selection rule: Allows you to use DSAPI Expression Language (EL) to filter plans of the same type by contextual data (request headers, tokens, attributes, etc.). For example, if there are multiple API key plans, you can set different selection rules on each plan to determine which plan handles each request.

API Key generation

By default, API keys are randomly generated for each subscription, but DSAPI also offers custom API key generation and shared API key generation. Both of these settings can be enabled at the environment level:

  1. Log in to your APIM Console

  2. Select Settings from the left nav

  3. Select Settings from the inner left nav:

    API key generation settings

Custom API key

You can specify a custom API key for an API Key plan. This is particularly useful when you want to silently migrate to APIM and have a pre-defined API key. When prompted, you can choose to provide your custom API key or let APIM generate one for you by leaving the field empty.

The custom API key must have between 8 and 64 characters and be URL-compliant. ^ # % @ \ / ; = ? | ~ ,and the 'space' character are invalid.

You can provide a custom API key when:

  • Creating a subscription

    Manually create a subscription

  • Accepting a subscription

  • Renewing a subscription

    Renew a subscription

Shared API key

The shared API key mode allows consumers to reuse the same API key across all API subscriptions of an application. On their application's second subscription, the consumer is asked to choose between reusing their key across all subscriptions or generating one different API key for each subscription (default). This is known as the application API key type, which cannot be modified.

Shared API key limitations

API keys can only be shared across API Key plans that belong to distinct Gateway APIs. If you attempt to subscribe to two API Key plans on the same Gateway API, no prompt will be made to choose the application API key type and the default mode will be used automatically.

Subscribing in the Developer Portal Subscribing in the APIM Console

To select the API key type, the shared API key mode must be enabled before creating an application. To enable this option, create a new application and subscribe to two API Key plans.

If shared API key mode is disabled, applications that have already been configured to use a shared key will continue to do so, but consumers will no longer be asked to choose between modes on their second subscription.

Modifying shared API keys

A shared API key may be used to call APIs that are owned by other API publishers. Consequently:

  • Shared API keys cannot be edited from an API publisher's subscriptions

  • API publishers can read shared API keys, but cannot renew or revoke them

    Shared API key administration limitations

  • Shared API keys can only be renewed/revoked by the application owner, from the subscription view of their APIM Console or Developer Portal

    Manage shared API keys in APIM Console

    Manage shared API keys in the Developer Portal

OAuth2

Introduction

OAuth 2.0 is an open standard that applications can use to provide client applications with secure, delegated access. OAuth 2.0 works over HTTPS and authorizes devices, APIs, servers, and applications via access tokens instead of credentials.

The OAuth2 authentication type checks access token validity during request processing using token introspection. If the access token is valid, the request is allowed to proceed. If not, the process stops and rejects the request.

Configuration

To configure an OAuth2 plan, you must first create an OAuth2 client resource that represents your OAuth 2.0 authorization server.

Configuring an OAuth2 plan presents the following options:

OAuth2 plan configuration
  • OAuth2 resource: Enter the name of the OAuth2 resource to use as the authorization server

  • Cache resource: Optionally enter the name of the cache resource to store responses from the authorization server

  • Extract OAuth2 payload: Allows the OAuth2 payload to be accessed from the oauth.payload context attribute via DSAPI Expression Language (EL) during request/response, e.g. using:

    {#context.attributes['oauth.payload']}
        
  • Check scopes: An authorization server can grant access tokens with a scopes parameter, which the Gateway will check against the provided Required scopes to determine if the client application is allowed to access the API

  • Mode strict: When disabled, the Gateway will validate the API call if the access token contains at least one scope from the Required scopes list. When enabled, strict mode requires the access token to contain all scopes from the Required scopes list.

  • Permit authorization header to the target endpoints: Propagate the header containing the access token to the backend APIs

  • Additional selection rule: Allows you to use the EL to filter by contextual data (request headers, tokens, attributes, etc.) for plans of the same type (e.g., for two OAuth2 plans, you can set different selection rules on each plan to determine which plan handles each request)

Once OAuth2 configuration is complete and the plan is created and published, your API will be OAuth2-secured and subscribed consumers must call the API with an Authorization Bearer :token: HTTP header to access the API resources.

Subscription requirements

During the OAuth2 plan selection, a token introspection is completed to retrieve the client_id which allows searching for a subscription. Any applications wanting to subscribe to an OAuth2 plan must have an existing client with a valid client_id registered in the OAuth 2.0 authorization server. The client_id will be used to establish a connection between the OAuth 2.0 client and the APIM consumer application.

To mitigate performance concerns, a cache system is available to avoid completing the same token introspection multiple times. If there are multiple OAuth2 plans, it is recommended to use selection rules to avoid any unnecessary token introspection.

JWT

Introduction

A JSON Web Token (JWT) is an open method for representing claims securely between two parties. It is digitally signed using an HMAC shared key or RSA public/private key pair. The JWT authentication type ensures that a JWT issued by a third party is valid by verifying its signature and expiration date. Only applications with approved JWTs can access APIs associated with a JWT plan.

Configuration

APIM uses client IDs to recognize applications that have subscribed to a JWT plan. The inbound JWT payload must include the client_id claim to establish a connection between the JWT and the APIM application subscription.

A JWT plan presents the following configuration options:

JWT plan configuration
  • Signature: Select the algorithm used to hash and encrypt your JWT

  • JWKS resolver: Select a method to retrieve the JSON Web Key (JWK), which is often stored inside a JSON Web Key Set (JWKS) and required by the Gateway to validate the signature of the JWT:

    • GIVEN_KEY: Provide a signature key as a resolver parameter according to the signature algorithm (ssh-rsa, pem, crt or public-key format

    • GATEWAY_KEYS: Search for public keys set in the API Gateway DSAPI.yml configuration that match the authorization server iss (issuer) and kid (key ID) claims of the incoming JWT

      jwt:
            issuer:
              my.authorization.server:
                default: ssh-rsa myValidationKey anEmail@domain.com
                kid-2016: ssh-rsa myCurrentValidationKey anEmail@domain.com
          

    • JWKS_URL: Provide a URL ending with /.well-known/jwks.json from which the Gateway can retrieve the JWKS

  • Use system proxy: When using JWKS_URL, optionally make the HTTP call through a system-wide proxy configured in DSAPI.yml

  • Extract JWT Claims: Allow claims to be accessed in the jwt.claims context attribute during request/response via DSAPI Expression Language (EL), e.g., extract the issuer claim from the JWT:

    {#context.attributes['jwt.claims']['iss']}
        
  • Propagate Authorization header: Propagate the header containing the JWT token to the backend APIs

  • User claim: Set the payload claim where the user can be extracted. The default sub value is standard with JWTs.

  • Client ID claim: Override the default claim where the client ID can be extracted. By default, the Gateway checks the azp claim, then the aud claim, and finally the client_id claim.

  • Ignore missing CNF: Ignores CNF validation if the token doesn't contain any CNF information

  • Enable certificate bound thumbprint validation: Validates the certificate thumbprint extracted from the access_token against the one provided by the client

  • Extract client certificate from headers: Extracts the client certificate from the request header (provided in Header name field). Necessary when the mTLS connection is handled by a proxy.

  • Additional selection rule: Allows you to use the EL to filter by contextual data (request headers, tokens, attributes, etc.) for plans of the same type (e.g., for two JWT plans, you can set different selection rules on each plan to determine which plan handles each request)

Once JWT configuration is complete and the plan is created and published, your API will be JWT-secured and subscribed consumers must call the API with an Authorization: Bearer your-JWT HTTP header.

Push

Introduction

A Push plan is used when an API contains an entrypoint that sends message payloads to API consumers (e.g., Webhook). This type of plan is unique in that the security configuration is defined by the API consumer, in the subscription request created in the Developer Portal. For example, when subscribing to a Webhook entrypoint, the API consumer specifies the target URL and authentication for the Gateway to use when sending messages.

Push plans do not apply to SSE entrypoints. Although messages are pushed from the server, the client application initiates message consumption.

Configuration

Push plans have the same configuration options as Keyless plans in APIM. The bulk of the configuration for a Push plan is set by the API consumer in the Developer Portal, and the content of the configuration varies by entrypoint type.

DSAPI currently supports Push plans for Webhook entrypoints

Creating and managing applications

Introduction

To access DSAPI APIs, consumers must register an application and subscribe to a published API plan. Applications act on behalf of the user to request tokens, provide user identity information, and retrieve protected resources from remote services and APIs.

This page contains the following sections:

Prerequisites

For an API consumer to create an application:

  • An admin must define the allowed types of applications that API consumers can create:
    • Default application type: API consumers can optionally define the client_id when creating a simple application.
    • Dynamic Client Registration (DCR) for applications: The API publisher must enable and configure DCR for the allowed application types. The client registration provider is responsible for creating the client_id and client_secret for each application that registers.
  • An API consumer must have a user account to register an application and subscribe to an API (see Administration)

Default application configuration

The default simple application enables an API consumer to define the client_id for use in JWT and OAuth API plans. To allow API consumers to create a simple application:

  1. Log in to your APIM Console

  2. Select Settings from the left nav

  3. Select Client Registration from the inner left nav

    Client Registration

  4. Under Default application type, toggle Simple ON

To expedite API consumption, a default application is automatically created for every new user (not including admins). This can be disabled in the DSAPI.yml file as shown below:

user:
    login:
       # Create a default application when user connects to the portal for the very first time (default true)
       defaultApplication: false

Manage applications

An application is usually shared through a developer application and retrieves information such as API keys and API analytics. Initially, only the application’s creator can view and manage the application. By default, APIM includes three membership roles:

RoleDescription
Primary ownerThe creator of the applcation. Can perform all possible API actions.
OwnerA lighter version of the primary owner role. Can perform all possible actions except delete the application.
UserA person who can access the application in read-only mode and use it to subscribe to an API.

Only users with the required permissions can manage application members. See User Management and Permissions.

Delete and restore applications

To delete an application, the primary owner must:

  1. Log in to your APIM Console

  2. Select Applications from the left nav

  3. Select your application

  4. Select Global Settings from the inner left nav

  5. In the Danger Zone, click Delete

    Delete an application

  • A deleted application has a status of ARCHIVED, meaning:
    • The link to the primary owner of the application is deleted.
    • Its subscriptions are closed. In the case of a subscription to an API Key plan, the keys are revoked.
    • Notification settings are deleted.
  • An ADMINcan restore applications in the APIM Console and will become the primary owner of the application
    • An application’s subscriptions will be restored withPENDING status. The API publisher must manually reactivate previous subscriptions.

Managing and transferring Subscriptions

Introduction

A subscription is a successful contract between an API publisher and an API consumer. A subscription is created when an API consumer uses a registered application to make a subscription request to a published plan and an API publisher either manually or automatically validates the subscription.

Keyless plan subscriptions

APIs with Keyless plans do not require the API consumer to create an application or submit a subscription request because no authorization is required to access the backend API.

This page includes the following sections:

Subscription requests

API consumers can subscribe to APIs with published plans during the application creation process, or after the application is created, through the APIM Console or Developer Portal.

Whether an application has an associated client_id depends on how it was configured. To subscribe to OAuth2 or JWT plans, the application must have a client_id.
>

To subscribe to an API via the APIM Console:

  1. Log in to your APIM Console

  2. Select Applications from the left nav

  3. Select Subscriptions from the inner left nav

  4. Click the + Create a subscription button

    Create a subscription

  5. Search for the API you want to subscribe to. To be searchable the API consumer must have access to the API, i.e., the API must be public or the API consumer must be a member of it.

  6. Select the plan you would like to request a subscription to

    Select the subscription plan

  7. Click Create to see the subscription details

Manage subscriptions

When creating a plan, you can enable subscription auto-validation to immediately approve subscription requests. If Auto validate subscription is disabled, the API publisher must approve all subscription requests.

To be notified of subscription validation tasks, enable Notifications

To manage subscriptions in APIM Console:

  1. Log in to your APIM Console
  2. Select APIs from the left nav
  3. Select the API with subscriptions to manage
  4. Select Consumers from the inner left nav
  5. Click the Subscriptions header tab
  6. Select the request or subscription you want to manage
  7. Validate or reject the subscription
    • If validating, fill out the Validate your subscription form, then click Validate

      Validate the subscription

API Key plans

Subscriptions to API Key plans include additional security management settings:

  • Renew: Generate a new API key or provide a custom API key. The existing API key will be automatically invalidated after two hours.

    Renew an API key

  • Revoke: Immediately invalidate an existing API key. This option is reversible.

    Revoke an API key

  • Expire: Set a date/time to automatically invalidate an existing API key

    Expire an API key

Transfer subscriptions

API publishers can transfer active subscriptions to a new plan with the same security type:

  1. Log in to your APIM Console

  2. Select APIs from the left nav

  3. Select the API with the subscription to transfer

  4. Select Consumers from the inner left nav

  5. Click the Subscriptions header tab

  6. Click the pencil icon of the subscription you want to transfer

  7. At the bottom of the Subscription details section, click Transfer

    Transfer a subscription

  8. Select the plan to transfer the subscription to, then click Transfer

    Specify and confirm subscription transfer

API Measurement, Tracking, and Analytics

DSAPI offers several options for measuring, tracking, and analyzing APIs to easily maintain visibility into performance and consumption.

Dashboards

Overview

The DSAPI Dashboard is an area in the UI where you can create custom dashboards reflecting API performance, status, lifecycle stage, etc. The Dashboard is comprised of 3 modules: Overview, APIs health-check, and My tasks.

Dashboard overview

  • Overview: Shows a summary of API metrics for the selected time interval via configurable charts and information, followed by a paginated list of API events
  • APIs health-check: Shows API status and availability data based on filter criteria and the selected time interval
  • My tasks: Starting with the most recent, shows the list of tasks to be validated

Create a dashboard

You can configure your DSAPI Dashboard by creating dashboard charts for three different categories: Platform, API, and Applications. To create a chart:

  1. Log in to your APIM Console

  2. Click on Settings in the left nav

  3. Click on Analytics in the inner left nav

  4. Choose to ADD A NEW PLATFORM DASHBOARD, ADD A NEW API DASHBOARD, or ADD A NEW APPLICATION DASHBOARD

    Add a dashboard to a category

  5. Define your Dashboard name and Query filter (optional), then click SAVE

    Add a dashboard

  6. Click the plus icon at the bottom of the screen to add a widget

  7. Click the pencil icon to configure the widget:

    Configure your widget

    • Give your widget a Name and (optionally) a Subtitle
    • Select a Widget type from the drop-down menu, e.g., table
    • Select a Field from the drop-down menu, e.g., API, or use a custom field
    • Choose the information to display for your selected field
    • Clice SAVE
  8. (Optional) Click ENABLE PREVIEW to preview your new dashboard and widget

View your dashboard

To view your new dashboard and chart:

  1. Log in to your APIM Console

  2. Click on Analytics in the left nav

  3. Under the Dashboard header, select your dashboard from the Select a dashboard drop-down menu

    View your dashboard

Edit an existing dashboard

To modify existing dashboards:

  1. Log in to your APIM Console
  2. Click on Settings in the left nav
  3. Click on Analytics in the inner left nav
  4. Click on the hyperlink of an existing dashboard
  5. Use the pencil icons to edit widget settings, or the plus icon to add a new widget
  6. Click SAVE

API Quality

The API Quality feature is only available to v2 APIs

Overview

The DSAPI API Quality feature enables API governance by allowing you to create and automatically assign customizable scores based on certain variables determined to impact API quality. If API Quality is enabled, APIs that you create in DSAPI will automatically be assigned an API quality score.

Configure API Quality

API Quality is configured at the Portal Settings level. To access these settings:

  1. Log in to your API Management Console.

  2. Select Settings from the left nav.

  3. Select API Quality from the inner left nav

  4. Configure pre-built quality characteristics that DSAPI automatically enforces:

    API Quality settings

    • Enable API review: Toggle ON to build API Quality review into your workflow and not allow an API to be published without review
    • Enable API Quality Metrics: Toggle ON to enable quality to be measured and viewable within an APIs details
    • Description: Description weight assigns a weight to the overall description, while Description minimum length, Logo weight, Categories weight, and Labels weight assign weights to description characteristics
    • Documentation: Specify Functional documentation weight and Technical documentation weight
    • Endpoint: Specify Healthcheck weight
  5. Click + Add new quality rule to configure a custom rule that will be enforced manually:

    Create a manual custom rule

    • Specify the rule name, description, and weight
    • Click Create

API Quality view and review

To view an API Quality score:

  1. Log in to the API Management Console

  2. Select APIs from the left nav

  3. Select your API

  4. From the inner left nav, select Info under General

  5. Scroll to the Quality section to view the API Quality score and rules that are impacting it

    View the API Quality score

DSAPI Expression Language

Overview

DSAPI Expression Language (EL) is used to query and manipulate object graphs and dynamically configure various aspects and policies of an API. It allows you to reference values from the current API transaction to use expressions to create dynamic filters, routing rules, and policies that respond to specific conditions or parameters.

EL is an extended version of the Spring Expression Language (SpEL) that augments standard SpEL capabilities by providing additional object properties inside the expression language context. As an extension of SpEL, all capabilities detailed in the SpEL documentation are available in EL. However, DSAPI has implemented customizations that are detailed below.

Object properties

Custom properties and attributes have special meanings in the DSAPI ecosystem:

  • Custom Properties: Defined at the API level and read-only during the Gateway's execution of an API transaction. You can learn more about how to set an API's custom properties here.
  • Attributes: Scoped to the current API transaction and can be manipulated during the execution phase through the assign-attributes policy. Attributes are used to attach additional information to a request or message via a variable that is dropped after the API transaction is completed.

The following sections define the scope and usage of EL:

Basic usage

The information below summarizes:

  • Object properties added to the EL context
  • How attributes are accessed for v4 and v2 APIs
  • Commonly used operators and functions

Expressions

Expressions in DSAPI are enclosed in curly braces {} and begin with the # symbol. Both dot notation and bracket notation are supported for accessing the properties of an object.

Example: {#context.attributes['user'].email}

Dot notation vs bracket notation

Please note that dot notation will not work with special characters:

{#request.headers.my-header} <- This will result in an error

Bracket notation should be used for property names that include a space or a hyphen, or start with a number:

{#request.headers['my-header']}

Lists

Expressions can be used to assign lists, e.g., {({'admin', 'writer'})}

  1. The outer enclosing brackets start and end the EL expression
  2. The parentheses indicates an object is being instantiated
  3. The list comprises the inner brackets and enclosed values, e.g., {'admin', 'writer'}

EL allows you to reference certain values injected into the EL context as object properties. The available object properties will be further detailed in later sections. EL adds the following root-level object properties:

  • {#api.properties}: Contains custom properties defined by the API publisher for that Gateway API.
  • {#dictionaries}: Contains custom dictionaries defined by the API publisher for that Gateway API.
  • {#endpoints}: Contains information about the Gateway API's respective endpoints.
  • {#request}: Contains information about the current API request.
  • {#response}: Contains information about the current API response.
  • {#message}: Contains information about the current API message.
  • {#node} : Contains information about the node hosting the instance of the Gateway handling the API transaction.

The attributes object property contains attributes that are automatically created by the APIM Gateway during an API transaction or added during the execution phase through the Assign Attributes policy. However, attributes fall into one of two categories based on API type:

  • {#context.attributes}: Contains attributes associated with v2 APIs or v4 Proxy APIs. A v4 Proxy API is created using the Proxy upstream protocol method.
  • {#message.attributes}: Contains attributes associated with v4 Message APIs. These APIs are created using the Introspect messages from event-driven backend method.

See the v4 API creation wizard for more details.

EL supports various operators, such as arithmetic, logical, comparison, and ternary operators. Examples of commonly used operators in DSAPI include:

  • Arithmetic operators: +, -, *, /
  • Logical operators: && (logical and), || (logical or), ! (logical not)
  • Comparison operators: ==, !=, <, <=, >, >=
  • Ternary operators: condition ? expression1 : expression2

EL provides a variety of built-in functions to manipulate and transform data in expressions. Examples of commonly used functions in DSAPI include:

  • String functions: length(), substring(), replace()
  • #jsonPath: Evaluates a jsonPath on a specified object. This function invokes JsonPathUtils.evaluate(…​), which delegates to the Jayway JsonPath library. The best way to learn jsonPath syntax is by using the online evaluator.
  • #xpath: To evaluate an xpath on some provided object. For more information regarding XML and XPath, see XML Support - Dealing with XML Payloads in the SpEL documentation.

jsonPath example

As an example of how jsonPath can be used with EL, suppose you have a JSON payload in the request body that contains the following data:

{
  "store": {
    "book": [
      {
        "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      {
        "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ]
  }
}

To extract the value of the price property for the book with title "The Lord of the Rings," you can use the following expression:

{#jsonPath(#request.content, "$.store.book[?(@.title=='The Lord of the Rings')].price")}

APIs

Using EL, you can access information about an API transaction through several root-level objects that are injected into the EL context: custom properties, dictionaries, and endpoints.

As an API publisher, you can define custom properties for your API. These properties are automatically injected into the expression language context and can be referenced during an API transaction from the {#api.properties} root-level object property.

Examples

  • Get the value of the property my-property defined in an API's custom properties using {#api.properties['my-property']}
  • Get the value of the property my-secret defined and encrypted in an API's custom properties using {#api.properties['my-secret']} to pass a secured property to your backend

Encrypted custom properties

When accessing an encrypted custom property, DSAPI's Gateway will automatically manage the decryption and provide a plain text value.

Dictionaries work similarly to custom properties, but you need to specify the dictionary ID as well as the dictionary property name. Dictionary properties are simply key-value pairs that can be accessed from the {#dictionaries} root-level object property.

Example

Get the value of the dictionary property dict-key defined in dictionary my-dictionary-id using {#dictionaries['my-dictionary-id']['dict-key']}.

When you define endpoints for your API, you need to give them a name that is a unique identifier across all endpoints of the API. This identifier can be used to get an endpoint reference (i.e., a URI) from the {#endpoints} root-level object property.

Example

When you create an API, a default endpoint is created that corresponds to the value you set for the backend property. This endpoint can be retrieved with EL by using the following syntax: {#endpoints['default']}.

Request

EL can be used to access request properties and attributes as described below.

Request object properties

The object properties you can access from the {#request} root-level object property and use for API requests are listed below.

Object PropertyDescriptionTypeExample
contentBody contentstring-
contextPathContext pathstring/v2/
headersHeaderskey / valueX-Custom → myvalue
hostThe host of the request. This is preferable to using the Host header of the request because HTTP2 requests do not provide this header.stringDSAPI.example.com
idIdentifierstring12345678-90ab-cdef-1234-567890ab
localAddressLocal addressstring0:0:0:0:0:0:0:1
methodHTTP methodstringGET
paramsQuery parameterskey / valueorder → 100
pathPathstring/v2/store/MyStore
pathInfoPath infostring/store/MyStore
pathInfosPath info partsarray of strings[,store,MyStore]
pathParamsPath parameterskey / valuestoreId → MyStore (see Warning for details)
pathParamsRawPath parametersstring/something/:id/**
pathsPath partsarray of strings[,v2,store,MyStore]
remoteAddressRemote addressstring0:0:0:0:0:0:0:1
schemeThe scheme of the request (either http or https)stringhttp
hoststring
sslSSL session informationSSL object-
timestampTimestamplong1602781000267
transactionIdTransaction identifierstringcd123456-7890-abcd-ef12-34567890
uriURIstring/v2/store/MyStore?order=100
versionHTTP versionstringHTTP_1_1
  • Get the value of the Content-Type header for an incoming HTTP request using {#request.headers['content-type']}
  • Get the second part of the request path using {#request.paths[1]}

Request context attributes

When APIM Gateway handles an incoming API request, some object properties are automatically created or added during the execution phase through the Assign Attributes policy. These object properties are known as attributes. Attributes can be accessed from the {#context.attributes} root-level object property.

Some policies (e.g., the OAuth2 policy) register other attributes in the request context. For more information, refer to the documentation for individual policies.

Request context attributes and examples are listed below.

Object PropertyDescriptionTypeNullable
apiCalled APIstring-
api-keyThe API key used (for an API Key plan)stringX (for no API Key plan)
applicationThe authenticated application making incoming HTTP requestsstringX (for Keyless plan)
context-pathContext pathstring-
planPlan used to manage incoming HTTP requestsstring-
resolved-pathThe path defined in policiesstring-
user-id

The user identifier of an incoming HTTP request:

* The subscription ID for an API Key plan

* The remote IP for a Keyless plan

string-
  • Get the value of the user-id attribute for an incoming HTTP request using {#context.attributes['user-id']}
  • Get the value of the plan attribute for an incoming HTTP request using {#context.attributes['plan']}

SSL object properties

The object properties you can access in the ssl session object from the {#request.ssl} root-level object property are listed below.

Object PropertyDescriptionTypeExample
clientHostHost name of the clientstringclient.domain.com
clientPortPort number of the clientlong443
clientClient informationPrincipal object-
serverServer informationPrincipal object-
Get the client HOST from the SSL session using {#request.ssl.clientHost}

Principal objects

The client and server objects are of type Principal. A Principal object represents the currently authenticated user who is making the request to the API and provides access to various user attributes such as username, email address, roles, and permissions.

The Principal object is typically used with security policies such as OAuth2, JWT, or basic authentication to enforce access control and authorization rules on incoming requests. For example, a policy can check if the current user has a specific role or permission before allowing them to access a protected resource.

If the Principal object is not defined, client and server object values are empty. Otherwise, there are domain name attributes you can access from the {#request.ssl.client} and {#request.ssl.server} Prinicipal objects as shown in the table below:

Limitation on arrays

All attributes of the Principalobject are flattened to be accessed directly with dot or bracket notation. While some of these attributes can be arrays, EL will only return the first item in the array. To retrieve all values of an attribute, use the attributes object property shown in the table and examples below.

Object PropertyDescriptionTypeExample
attributesRetrieves all the Prinicipal object's domain name attributes key / value"ou" → ["Test team", "Dev team"]
businessCategoryBusiness categorystring-
cCountry codestringFR
cnCommon namestring-
countryOfCitizenshipRFC 3039 CountryOfCitizenshipstring-
countryOfResidenceRFC 3039 CountryOfResidencestring-
dateOfBirthRFC 3039 RFC 3039 DateOfBirthstring19830719000000Z
dcDomain componentstring-
definedReturns true if the Principal object is defined and contains values. Returns false otherwise.boolean-
descriptionDescriptionstring-
dmdNameRFC 2256 directory management domainstring-
dnFully qualified domain namestring-
dnQualifierDomain name qualifierstring-
eEmail address in Verisign certificatesstring-
emailAddressEmail address (RSA PKCS#9 extension)string-
genderRFC 3039 Genderstring"M", "F", "m" or "f"
generationNaming attributes of type X520namestring-
givennameNaming attributes of type X520namestring-
initialsNaming attributes of type X520namestring-
lLocality namestring-
nameNamestring-
nameAtBirthISIS-MTT NameAtBirthstring-
oOrganizationstring-
organizationIdentifierOrganization identifierstring-
ouOrganization unit namestring-
placeOfBirthRFC 3039 PlaceOfBirthstring-
postalAddressRFC 3039 PostalAddressstring-
postalCodePostal codestring-
pseudonymRFC 3039 Pseudonymstring-
roleRolestring-
serialnumberDevice serial number namestring-
stState or province namestring-
streetStreetstring-
surnameNaming attributes of type X520namestring-
tTitlestring-
telephoneNumberTelephone numberstring-
uidLDAP User idstring-
uniqueIdentifierNaming attributes of type X520namestring-
unstructuredAddressUnstructured address (from PKCS#9)string-

Standard Object Properties

  • Get the client DN from the SSL session: {#request.ssl.client.dn}
  • Get the server organization from the SSL session: {#request.ssl.server.o}

Arrays and boolean logic

  • Get all the organization units of the server from the SSL session:
    • {#request.ssl.server.attributes['ou'][0]}
    • {#request.ssl.server.attributes['OU'][1]}
    • {#request.ssl.server.attributes['Ou'][2]}
  • Get a custom attribute of the client from the SSL session: {#request.ssl.client.attributes['1.2.3.4'][0]}
  • Determine if the SSL attributes of the client are set: {#request.ssl.client.defined}

Response

The object properties you can access for API responses from the {#response} root-level object property are listed below.

Object PropertyDescriptionTypeExample
contentBody contentstring-
headersHeaderskey / valueX-Custom → myvalue
statusStatus of the HTTP responseint200
Get the status of an HTTP response: {#response.status}

Message

The object properties you can access for API messages from the {#message} root-level object property are listed below. A message (either sent or received) may also contain attributes that can be retrieved via {#message.attributes[key]}.

The EL used for a message does not change based on phase. EL is executed on the message itself, so whether the message is sent in the subscribe or publish phase is irrelevant.

Object PropertyDescriptionTypeExample
attributeNamesThe names of the attributeslist / array-
attributesAttributes attached to the messagekey / value-
contentContent of the messagestring-
contentLengthSize of the contentinteger-
errorFlag regarding the error state of the messageboolean-
headersHeaders attached to the messagekey / value-
idID of the messagestring-
metadataMetadata attached to the messagekey / value-
  • Get the value of the Content-Type header for a message using {#message.headers['content-type']}
  • Get the size of a message using {#message.contentLength}

Nodes

A node is a component that represents an instance of the DSAPI Gateway. Each node runs a copy of the Gateway that is responsible for handling incoming requests, executing policies, and forwarding requests to the appropriate upstream services. The object properties you can access for nodes from the {#node} root-level object property are listed below.

Object PropertyDescriptionTypeExample
idNode IDstring975de338-90ff-41ab-9de3-3890ff41ab62
shardingTagsNode sharding tagarray of string[internal,external]
tenantNode tenantstringEurope
versionNode versionstring3.14.0
zoneZone the node is grouped instringeurope-west-2
Get the version of a node : {#node.version}

Mixin

In previous examples, we showed various ways to manipulate objects available in the EL context. You can also mix root-level object property usage to provide an increasingly dynamic configuration.

For example, to retrieve the value of an HTTP header where the name is based on an API custom property named my-property, use {#request.headers[#api.properties['my-property']]}.

Policies

You can use the EL to update some aspects of policy configuration. The policy specifies if it supports EL or not by including a Condition section in the Policy Studio configuration.

Assign attributes policy supports EL conditions

Conditions

You can use the EL to set a condition of execution (see 'conditional policies and flows conditions') and it is possible to use logical operators such as && or ||, as shown in the example below:

{#request.headers['my-header'] != null && #request.headers['my-header'][0] =="my-value"}

Alternate equality check

You can use the equals() method instead of ==. When you use .equals(), it is recommended to put the string first to prevent an error. For example, if #request.headers['my-header'] is null , then 'my-value'.equals(#request.headers['my-header'])will prevent an error.

Debugging

In case of an error when using EL, an exception will be raised :

The template evaluation returns an error. Expression: {#context.error}

If debugging your expression is difficult, consider the following example for guidance:

Assume {#request.content.length() >= 10} is the conditional expression on a flow. When testing, you are expecting the condition to evaluate to false and stop the flow from executing, but the flow continues to function unexpectedly.