Building an Private API Manager with Terraform: Token-based validation policy or OAuth Authentication

Danushka Lakmina
5 min readFeb 18, 2023

--

In this article, we will explore the process of creating an API manager using Terraform, a popular infrastructure-as-code tool that enables us to provision and manage our cloud resources programmatically. We will also discuss the benefits and drawbacks of two common authentication mechanisms for API security: token-based authentication and certificate-based authentication. By leveraging the power of Terraform and selecting the appropriate authentication method for your use case, you can effectively manage your APIs and protect your sensitive data against unauthorised access.

Create Api Manager module using terraform

Inside the ‘apim.tf’ file, you can also define the specific configuration settings for the API Manager instance, such as the pricing tier, the number of instances, and the policies to be enforced. Additionally, you can configure the authentication mechanism for your APIs using either token-based authentication or certificate-based authentication, depending on your use case.

By properly defining the resources and attributes in the ‘apim.tf’ file, you can effectively provision and manage your Azure API Manager instance using Terraform. This allows for streamlined and repeatable deployments, as well as enabling effective version control of your API Manager infrastructure.”

resource "azurerm_api_management" "apim" {
location = var.location
name = var.apim_name
publisher_email = var.publisher_email
publisher_name = var.publisher_name
resource_group_name = var.resource_group_name
sku_name = var.sku_name
# tags = var.tags
virtual_network_type = var.virtual_network_type



identity {
type = "SystemAssigned"
}

protocols {
enable_http2 = false
}

sign_up {
enabled = false

terms_of_service {
consent_required = false
enabled = false
}
}

dynamic "virtual_network_configuration" {
for_each = var.virtual_network_type=="Internal"?[1]:[]
content {
subnet_id = var.apim_subnet_id
}
}

lifecycle {
ignore_changes = [hostname_configuration]
}

}

“Within the context of developing APIs, an API endpoint is a critical component that enables communication between different software systems. To create an API endpoint in JSON format, a configuration file named ‘api_endpoint.tf’ can be utilized. This file contains the necessary specifications and configurations that define the behavior and functionality of the endpoint, including the response format, headers, parameters, and other related details. By carefully defining and configuring the ‘api_endpoint.tf’ file, developers can ensure that the resulting API endpoint is robust, secure, and effective in meeting the needs of its intended users.

resource "azurerm_api_management_api" "apim_api" {
name = var.api_name
resource_group_name = var.resource_group_name
api_management_name = var.apim_name
revision = "1"
display_name = var.api_name
path = var.path
protocols = ["https"]
service_url = var.backend_url
subscription_required = false

import {
content_format = "swagger-json"
content_value = file("${path.module}/api-content/prodswagger.json")
}

oauth2_authorization {
authorization_server_name = var.auth_name

}
}

The ‘api_endpoint.tf’ file is responsible for calling the JSON script that creates the API. The JSON script contains a set of instructions that define the API’s structure and behavior, including the endpoints, request methods, response formats, and other relevant details. By properly configuring the ‘api_endpoint.tf’ file to call the JSON script, developers can create an API that is functional and efficient, and that meets the requirements of its intended use case.

{
"swagger": "2.0",
"info": {
"title": "API_List",
"version": "1.0"
},
"host": "<host-name>",
"schemes": [
"http",
"https"
],
"securityDefinitions": {
"apiKeyHeader": {
"type": "apiKey",
"name": "Ocp-Apim-Subscription-Key",
"in": "header"
},
"apiKeyQuery": {
"type": "apiKey",
"name": "subscription-key",
"in": "query"
}
},
"security": [
{
"apiKeyHeader": []
},
{
"apiKeyQuery": []
}
],
"paths": {
"/status/*": {
"get": {
"description": "baseGet",
"operationId": "baseget",
"summary": "baseGet",
"responses": {
"200": {
"description": "null"
}
}
}
},
"/*": {
"post": {
"description": "BasePost",
"operationId": "basepost",
"summary": "BasePost",
"responses": {
"200": {
"description": "null"
}
}
},
"put": {
"description": "BasePut",
"operationId": "baseput",
"summary": "BasePut",
"responses": {
"200": {
"description": "null"
}
}
},
"delete": {
"description": "baseDelete",
"operationId": "basedelete",
"summary": "baseDelete",
"responses": {
"200": {
"description": "null"
}
}
}
}
},
"tags": []
}

