Akamai Adaptive Security Engine + Terraform

Akamai Adaptive Security Engine + Terraform

Akamai rolled out the brand new Adaptive Security Engine (ASE) as the newest Web Application Firewall (WAF) mode to help protect your web applications and API endpoints with Akamai's Application Security solutions.

These Application Security solutions use one of three WAF modes that are available, each offering a newer generation.

The WAF modes available are:

  1. Kona Rule Set (KRS) - the first WAF mode at Akamai, 300+ rules that are grouped into 8 distinct Attack Groups that help protect against Web Application and API attacks.
  2. Automated Attack Groups (AAG) - more automation from Akamai to help add intelligence to the Attack Groups.
  3. Adaptive Security Engine (ASE) - rolled out in late 2021, using AI/ML to verify the types of attacks and apply a new way of scoring requests properly.

All three WAF Modes are fully available to use with the Application Security solutions we offer and are fully compatible with the Akamai Developer tools that are available which are the Akamai AppSec API, AppSec CLI and the AppSec functionality built into our Akamai Terraform Provider.

How can you best use the Akamai Terraform Provider to use ASE as the WAF mode? We will dive into this in this blog.

Note: If you are not familiar yet with the Akamai Terraform Provider, read up on this blog to get started: blog.securitylevelup.eu/getting-started-wit..

In order to use the AppSec + Akamai Terraform Provider, you will need to have several resources in place that will manage your AppSec configuration and policy.

# resource for the Akamai Application Security configuration, tied to an Akamai Contract and Group. Can have multiple hostnames.
resource "akamai_appsec_configuration" "akamai_appsec" {
  contract_id = replace(var.contract_id, "ctr_", "")
  group_id  = replace(data.akamai_group.group.id, "grp_", "")
  name = var.configuration_name
  description = var.configuration_description
  host_names = [ var.hostname ]
}

This resource is the high level construct to manage you Akamai AppSec Configuration. It is tied to an Akamai Contract and Akamai Group, has a name and consists of an array of hostname that you want to protect.

# resource for the Akamai Application Security Policy, tied to an Application Security configuration.
resource "akamai_appsec_security_policy" "security_policy" {
  config_id = akamai_appsec_configuration.akamai_appsec.config_id
  security_policy_name = var.policy_name
  security_policy_prefix = var.policy_prefix
  default_settings = true
}

Each AppSec configuration can have one or multiple security policies. This is a great way to set up multiple policies to manage the types of traffic you have easily (for instance, web applications and API endpoint can be kept separate). This is the resource for the Akamai AppSec Security Policy, it is tied to an AppSec config, has a name and also a 4 digit alpha-numeric prefix that is a helpful way to identify the policy.

# resource to set the Application Security mode. Currently set to Adaptive Security Engine in Automatic mode which required the least management.
resource "akamai_appsec_waf_mode" "default_policy" {
  config_id = akamai_appsec_configuration.akamai_appsec.config_id
  security_policy_id = akamai_appsec_security_policy.security_policy.security_policy_id
  mode = "ASE_AUTO"
}

There is also a resource to set the WAF mode, this is tied to the Config and Policy and has a setting called mode. Using ASE_AUTO, will allow you to set the WAF mode to the Adaptive Security Engine in Automatic Mode.

For transparency, the possible options are:

KRS. Organizations must manually update their KRS rules. AAG. KRS rules are automatically updated by Akamai. ASE_AUTO. KRS rules are automatically updated by Akamai. See the note below for more information. ASE_MANUAL. Organizations must manually update their KRS rules. See the note below for more information.

Setting the WAF mode to ASE_AUTO is a great start. It can also be helpful to know the different Attack Groups available.

You can create resources for the Akamai Attack Groups, the values available are:

  • WAT: Web Attack Tools used to Attack
  • PROTOCOL: Web Protocol Attacks
  • SQL: SQL Injection Attacks
  • XSS: Cross-Site Scripting Attacks
  • LFI: Local File Inclusion Attacks
  • RFI: Remote File Inclusion Attacks
  • CMD: Command Injection Attacks
  • PLATFORM: Web Platform Attacks (based on type of tech stack/architecture you use)
  • POLICY: Web Policy Violations
  • OUTBOUND: Outbound traffic (not recommended to turn on by default, only after analyzing your traffic)

The code below can be used to set-up your Attack Groups. Exceptions for these groups can be added to a .json file. More info on that here: techdocs.akamai.com/application-security/re..

# 10 resources that reflect the Adaptive Security Engine Attack Groups. Exception can be added in JSON for each of the groups. Actions can be set to ALERT/DENY/NONE in variables.

resource "akamai_appsec_attack_group" "attack_group_web_attack_tool" {
  config_id = akamai_appsec_configuration.akamai_appsec.config_id
  security_policy_id = akamai_appsec_security_policy.security_policy.security_policy_id
  attack_group = "WAT"
  attack_group_action = var.attack_group_web_attack_tool_action
  condition_exception = file("${path.module}/appsec-snippets/attack-groups/attack_group_web_attack_tool_exception.json")
}

