In API security and management, we often use a lot of different security mechanisms to protect the requested resource behind the API Gateway. One of these mechanisms is the validation of scopes to authorize a client on a specific sub-resource of the API. Most of the time the required scopes for the used HTTP verb are defined inside an OpenAPI Specification also known as a Swagger File.

OpenAPI Specification on Apigee

Inside an Apigee proxy, you can add an OpenAPI Spec Validation policy, which you can use to validate the incoming request’s message content and parameters such as query parameters, headers & cookies. Unfortunately, Apigee does not support the validation of required scopes specified inside of the uploaded OpenAPI Specification, resulting in a custom development.

Scope validation overview

The custom development is built out of two separate components, an external NodeJS script and a SharedFlow to bundle the Apigee policies used for this authorization mechanism.

Working of the NodeJS Script

The NodeJS script will, first of all, convert a given OpenAPI Specification in YML file to a more usable JSON format. After the conversion from YML to JSON it will start creating a “scope-mapping” object which contains every resource path, verb, and required scope defined in the provided OpenAPI Specification.

Because we need this “scope-mapping” object in Apigee, we will need some mechanism to make this available. Therefore the script will use the Apigee Management API to save the created “scope-mapping” object to a given KeyValueMap.

Working of the SharedFlow

The SharedFlow is built to require a single input parameter (in.Scope-Validation-OpenAPISpec.token_scopes) for the scopes found inside of the response after introspecting the incoming access token by the used Identity Provider. After the request is entered into the SharedFlow we will look up the scopes (extracted by the NodeJS script) from the KeyValueMap with as key the name of the current proxy.

When there is no entry found for the given proxy, a RaiseFault policy will be executed with a status code of 500 Internal Server Error to prevent further issues. If there is an entry, we will check if the required scopes (from KeyValueMap) are present inside of the input parameter (scopes extracted out of introspection response) using a JavaScript policy.

When the required scopes are not matching/are found inside of the access token scopes, we will return an HTTP status of 403 Forbidden. If the scope check succeeds we will forward the request to the rest of the proxy flow.

Open-Source Resources

If you, after reading this, are interested in using this mechanism or you are curious about the source code, you can take a look at our GitHub repository! In this repository, you will find everything you would need to reproduce the mechanism talked about in this blog article.

By Yorick Cleerbout