This topic describes how to use Alibaba Cloud API Gateway and machine-to-machine (M2M) technology to manage third-party access permissions. This method enables efficient, secure, and automated communication between systems.
Prerequisites
You have an M2M application server and client in IDaaS.

Overview
Follow these three steps to implement M2M authentication for your API. This ensures that callers are trusted and their permissions are controlled.
Register the API with Alibaba Cloud API Gateway.
Grant permissions to your M2M client.
Use plugin configurations in API Gateway to associate the protected API with the permission scopes of the M2M client.
Procedure
Register the API with API Gateway
Log on to the API Gateway console. In the navigation pane on the left, choose . Click Create Group.

Choose Backend Services in the menu, click Create Backend Service to register your business service endpoint with Alibaba Cloud API Gateway. This simplifies the management of your business service's API operations.

Attach your business service endpoint to the backend service that you created.

After you create the backend service, manage the API operations within it.
In the backend service that you created, click Create API. The Create API page appears.

On the Create API page, set Security Authentication to No Authentication for this example. Then, click Next.

In the Request Basic Settings section, enter the Request Path and select the HTTP Method.

When you define the backend service for the API, enter the actual request path. When a caller invokes the API using the specified request path, the request is mapped to the actual backend path.

Select the response ContentType and complete the API creation.

After you create the API, debug it in the console to verify that it is available and runs as expected.
Prepare the debugging environment. Select an environment and publish the API.

Debug the API in the staging environment by sending a request. In this example, the result is as expected. This confirms that the API is available.
Grant permissions to the M2M client
In the IDaaS console, navigate to your M2M application. In the authorized applications section, find your M2M application and grant it the required permission scopes. In this example, the `user:read:one` permission scope is granted to the client.
Configure API Gateway plugins
Configure gateway plugins to implement request authentication and authorization. This process associates the M2M permission scopes with API Gateway. You need to create two gateway plugins: a JWT Authentication plugin and a Parameter Access Control plugin.
Create a JWT Authentication plugin
Go to the API Gateway console. In the navigation pane on the left, choose . On the Plugin List page, click Create Plugin and set Plug-in Type to JWT Authentication.

Enter the script configuration. The JSON Web Key (JWK) information in the script must match the public key of the M2M server. In the IDaaS console, navigate to your M2M application. In the Application Settings section, copy the URL of the Public Key Endpoint. Open the URL in a browser to view the public key information. The public key information for this example is shown in the following figures:
Public key link in the console

Public key content displayed in the browser

Replace the `jwk` section in the following script with the JWT public key information that you retrieved.
Script configuration before replacement
--- parameter: id_token # Get the JWT from the specified parameter, which corresponds to the API parameter. parameterLocation: query # Optional when the API is in mapping mode. Required in pass-through mode. Specifies where to read the JWT. Only `query` and `header` are supported. bypassEmptyToken: false # Specifies whether to allow verification to pass if the JWT is empty. claimParameters: # Claims parameter transformation. The gateway maps JWT claims to backend parameters. - claimName: aud # Claim name. Public and private claims are supported. parameterName: aud # Name of the mapped parameter. location: query # Location of the mapped parameter. `query`, `header`, `path`, and `formData` are supported. - claimName: scope # Claim name. Public and private claims are supported. parameterName: scope # Name of the mapped parameter. location: query # Location of the mapped parameter. `query`, `header`, `path`, and `formData` are supported. - claimName: client_id # Claim name. Public and private claims are supported. parameterName: client_id # Name of the mapped parameter. location: query # Location of the mapped parameter. `query`, `header`, `path`, and `formData` are supported. preventJtiReplay: false # Specifies whether to enable anti-replay checks for `jti`. Default: false. # # The following content needs to be replaced. jwk: kty: RSA e: AQAB use: sig kid: O8fpdhrViq2zaaaBEWZITz # When only one JWK is configured, kid is optional. However, if the JWT contains a kid, the gateway verifies its consistency. alg: RS256 n: qSVxcknOm0uCq5vGsOmaorPDzHUubBmZZ4UXj-9do7w9X1uKFXAnqfto4TepSNuYU2bA_-tzSLAGBsR-BqvT6w9SjxakeiyQpVmexxnDw5WZwpWenUAcYrfSPEoNU-0hAQwFYgqZwJQMN8ptxkd0170PFauwACOx4Hfr-9FPGy8NCoIO4MfLXzJ3mJ7xqgIZp3NIOGXz-GIAbCf13ii7kSStpYqN3L_zzpvXUAos1FJ9IPXRV84tIZpFVh2lmRh0h8ImK-vI42dwlD_hOIzayL1Xno2R0T-d5AwTSdnep7g-Fwu8-sj4cCRWq3bd61Zs2QOJ8iustH0vSRMYdP5oYQScript configuration after replacement
--- parameter: id_token # Get the JWT from the specified parameter, which corresponds to the API parameter. parameterLocation: query # Optional when the API is in mapping mode. Required in pass-through mode. Specifies where to read the JWT. Only `query` and `header` are supported. bypassEmptyToken: false # Specifies whether to allow verification to pass if the JWT is empty. claimParameters: # Claims parameter transformation. The gateway maps JWT claims to backend parameters. - claimName: aud # Claim name. Public and private claims are supported. parameterName: aud # Name of the mapped parameter. location: query # Location of the mapped parameter. `query`, `header`, `path`, and `formData` are supported. - claimName: scope # Claim name. Public and private claims are supported. parameterName: scope # Name of the mapped parameter. location: query # Location of the mapped parameter. `query`, `header`, `path`, and `formData` are supported. - claimName: client_id # Claim name. Public and private claims are supported. parameterName: client_id # Name of the mapped parameter. location: query # Location of the mapped parameter. `query`, `header`, `path`, and `formData` are supported. preventJtiReplay: false # Specifies whether to enable anti-replay checks for `jti`. Default: false. # # Public Key of the JSON Web Key jwk: kty: RSA e: AQAB use: sig kid: AUTHSKEY7Ph6QS83xkN76oRwvZsJT68ejJ4PdAXmk # When only one JWK is configured, kid is optional. However, if the JWT contains a kid, the gateway verifies its consistency. alg: RS256 n: i1tIYhXvfilaJi8kaIS8EpgsnDp6G4c1lEg2qRD_-1lY8jOIWAVcetq89itl7rjFJ9gmbKGBMJoutaxGHtbAkY0aINkg1_n_0NnNTZDt2UC1UNJaZh12bkYyubRLA_t6JS8PVSr5bpse1SErvDiumqU9CjxBUCd4K8R0ALxOwup6yY5gVT4Juia1bEVGPlJ-RnuMvXXbVmwuklKTiWNfBFw1lCDPftfzKVEDTXt4VphAWOT-CyZKJ8hcYiTnd_VaAYxjMQSCxmE-utrdXGhyDUaQobs0myvD2eJfzcSWG-qOTC7Hin8bvXIQ_v9BkJO3D6uoLpB14XQozWVTXaPTIw
Create a Parameter Access Control plugin
Set Plugin Type to Parametric Access Control.