Token base authentication

“The ‘api_tb_policy.tf’ file provides a means of specifying token validation policies that can be used to enable secure authentication and authorization mechanisms for APIs. By configuring the ‘api_tb_policy.tf’ file, developers can define the criteria for accepting or rejecting authentication tokens, as well as specify the appropriate authorization levels for users accessing different API endpoints. With this file, developers can ensure that only authorized users can access sensitive data or perform specific actions, which helps to mitigate the risk of security breaches and unauthorized access to critical systems.

resource "azurerm_api_management_api_policy" "api_endpoint" {
api_name = var.api_name
api_management_name = var.apim_name
resource_group_name = var.resource_group_name

xml_content = <<XML
<policies>
<inbound>
<base />
<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized. Access token is missing or invalid.">
<openid-config url="https://login.microsoftonline.com/a4726b0e-e64d-4ee6-bbd6-4b0027f42423/v2.0/.well-known/openid-configuration" />
<required-claims>
<claim name="aud">
<value>a9799af4-c423-4a5a-8ce5-80af0836a132</value>
</claim>
</required-claims>
</validate-jwt>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
XML
}

Oauth authentication

The ‘oauth.tf’ file provides a means of configuring certificate-based authentication for APIs using the OAuth protocol. By specifying the necessary parameters and configurations within this file, developers can enable secure, certificate-based authentication mechanisms for their APIs. Certificate-based authentication provides an additional layer of security by requiring the presentation of a valid digital certificate to verify the identity of the requester. With the ‘oauth.tf’ file, developers can define the requirements for accepting or rejecting digital certificates, as well as specify the necessary parameters for generating and validating these certificates. By using certificate-based authentication in combination with other security measures, developers can ensure that their APIs are robust, reliable, and secure against a variety of threats and attacks

resource "azurerm_api_management_authorization_server" "apim_auth" {

name = var.auth_name
api_management_name = var.apim_name
resource_group_name = var.resource_group_name
display_name = var.auth_name
authorization_endpoint = "https://login.microsoftonline.com/${var.tenant_id}/oauth2/v2.0/authorize"
client_id = var.client_id
client_secret = var.client_secret
client_registration_endpoint = "http://localhost"
token_endpoint = "https://login.microsoftonline.com/${var.tenant_id}/oauth2/v2.0/token"

default_scope = var.default_scope

client_authentication_method = [
"Body"
]

authorization_methods = [
"GET",
"POST",
]

bearer_token_sending_methods = [
"authorizationHeader"
]

grant_types = [
"authorizationCode",
]
}

Terraform provides a powerful set of tools for building and managing private API managers. By leveraging token-based validation policies or OAuth authentication mechanisms, developers can ensure that their APIs are secure, reliable, and accessible only to authorized users. Whether you choose to use token-based validation policies, OAuth authentication, or a combination of both, Terraform provides a flexible and extensible platform for building the private API manager that meets your unique needs and requirements. With its rich set of features and capabilities, Terraform is an excellent choice for building and deploying APIs in a private environment, providing developers with the tools they need to create robust and secure APIs that can be easily managed and maintained over time.

I hope this article has been informative and helpful in your journey to building a private API manager with Terraform. If you have any questions or feedback, please feel free to leave a comment or reach out to me directly. Additionally, if you found this article useful, I encourage you to share it with others who may benefit from this knowledge.

Thank you for taking the time to read this article and for your interest in building a private API manager with Terraform. Your support and engagement are greatly appreciated, and I hope to continue providing valuable insights and information in the future.

--

--

Danushka Lakmina

Skilled DevOps Engineer with 4+ years of hands-on experience supporting, automating, and optimizing mission critical deployments in AWS, leveraging config.