Import Swagger to Define and Control API Groups
On This Page:
Objective
This guide provides instructions on how to import a Swagger file to define API groups and set rules to control access to APIs, enabling granular API access control ability. To know more about security concepts, see Security.
Enabling this feature includes preparing the Swagger files for your API definitions, importing them to F5 Distributed Cloud Services, and applying them to your load balancer. Using the instructions provided in this guide, you can import swagger files, attach to your load balancer, and apply service policies to restrict access to the API groups defined in the Swagger files.
Prerequisites
The following prerequisites apply:
-
F5 Distributed Cloud Services Account. If you do not have an account, see Create an Account.
-
A HTTP Load Balancer advertising your application.
- Note: For instructions on how to delegate your domain to F5 Distributed Cloud, see HTTP Load Balancer. See the vK8s Deployment guide for deploying your applications on the F5 Distributed Cloud's Network Cloud or Edge Cloud.
Configuration
Importing Swagger files to define API groups and controlling access to those groups includes the following sequences of activities:
- Prepare Swagger files containing API groups and definitions and import them using Console.
- Define service policy to control access to the API groups.
Note: You can create API definition as part of HTTP load balancer configuration or separately using the
Manage
>API Definition
option. This guide presents instructions to create a separate API definition and later apply them to load balancer.
Import Swagger Files and Create API Definitions
Do the following to prepare and import Swagger files containing API groups and definitions.
Step 1: Prepare Swagger files.
Prepare Swagger files on your local machine with the API groups and definitions as per your requirement. The following are sample files for your reference. Here one file is for user API and other is for REST API.
Note: You can add tags to the API groups to identify and apply controls based on the tags. For example, you can specify the
x-volterra-api-group
tag with value such assensitive
to denote that access to this group must be tightly controlled. The REST API file in the following samples specifies this tag.
User API
{
"swagger": "2.0",
"info": {
"description": "Juice Shop User API",
"title": "Juice Shop User API",
"version": "v0"
},
"basePath": "/api",
"schemes": [
"http",
"https"
],
"paths": {
"/Addresss": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"responses": {
"200": {
"description": ""
}
}
}
},
"/Addresss/{id}": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/BasketItems/": {
"post": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
{
"description": "",
"in": "body",
"name": "body",
"schema": {
"example": [
"{\"ProductId\":6,\"BasketId\":\"6\",\"quantity\":1}",
"{\"ProductId\":9,\"BasketId\":\"6\",\"quantity\":1}",
"{\"ProductId\":24,\"BasketId\":\"6\",\"quantity\":1}"
],
"properties": {
"BasketId": {
"description": "Integer",
"pattern": "-?\\d+",
"type": "string"
},
"ProductId": {
"type": "integer"
},
"quantity": {
"type": "integer"
}
},
"required": [
"quantity",
"BasketId",
"ProductId"
],
"type": "object"
}
}
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/BasketItems/{id}": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
{
"description": "",
"in": "body",
"name": "body",
"schema": {
"example": [
"{\"ProductId\":6,\"BasketId\":\"6\",\"quantity\":1}",
"{\"ProductId\":9,\"BasketId\":\"6\",\"quantity\":1}",
"{\"ProductId\":24,\"BasketId\":\"6\",\"quantity\":1}"
],
"properties": {
"BasketId": {
"description": "Integer",
"pattern": "-?\\d+",
"type": "string"
},
"ProductId": {
"type": "integer"
},
"quantity": {
"type": "integer"
}
},
"required": [
"quantity",
"BasketId",
"ProductId"
],
"type": "object"
}
},
{
"name": "id",
"in": "path",
"description": "ID",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/Cards/{id}": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/Cards": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"responses": {
"200": {
"description": ""
}
}
}
},
"/Cards/": {
"post": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"responses": {
"200": {
"description": ""
}
}
}
},
"/Challenges/": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
{
"description": "",
"in": "query",
"name": "name",
"type": "string"
}
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/Products/{id}": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/Quantitys/": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/Deliverys": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/Deliverys/{id}": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/SecurityAnswers": {
"post": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
{
"description": "",
"in": "body",
"name": "body",
"schema": {
"example": [
"{\"UserId\":22,\"answer\":\"09/77/33\",\"SecurityQuestionId\":3}"
],
"properties": {
"SecurityQuestionId": {
"type": "integer"
},
"UserId": {
"type": "integer"
},
"answer": {
"description": "Integer",
"pattern": "-?\\d+",
"type": "string"
}
},
"required": [
"UserId",
"SecurityQuestionId",
"answer"
],
"type": "object"
}
}
],
"responses": {
"200": {
"description": ""
}
}
}
}
}
}
REST API
{
"swagger": "2.0",
"info": {
"description": "Juice Shop REST",
"title": "Juice Shop REST",
"version": "v1"
},
"basePath": "/rest",
"schemes": [
"http",
"https"
],
"paths": {
"/basket/{id}": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/captcha": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/languages": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/memories": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/saveLoginIp": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/products/{id}/reviews": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": ""
}
}
},
"put": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/products/{id}": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": ""
}
}
},
"post": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/basket/{id}/checkout": {
"post": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/wallet/balance": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
],
"responses": {
"200": {
"description": ""
}
},
"x-volterra-api-group":"sensitive"
}
},
"/track-order/{id}": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/user/whoami": {
"get": {
"consumes": [
"application/json"
],
"description": "Swagger auto-generated from learnt schema",
"parameters": [
],
"responses": {
"200": {
"description": ""
}
},
"x-volterra-api-group":"sensitive"
}
}
}
}
Step 2: Log into Console and import Swagger files.
- Switch to
Web App & API Protection
service and change to desired namespace. - Go to
Manage
>Files
>Swagger Files
. ClickAdd Swagger File
.
- Enter a name in the metadata section.
- Go to
Upload Swagger File
section and clickUpload File
.
- Select the Swagger file when prompted and click
Upload
. - Click
Save and Exit
to create the Swagger file objects in Console. - Repeat the previous steps for importing more Swagger files.
- Click
...
>Copy Latest Version's URL
for a Swagger file object in Console to copy its path. This is useful to create API definitions in the next step.
Step 3: Create API definitions and groups.
- Go to
Manage
>API Management
>API Definition
. ClickAdd API Definition
. - Enter a name in the metadata section.
- Go to
Swagger Specs
section and click on theEnter swagger specs
field. - Enter the Swagger file path you copied in previous step.
- Click
Add item
and add entries for more Swagger files.
- Click
Save and Exit
to create API definition objects in Console. - Click
...
>Show Child Objects
to view the list of API groups and API definitions. This example configures 3 API definition objects and the following is an example definition:
- Note down the names of the API definitions as this is used in the service policy rules to control access.
Create Service Policy to Control Access to APIs
Do the following to create service policies to control access to API groups based on API definitions and apply them to load balancer.
Step 1: Go to load balancers and start editing your load balancer.
- Switch to
Load Balancers
service and change to desired namespace. - Select
Manage
>Load Balancers
>HTTP Load Balancers
. A list of load balancers is presented. - Click
...
>Manage Configuration
for your load balancer. - Click
Edit Configuration
on the manage configuration screen.
Step 2: Attach API definitions to load balancer.
- Go to
Security Configuration
and enable theShow Advanced Fields
option. - Scroll down to the
API Definitions
section and clickAdd item
.
- Click on the
Select API definition
field and select the API definitions created in the previous section. You can useAdd item
to add more than one definitions.
Step 3: Start creating service policies.
In the same Security Configuration
section, scroll up do the following:
- Select
Apply Specified Service Policies
for theService Policies
field. - Click
Configure
under theApply Specified Service Policies
field. - Click on the
Select service policy
field in thePolicies
screen and selectCreate new service policy
option. - Enter a name for the policy in the metadata section and go to
Rules
section. - Select
Custom Rule List
for theSelect Policy Rules
field and clickConfigure
under theRules
field.
Step 4: Start creating service policy rules.
- Click
Add item
in theRules
screen. - Enter a name in the metadata section and click
Configure
in theRule Specification
section. - Select
Allow
forAction
field in theAction
section. - Scroll down to
Advanced Match
section and clickConfigure
for theAPI Group Matcher
field. - In the
API Group Matcher
screen, enter an API group name string in theMatch
field. You can useAdd item
option to specify more than one group. - Click
Apply
to add the matcher and clickApply
to add the rule specification. ClickAdd item
to add the rule. - Create one more rule using the
Add item
option in the rules section. SetDeny
as theAction
and spcficy another API group to which you want to deny access (for example, all base URLs).
This example configures the following rules:
- The first rule allows the
all-operations
APIs.
- The second rule denys the
base-urls
APIs.
- The third rule allows rest all with the action as
Allow
. Note that there is no need of API matching for the third rule.
The sample order of service policy rules is as shown in the following image. This order is important as the rules are executed in the same order.
Note: This example creates a positive security model that only allows requests to operations that are specified in the swagger file for each specified base URL. Requests to all operations (path + method) specified in swagger files are allowed and requests to any unspecified operations under base URLs are denied. Requests sent to other URLs that do not match base URL are allowed.
Step 4: Complete creating service policy rules and policy.
- Check that you created all rules as per your requirement. Click
Apply
in theRules
section. - Click
Continue
to add the the service policy to the load balancer. - Click
Save and Exit
to apply changes to load balancer configuration.