Enter the script content to implement access control. The following script uses a `condition` to implement the validation policy.
The script on the right uses the clientId and scope for validation as an example.
condition: "$clientId = 'app_m7hfgn66xkyyxlhpkiw5kjenhy' and $scope like '%user:read:one%'"
clientId is the application ID of the M2M client.
scope is the permission scope of the M2M client. Replace these two parameters as needed.
--- # # In this example, assume that our API request path is `/{userId}/...`, # The API uses JWT authentication, and the JWT contains two claims: userId and userType. # The validation conditions for this plugin are as follows: # - If userType=admin, all paths are allowed. # - If userType=user, only requests with a matching /{userId} path are allowed. parameters: scope: "Token:scope" clientId: "Token:client_id" # # The rules are processed sequentially. Based on whether the condition returns `true` or `false`, the `ifTrue` or `ifFalse` logic is executed. # `ALLOW` immediately results in a success. `DENY` immediately returns an error code to the client. # If neither `ALLOW` nor `DENY` is triggered, the next rule is executed. rules: - name: checkScope condition: "$clientId = 'app_m7hfgn66xkyyxlhpkiw5kjenhy' and $scope like '%user:read:one%'" ifFalse: "DENY" statusCode: 403 errorMessage: "No permission by client id: ${clientId}" responseHeaders: Content-Type: application/json X-IDaaS-clientId: ${clientId} X-IDaaS-scope: ${scope} responseBody: | <Reason>No permission by client id: ${clientId}</Reason>
Bind the plugins to the API
After you create the two plugins, bind them to the API operation. This creates a mapping between the permission scope and the API operation. In this example, this binding allows the `user:read:one` permission scope to control access to the `hello` API.
For each of the two plugins, click Bind API in the Actions column to bind the plugin to the API operation.

Verification and usage
After you complete the procedure, obtain an authorization token from the M2M server. The caller then uses this token to access the business API.
Obtain a token
Use the client_secret_post authentication method to obtain a token. Follow these steps:
Copy the Issuer URL of the M2M server.

Enter the following request parameters and send a request to the Issuer URL.
Parameter
Description
client_secret
The application secret of the M2M client.
client_id
The application ID of the M2M client.
grant_type
The static value `client_credentials`.
scope
The audience identifier of the M2M server plus the permission scope. In this example:
https://xxxx.aliyunidaas.com|user:read:one
Debug the API
Use the second-level domain of the group as the request URL. You can find this domain in the group details.

The input parameters are the token location and token parameter identifier that you defined in the JWT Authentication plugin. In this example, the input parameter key is `id_token`, and the value is the token that you retrieved in the previous step.
The request returns the expected result. This confirms that the M2M client has permission to access the `hello` API.

References
For more information about the working principles of M2M applications, see M2M applications (machine-to-machine permission management).
For information about how to use Alibaba Cloud Resource Access Management (RAM) to implement access without an AccessKey, see Configuration procedure for access without an AccessKey.