resource "akamai_appsec_attack_group" "attack_group_web_protocol_attack" {
  config_id = akamai_appsec_configuration.akamai_appsec.config_id
  security_policy_id = akamai_appsec_security_policy.security_policy.security_policy_id
  attack_group = "PROTOCOL"
  attack_group_action = var.attack_group_web_protocol_attack_action
  condition_exception = file("${path.module}/appsec-snippets/attack-groups/attack_group_web_protocol_attack_exception.json")
}

resource "akamai_appsec_attack_group" "attack_group_sql_injection" {
  config_id = akamai_appsec_configuration.akamai_appsec.config_id
  security_policy_id = akamai_appsec_security_policy.security_policy.security_policy_id
  attack_group = "SQL"
  attack_group_action = var.attack_group_sql_injection_action
  condition_exception = file("${path.module}/appsec-snippets/attack-groups/attack_group_sql_injection_exception.json")
}

resource "akamai_appsec_attack_group" "attack_group_cross_site_scripting" {
  config_id = akamai_appsec_configuration.akamai_appsec.config_id
  security_policy_id = akamai_appsec_security_policy.security_policy.security_policy_id
  attack_group = "XSS"
  attack_group_action = var.attack_group_cross_site_scripting_action
  condition_exception = file("${path.module}/appsec-snippets/attack-groups/attack_group_cross_site_scripting_exception.json")
}

resource "akamai_appsec_attack_group" "attack_group_local_file_inclusion" {
  config_id = akamai_appsec_configuration.akamai_appsec.config_id
  security_policy_id = akamai_appsec_security_policy.security_policy.security_policy_id
  attack_group = "LFI"
  attack_group_action = var.attack_group_local_file_inclusion_action
  condition_exception = file("${path.module}/appsec-snippets/attack-groups/attack_group_local_file_inclusion_exception.json")
}

resource "akamai_appsec_attack_group" "attack_group_remote_file_inclusion" {
  config_id = akamai_appsec_configuration.akamai_appsec.config_id
  security_policy_id = akamai_appsec_security_policy.security_policy.security_policy_id
  attack_group = "RFI"
  attack_group_action = var.attack_group_remote_file_inclusion_action
  condition_exception = file("${path.module}/appsec-snippets/attack-groups/attack_group_remote_file_inclusion_exception.json")
}

resource "akamai_appsec_attack_group" "attack_group_command_injection" {
  config_id = akamai_appsec_configuration.akamai_appsec.config_id
  security_policy_id = akamai_appsec_security_policy.security_policy.security_policy_id
  attack_group = "CMD"
  attack_group_action = var.attack_group_command_injection_action
  condition_exception = file("${path.module}/appsec-snippets/attack-groups/attack_group_command_injection_exception.json")
}

resource "akamai_appsec_attack_group" "attack_group_web_platform_attack" {
  config_id = akamai_appsec_configuration.akamai_appsec.config_id
  security_policy_id = akamai_appsec_security_policy.security_policy.security_policy_id
  attack_group = "PLATFORM"
  attack_group_action = var.attack_group_web_platform_attack_action
  condition_exception = file("${path.module}/appsec-snippets/attack-groups/attack_group_web_platform_attack_exception.json")
}

resource "akamai_appsec_attack_group" "attack_group_web_policy_violation" {
  config_id = akamai_appsec_configuration.akamai_appsec.config_id
  security_policy_id = akamai_appsec_security_policy.security_policy.security_policy_id
  attack_group = "POLICY"
  attack_group_action = var.attack_group_web_policy_violation_action
  condition_exception = file("${path.module}/appsec-snippets/attack-groups/attack_group_web_policy_violation_exception.json")
}

# Total Outbound is typically set to Not Used/None because it can negatively impact performance. Enable into ALERT/DENY with care.
resource "akamai_appsec_attack_group" "attack_group_total_outbound" {
  config_id = akamai_appsec_configuration.akamai_appsec.config_id
  security_policy_id = akamai_appsec_security_policy.security_policy.security_policy_id
  attack_group = "OUTBOUND"
  attack_group_action = var.attack_group_total_outbound_action
  #condition_exception = file("${path.module}/appsec-snippets/attack-groups/attack_group_total_outbound_exception.json")
}

You can find helpful Akamai AppSec templates on our GitHub, you can find these here: github.com/akamai/examples-terraform/blob/m..

There are more things you can specify when it comes to your Akamai AppSec configuration with the Akamai Terraform Provider, but we will keep this blog focused on how to enable WAF Mode ASE_AUTO.

If you have any questions on using the Akamai Terraform Provider, please reach out to me on Mike Elissen