Advanced WAF v16.0 - Declarative API

Since v15.1 (in draft), F5® BIG-IP® Advanced WAF can import Declarative WAF policy in JSON format.

The F5® BIG-IP® Advanced Web Application Firewall (Advanced WAF) security policies can be deployed using the declarative JSON format, facilitating easy integration into a CI/CD pipeline. The declarative policies are extracted from a source control system, for example Git, and imported into the BIG-IP.

Using the provided declarative policy templates, you can modify the necessary parameters, save the JSON file, and import the updated security policy into your BIG-IP devices. The declarative policy copies the content of the template and adds the adjustments and modifications on to it. The templates therefore allow you to concentrate only on the specific settings that need to be adapted for the specific application that the policy protects.

This Declarative WAF JSON policy is similar to NGINX App Protect policy. You can find more information on the Declarative Policy here :

Audience

This guide is written for IT professionals who need to automate their WAF policy and are familiar with Advanced WAF configuration. These IT professionals can fill a variety of roles:

  • SecOps deploying and maintaining WAF policy in Advanced WAF
  • DevOps deploying applications in modern environment and willing to integrate Advanced WAF in their CI/CD pipeline
  • F5 partners who sell technology or create implementation documentation

This article covers how to PUSH/PULL a declarative WAF policy in Advanced WAF:

  • With Postman
  • With AS3


Table of contents

  1. Upload Policy in BIG-IP
  2. Check the import
  3. Apply the policy
  4. OpenAPI Spec File import
  5. AS3 declaration
  6. CI/CD integration
  7. Find the Policy-ID
  8. Update an existing policy
  9. Video demonstration
 

First of all, you need a JSON WAF policy, as below :

{
    "policy": {
        "name": "policy-api-arcadia",
        "description": "Arcadia API",
        "template": {
            "name": "POLICY_TEMPLATE_API_SECURITY"
        },
        "enforcementMode": "blocking",
        "server-technologies": [
            {
                "serverTechnologyName": "MySQL"
            },
            {
                "serverTechnologyName": "Unix/Linux"
            },
            {
                "serverTechnologyName": "MongoDB"
            }
        ],
        "signature-settings": {
            "signatureStaging": false
        },
        "policy-builder": {
            "learnOnlyFromNonBotTraffic": false
        }
    }
}


1. Upload Policy in BIG-IP

There are 2 options to upload a JSON file into the BIG-IP:

1.1 Either you PUSH the file into the BIG-IP and you IMPORT IT

OR

1.2 the BIG-IP PULL the file from a repository (and the IMPORT is included) <- BEST option

1.1 PUSH JSON file into the BIG-IP

The call is below. As you can notice, it requires a 'Content-Range' header. And the value is 0-(filesize-1)/filesize. In the example below, the file size is 662 bytes. This is not easy to integrate in a CICD pipeline, so we created the PULL method instead of the PUSH (in v16.0)

curl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/file-transfer/uploads/policy-api.json' \
--header 'Content-Range: 0-661/662' \
--header 'Authorization: Basic YWRtaW46YWRtaW4=' \
--header 'Content-Type: application/json' \
--data-binary '@/C:/Users/user/Desktop/policy-api.json'

 

At this stage, the policy is still a file ​​​​​​​in the BIG-IP file system. We need to import it into Adv. WAF. To do so, the next call is required.

This call import the file "policy-api.json" uploaded previously. An CREATE the policy /Common/policy-api-arcadia

curl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \
--header 'Content-Type: application/javascript' \
--header 'Authorization: Basic YWRtaW46YWRtaW4=' \
--data-raw '{
    "filename":"policy-api.json",
    "policy":
        {
        "fullPath":"/Common/policy-api-arcadia"
        }
}'

 

1.2 PULL JSON file from a repository

Here, the JSON file is hosted somewhere (in Gitlab or Github ...). And the BIG-IP will pull it

The call is below. As you can notice, the call refers to the remote repo and the body is a JSON payload. Just change the link value with your JSON policy URL.

With one call, the policy is PULLED and IMPORTED.

curl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic YWRtaW46YWRtaW4=' \
--data-raw '{
    "fileReference": { 
        "link": "http://10.1.20.4/root/as3-waf/-/raw/master/policy-api.json"
    }
}'

 

second version of this call exists, and refer to the fullPath of the policy. This will allow you to update the policy, from a second version of the JSON file, easily. One call for the creation and the update.

As you can notice below, we add the "policy":"fullPath" directive. The value of the "fullPath" is the partition and the name of the policy set in the JSON policy file.

This method is VERY USEFUL for CI/CD integrations. 

curl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic YWRtaW46YWRtaW4=' \
--data-raw '{
    "fileReference": { 
        "link": "http://10.1.20.4/root/as3-waf/-/raw/master/policy-api.json"
    },
    "policy":
        {
            "fullPath":"/Common/policy-api-arcadia"
        }
}'


2. Check the IMPORT

Check if the IMPORT worked. To do so, run the next call.

curl --location --request GET 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \
--header 'Authorization: Basic YWRtaW46YWRtaW4=' \

 

You should see a 200 OK, with the content below (truncated in this example).
Please notice the 
"status":"COMPLETED".

{
    "kind": "tm:asm:tasks:import-policy:import-policy-taskcollectionstate",
    "selfLink": "https://localhost/mgmt/tm/asm/tasks/import-policy?ver=16.0.0",
    "totalItems": 11,
    "items": [
        {
            "isBase64": false,
            "executionStartTime": "2020-07-21T15:50:22Z",
            "status": "COMPLETED",
            "lastUpdateMicros": 1.595346627e+15,
            "getPolicyAttributesOnly": false,
...
​

From now, your policy is imported and created in the BIG-IP. You can assign it to a VS as usual (Imperative Call or AS3 Call). But in the next session, I will show you how to create a Service with AS3 including the WAF policy.


3. APPLY the policy

As you may know, a WAF policy needs to be applied after each change. This is the call.

curl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/apply-policy/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic YWRtaW46YWRtaW4=' \
--data-raw '{"policy":{"fullPath":"/Common/policy-api-arcadia"}}'


4. OpenAPI spec file IMPORT

As you know, Adv. WAF supports OpenAPI spec (2.0 and 3.0). Now, with the declarative WAF, we can import the OAS file as well. The BEST solution, is to PULL the OAS file from a repo. And in most of the customer' projects, it will be the case.

In the example below, the OAS file is hosted in SwaggerHub (Github for Swagger files). But the file could reside in a private Gitlab repo for instance.

  1. The URL of the project is : https://app.swaggerhub.com/apis/F5EMEASSA/Arcadia-OAS3/1.0.0-oas3
  2. The URL of the OAS file is : https://api.swaggerhub.com/apis/F5EMEASSA/Arcadia-OAS3/1.0.0-oas3

This swagger file (OpenAPI 3.0 Spec file) includes all the application URL and parameters. What's more, it includes the documentation (for NGINX APIm Dev Portal).


Now, it is pretty easy to create a WAF JSON Policy with API Security template, referring to the OAS file.

Below, you can notice the new section "open-api-files" with the link reference to SwaggerHub. And the new template POLICY_TEMPLATE_API_SECURITY.

Now, when I upload / import and apply the policy, Adv. WAF will download the OAS file from SwaggerHub and create the policy based on API_Security template.

{
    "policy": {
        "name": "policy-api-arcadia",
        "description": "Arcadia API",
        "template": {
            "name": "POLICY_TEMPLATE_API_SECURITY"
        },
        "enforcementMode": "blocking",
        "server-technologies": [
            {
                "serverTechnologyName": "MySQL"
            },
            {
                "serverTechnologyName": "Unix/Linux"
            },
            {
                "serverTechnologyName": "MongoDB"
            }
        ],
        "signature-settings": {
            "signatureStaging": false
        },
        "policy-builder": {
            "learnOnlyFromNonBotTraffic": false
        },
        "open-api-files": [
            {
            "link": "https://api.swaggerhub.com/apis/F5EMEASSA/Arcadia-OAS3/1.0.0-oas3"
            }
        ]
    }
}


5. AS3 declaration

Now, it is time to learn how we can do all of these steps in one call with AS3 (3.18 minimum).

The documentation is here : https://clouddocs.f5.com/products/extensions/f5-appsvcs-extension/latest/declarations/application-security.html?highlight=waf_policy#virtual-service-referencing-an-external-security-policy

 

With this AS3 declaration, we:

  1. Import the WAF policy from a external repo
  2. Import the Swagger file (if the WAF policy refers to an OAS file) from an external repo
  3. Create the service
{
    "class": "AS3",
    "action": "deploy",
    "persist": true,
    "declaration": {
        "class": "ADC",
        "schemaVersion": "3.2.0",
        "id": "Prod_API_AS3",
        "API-Prod": {
            "class": "Tenant",
            "defaultRouteDomain": 0,
            "API": {
                "class": "Application",
                "template": "generic",
                "VS_API": {
                    "class": "Service_HTTPS",
                    "remark": "Accepts HTTPS/TLS connections on port 443",
                    "virtualAddresses": ["10.1.10.27"],
                    "redirect80": false,
                    "pool": "pool_NGINX_API_AS3",
                    "policyWAF": {
                        "use": "Arcadia_WAF_API_policy"
                    },
                    "securityLogProfiles": [{
                        "bigip": "/Common/Log all requests"
                    }],
                    "profileTCP": {
                        "egress": "wan",
                        "ingress": { "use": "TCP_Profile" } },
                    "profileHTTP": { "use": "custom_http_profile" },
                    "serverTLS": { "bigip": "/Common/arcadia_client_ssl" }
                },
                "Arcadia_WAF_API_policy": {
                    "class": "WAF_Policy",
                    "url": "http://10.1.20.4/root/as3-waf-api/-/raw/master/policy-api.json",
                    "ignoreChanges": true
                },
                "pool_NGINX_API_AS3": {
                    "class": "Pool",
                    "monitors": ["http"],
                    "members": [{
                        "servicePort": 8080,
                        "serverAddresses": ["10.1.20.9"]
                    }]
                },
                "custom_http_profile": {
                    "class": "HTTP_Profile",
                    "xForwardedFor": true
                },
                "TCP_Profile": {
                    "class": "TCP_Profile",
                    "idleTimeout": 60 }
            }
        }
    }
}


6. CI/CID integration

As you can notice, it is very easy to create a service with a WAF policy pulled from an external repo. So, it is easy to integrate these calls (or the AS3 call) into a CI/CD pipeline.

Below, an Ansible playbook example. This playbook run the AS3 call above.
That's it :)

---
​
    - hosts: bigip
      connection: local
      gather_facts: false
      vars:
        my_admin: "admin"
        my_password: "admin"
        bigip: "10.1.1.12"
​
      tasks:
      - name: Deploy AS3 WebApp
        uri:
          url: "https://{{ bigip }}/mgmt/shared/appsvcs/declare"
          method: POST
          headers:
            "Content-Type": "application/json"
            "Authorization": "Basic YWRtaW46YWRtaW4="
          body: "{{ lookup('file','as3.json') }}"
          body_format: json
          validate_certs: no
          status_code: 200


7. FIND the Policy-ID

When the policy is created, a Policy-ID is assigned. By default, this ID doesn't appear anywhere. Neither in the GUI, nor in the response after the creation.

You have to calculate it or ask for it. This ID is required for several actions in a CI/CD pipeline.

7.1 Calculate the Policy-ID

We created this python script to calculate the Policy-ID. It is an hash from the Policy name (including the partition). For the previous created policy named "/Common/policy-api-arcadia", the policy ID is "Ar5wrwmFRroUYsMA6DuxlQ"

Paste this python code in a new waf-policy-id.py file, and run the command python waf-policy-id.py "/Common/policy-api-arcadia"

Outcome will be The Policy-ID for /Common/policy-api-arcadia is: Ar5wrwmFRroUYsMA6DuxlQ

#!/usr/bin/python
​
from hashlib import md5
import base64
import sys
pname = sys.argv[1]
print 'The Policy-ID for', sys.argv[1], 'is:', base64.b64encode(md5(pname.encode()).digest()).replace("=", "")


7.2 Retrieve the Policy-ID and fullPath with a REST API call

Make this call below, and you will see in the response, all the policy creations. Find yours and collect the PolicyReference directive. The Policy-ID is in the link value "link": "https://localhost/mgmt/tm/asm/policies/Ar5wrwmFRroUYsMA6DuxlQ?ver=16.0.0"

You can see as well, at the end of the definition, the "fileReference" referring to the JSON file pulled by the BIG-IP.

And please notice the "fullPath", required if you want to update your policy

curl --location --request GET 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \
--header 'Content-Range: 0-601/601' \
--header 'Authorization: Basic YWRtaW46YWRtaW4=' \
{
    "isBase64": false,
    "executionStartTime": "2020-07-22T11:23:42Z",
    "status": "COMPLETED",
    "lastUpdateMicros": 1.595417027e+15,
    "getPolicyAttributesOnly": false,
    "kind": "tm:asm:tasks:import-policy:import-policy-taskstate",
    "selfLink": "https://localhost/mgmt/tm/asm/tasks/import-policy/B45J0ySjSJ9y9fsPZ2JNvA?ver=16.0.0",
    "filename": "",
    "policyReference": {
        "link": "https://localhost/mgmt/tm/asm/policies/Ar5wrwmFRroUYsMA6DuxlQ?ver=16.0.0",
        "fullPath": "/Common/policy-api-arcadia"
    },
    "endTime": "2020-07-22T11:23:47Z",
    "startTime": "2020-07-22T11:23:42Z",
    "id": "B45J0ySjSJ9y9fsPZ2JNvA",
    "retainInheritanceSettings": false,
    "result": {
        "policyReference": {
            "link": "https://localhost/mgmt/tm/asm/policies/Ar5wrwmFRroUYsMA6DuxlQ?ver=16.0.0",
            "fullPath": "/Common/policy-api-arcadia"
        },
        "message": "The operation was completed successfully. The security policy name is '/Common/policy-api-arcadia'. "
    },
    "fileReference": {
        "link": "http://10.1.20.4/root/as3-waf/-/raw/master/policy-api.json"
    }
},


8 UPDATE an existing policy

It is pretty easy to update the WAF policy from a new JSON file version. To do so, collect from the previous call 7.2 Retrieve the Policy-ID and fullPath with a REST API call the "Policy" and "fullPath" directive. This is the path of the Policy in the BIG-IP.

Then run the call below, same as 1.2 PULL JSON file from a repository, ​​​​​​​but add the Policy and fullPath directives

Don't forget to APPLY this new version of the policy 3. APPLY the policy

curl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic YWRtaW46YWRtaW4=' \
--data-raw '{
    "fileReference": { 
        "link": "http://10.1.20.4/root/as3-waf/-/raw/master/policy-api.json"
    },
    "policy":
        {
            "fullPath":"/Common/policy-api-arcadia"
        }
}'


TIP : this call, above, can be used in place of the FIRST call when we created the policy "1.2 PULL JSON file from a repository". But be careful, the fullPath is the name set in the JSON policy file. 

The 2 values need to match:

  • "name": "policy-api-arcadia" in the JSON Policy file pulled by the BIG-IP
  • "policy":"fullPath" in the POST call


9 Video demonstration

In order to help you to understand how it looks with the BIG-IP, I created this video covering 4 topics explained in this article :

  • The JSON WAF policy
  • Pull the policy from a remote repository
  • Update the WAF policy with a new version of the declarative JSON file
  • Deploy a full service with AS3 and Declarative WAF policy

At the end of this video, you will be able to adapt the REST Declarative API calls to your infrastructure, in order to deploy protected services with your CI/CD pipelines.

Direct link to the video on DevCentral YouTube channel : https://youtu.be/EDvVwlwEFRw

 

Published Jul 30, 2020
Version 1.0

2 Comments

  • Thanks! Is there a way to push JSON file with F5 Ansible module like "bigip_asm_policy_import". I know that probably the URI Ansbile module will do the trick but I am looking for a native way to push the ASM policy and then use the new " bigip_as3_deploy" module (the new way to push AS3 Declarations and I made an article about it https://community.f5.com/t5/codeshare/comparison-between-deploying-as3-or-fast-iapp-declarations-with/ta-p/309613 ) to deploy the AS3 declaration that will reference the pushed policy.

     

    I tried to replace "url": "http://10.1.20.4/root/as3-waf-api/-/raw/master/policy-api.json" with the ASM policy but if I do not want to host the ASM polcy on git then I see the option I mentioned as pushing the ASM policy to the F5 and then referencing it in the AS3.

     

    Edit:

     

    I think with the Ansible URI module I can script the file upload commands (the bigip_asm_policy_import seems to have issues so the URI module seems the better option for file upload and then making the asm policy from the file upload) as have for other stuff but still a native Ansible module that can also auto calculate the "Content-Range" header for file upload will really be helpfull but as you mentioned using the "Pull" could be an option.

     

    Managed to make it work with the URI module, just for some reason the F5 thinks the files are the wrong falue and this seems like a bug.

     

    "message": "Chunk byte count 402 in Content-Range header different from received buffer length 394",

     

    └─# stat -c%s asm_policy.json
    665

     

     

    tasks:


    - name: PUSH FILE WAF

    uri:

    url: "https://{{ ansible_host }}/mgmt/tm/asm/file-transfer/uploads/asm_policy.json"

    method: POST

    body: "{{ lookup('template','asm_policy.json', split_lines=False) }}"

    status_code: 200

    timeout: 300

    body_format: json

    force_basic_auth: yes

    user: "{{ ansible_user }}"

    password: "{{ ansible_httpapi_password }}"

    validate_certs: no

    headers:
    Content-Range: 0-393/394
    Content-Type: application/octet-stream

     

    - name: PUSH WAF

    uri:

    url: "https://{{ ansible_host }}/mgmt/tm/asm/tasks/import-policy"

    method: POST

    body: "{{ lookup('template','asm_config.json', split_lines=False) }}"

    status_code: 201

    timeout: 300

    body_format: json

    force_basic_auth: yes

    user: "{{ ansible_user }}"

    password: "{{ ansible_httpapi_password }}"

    validate_certs: no

    headers:
    Content-Type: application/javascript

  • Using the uri option in the declaration it is unclear how the policy arrives at the BIG-IP.

     "My_ASM_Policy": {
            "class": "WAF_Policy",
            "url": "https://example.com/asm-policy.xml",
            "ignoreChanges": true

    How does the data from that url get uploaded/downloaded to the big-ip.

    1. PUSH: Does the AS3 software include the json data from that url as part of it's declaration?
    2. PULL: Does the BIG-IP download the json from that url?
"}},"componentScriptGroups({\"componentId\":\"custom.widget.Beta_MetaNav\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"component({\"componentId\":\"custom.widget.Beta_Footer\"})":{"__typename":"Component","render({\"context\":{\"component\":{\"entities\":[],\"props\":{}},\"page\":{\"entities\":[\"board:TechnicalArticles\",\"message:289251\"],\"name\":\"TkbMessagePage\",\"props\":{},\"url\":\"https://community.f5.com/kb/technicalarticles/advanced-waf-v16-0---declarative-api/289251\"}}})":{"__typename":"ComponentRenderResult","html":"
 
 
 
 
 

\"F5 ©2024 F5, Inc. All rights reserved.
Trademarks Policies Privacy California Privacy Do Not Sell My Personal Information
"}},"componentScriptGroups({\"componentId\":\"custom.widget.Beta_Footer\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"component({\"componentId\":\"custom.widget.Tag_Manager_Helper\"})":{"__typename":"Component","render({\"context\":{\"component\":{\"entities\":[],\"props\":{}},\"page\":{\"entities\":[\"board:TechnicalArticles\",\"message:289251\"],\"name\":\"TkbMessagePage\",\"props\":{},\"url\":\"https://community.f5.com/kb/technicalarticles/advanced-waf-v16-0---declarative-api/289251\"}}})":{"__typename":"ComponentRenderResult","html":" "}},"componentScriptGroups({\"componentId\":\"custom.widget.Tag_Manager_Helper\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"component({\"componentId\":\"custom.widget.Consent_Blackbar\"})":{"__typename":"Component","render({\"context\":{\"component\":{\"entities\":[],\"props\":{}},\"page\":{\"entities\":[\"board:TechnicalArticles\",\"message:289251\"],\"name\":\"TkbMessagePage\",\"props\":{},\"url\":\"https://community.f5.com/kb/technicalarticles/advanced-waf-v16-0---declarative-api/289251\"}}})":{"__typename":"ComponentRenderResult","html":"
"}},"componentScriptGroups({\"componentId\":\"custom.widget.Consent_Blackbar\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/QueryHandler\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"components/community/NavbarDropdownToggle\"]})":[{"__ref":"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageView/MessageViewStandard\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageView/MessageViewStandard-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/ThreadedReplyList\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/ThreadedReplyList-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageReplyCallToAction\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageReplyCallToAction-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageSubject\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageSubject-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageBody\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageBody-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageCustomFields\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageCustomFields-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageRevision\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageRevision-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageReplyButton\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageReplyButton-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageAuthorBio\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"components/guides/GuideBottomNavigation\"]})":[{"__ref":"CachedAsset:text:en_US-components/guides/GuideBottomNavigation-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserLink\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserLink-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserRank\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserRank-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTime\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTime-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"components/customComponent/CustomComponent\"]})":[{"__ref":"CachedAsset:text:en_US-components/customComponent/CustomComponent-1740415735000"}],"message({\"id\":\"message:309802\"})":{"__ref":"TkbReplyMessage:message:309802"},"message({\"id\":\"message:335040\"})":{"__ref":"TkbReplyMessage:message:335040"},"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/ranks/UserRankLabel\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserRegistrationDate\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserRegistrationDate-1740415735000"}],"cachedText({\"lastModified\":\"1740415735000\",\"locale\":\"en-US\",\"namespaces\":[\"components/tags/TagView/TagViewChip\"]})":[{"__ref":"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1740415735000"}]},"CachedAsset:pages-1741989810203":{"__typename":"CachedAsset","id":"pages-1741989810203","value":[{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"HowDoI.GetInvolved.MvpProgram","type":"COMMUNITY","urlPath":"/c/how-do-i/get-involved/mvp-program","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"BlogViewAllPostsPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId/all-posts/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"CasePortalPage","type":"CASE_PORTAL","urlPath":"/caseportal","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"CreateGroupHubPage","type":"GROUP_HUB","urlPath":"/groups/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"CaseViewPage","type":"CASE_DETAILS","urlPath":"/case/:caseId/:caseNumber","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"InboxPage","type":"COMMUNITY","urlPath":"/inbox","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"HowDoI.GetInvolved.AdvocacyProgram","type":"COMMUNITY","urlPath":"/c/how-do-i/get-involved/advocacy-program","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"HowDoI.GetHelp.NonCustomer","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/non-customer","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"HelpFAQPage","type":"COMMUNITY","urlPath":"/help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"HowDoI.GetHelp.F5Customer","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/f5-customer","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"IdeaMessagePage","type":"IDEA_POST","urlPath":"/idea/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"IdeaViewAllIdeasPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/all-ideas/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"LoginPage","type":"USER","urlPath":"/signin","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"BlogPostPage","type":"BLOG","urlPath":"/category/:categoryId/blogs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"HowDoI.GetInvolved","type":"COMMUNITY","urlPath":"/c/how-do-i/get-involved","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"HowDoI.Learn","type":"COMMUNITY","urlPath":"/c/how-do-i/learn","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1739501733000,"localOverride":null,"page":{"id":"Test","type":"CUSTOM","urlPath":"/custom-test-2","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"ThemeEditorPage","type":"COMMUNITY","urlPath":"/designer/themes","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"TkbViewAllArticlesPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId/all-articles/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"OccasionEditPage","type":"EVENT","urlPath":"/event/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"OAuthAuthorizationAllowPage","type":"USER","urlPath":"/auth/authorize/allow","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"PageEditorPage","type":"COMMUNITY","urlPath":"/designer/pages","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"PostPage","type":"COMMUNITY","urlPath":"/category/:categoryId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"ForumBoardPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"TkbBoardPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"EventPostPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"UserBadgesPage","type":"COMMUNITY","urlPath":"/users/:login/:userId/badges","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"GroupHubMembershipAction","type":"GROUP_HUB","urlPath":"/membership/join/:nodeId/:membershipType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"MaintenancePage","type":"COMMUNITY","urlPath":"/maintenance","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"IdeaReplyPage","type":"IDEA_REPLY","urlPath":"/idea/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"UserSettingsPage","type":"USER","urlPath":"/mysettings/:userSettingsTab","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"GroupHubsPage","type":"GROUP_HUB","urlPath":"/groups","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"ForumPostPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"OccasionRsvpActionPage","type":"OCCASION","urlPath":"/event/:boardId/:messageSubject/:messageId/rsvp/:responseType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"VerifyUserEmailPage","type":"USER","urlPath":"/verifyemail/:userId/:verifyEmailToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"AllOccasionsPage","type":"OCCASION","urlPath":"/category/:categoryId/events/:boardId/all-events/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"EventBoardPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"TkbReplyPage","type":"TKB_REPLY","urlPath":"/kb/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"IdeaBoardPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"CommunityGuideLinesPage","type":"COMMUNITY","urlPath":"/communityguidelines","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"CaseCreatePage","type":"SALESFORCE_CASE_CREATION","urlPath":"/caseportal/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"TkbEditPage","type":"TKB","urlPath":"/kb/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"ForgotPasswordPage","type":"USER","urlPath":"/forgotpassword","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"IdeaEditPage","type":"IDEA","urlPath":"/idea/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"TagPage","type":"COMMUNITY","urlPath":"/tag/:tagName","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"BlogBoardPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"OccasionMessagePage","type":"OCCASION_TOPIC","urlPath":"/event/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"ManageContentPage","type":"COMMUNITY","urlPath":"/managecontent","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"ClosedMembershipNodeNonMembersPage","type":"GROUP_HUB","urlPath":"/closedgroup/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"HowDoI.GetHelp.Community","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/community","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"CommunityPage","type":"COMMUNITY","urlPath":"/","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"HowDoI.GetInvolved.ContributeCode","type":"COMMUNITY","urlPath":"/c/how-do-i/get-involved/contribute-code","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"ForumMessagePage","type":"FORUM_TOPIC","urlPath":"/discussions/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"IdeaPostPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"BlogMessagePage","type":"BLOG_ARTICLE","urlPath":"/blog/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"RegistrationPage","type":"USER","urlPath":"/register","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"EditGroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"ForumEditPage","type":"FORUM","urlPath":"/discussions/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"ResetPasswordPage","type":"USER","urlPath":"/resetpassword/:userId/:resetPasswordToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"TkbMessagePage","type":"TKB_ARTICLE","urlPath":"/kb/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"HowDoI.Learn.AboutIrules","type":"COMMUNITY","urlPath":"/c/how-do-i/learn/about-irules","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"BlogEditPage","type":"BLOG","urlPath":"/blog/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"HowDoI.GetHelp.F5Support","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/f5-support","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"ManageUsersPage","type":"USER","urlPath":"/users/manage/:tab?/:manageUsersTab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"ForumReplyPage","type":"FORUM_REPLY","urlPath":"/discussions/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"PrivacyPolicyPage","type":"COMMUNITY","urlPath":"/privacypolicy","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"NotificationPage","type":"COMMUNITY","urlPath":"/notifications","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"UserPage","type":"USER","urlPath":"/users/:login/:userId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"HealthCheckPage","type":"COMMUNITY","urlPath":"/health","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"OccasionReplyPage","type":"OCCASION_REPLY","urlPath":"/event/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"ManageMembersPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/manage/:tab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"SearchResultsPage","type":"COMMUNITY","urlPath":"/search","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"BlogReplyPage","type":"BLOG_REPLY","urlPath":"/blog/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"GroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"TermsOfServicePage","type":"COMMUNITY","urlPath":"/termsofservice","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"HowDoI.GetHelp","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"HowDoI.GetHelp.SecurityIncident","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/security-incident","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"CategoryPage","type":"CATEGORY","urlPath":"/category/:categoryId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"ForumViewAllTopicsPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/all-topics/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"TkbPostPage","type":"TKB","urlPath":"/category/:categoryId/kbs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"GroupHubPostPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1741989810203,"localOverride":null,"page":{"id":"HowDoI","type":"COMMUNITY","urlPath":"/c/how-do-i","__typename":"PageDescriptor"},"__typename":"PageResource"}],"localOverride":false},"CachedAsset:text:en_US-components/context/AppContext/AppContextProvider-0":{"__typename":"CachedAsset","id":"text:en_US-components/context/AppContext/AppContextProvider-0","value":{"noCommunity":"Cannot find community","noUser":"Cannot find current user","noNode":"Cannot find node with id {nodeId}","noMessage":"Cannot find message with id {messageId}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-0":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-0","value":{"title":"Loading..."},"localOverride":false},"User:user:-1":{"__typename":"User","id":"user:-1","uid":-1,"login":"Former Member","email":"","avatar":null,"rank":null,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":"ANONYMOUS","registrationTime":null,"confirmEmailStatus":false,"registrationAccessLevel":"VIEW","ssoRegistrationFields":[]},"ssoId":null,"profileSettings":{"__typename":"ProfileSettings","dateDisplayStyle":{"__typename":"InheritableStringSettingWithPossibleValues","key":"layout.friendly_dates_enabled","value":"false","localValue":"true","possibleValues":["true","false"]},"dateDisplayFormat":{"__typename":"InheritableStringSetting","key":"layout.format_pattern_date","value":"dd-MMM-yyyy","localValue":"MM-dd-yyyy"},"language":{"__typename":"InheritableStringSettingWithPossibleValues","key":"profile.language","value":"en-US","localValue":null,"possibleValues":["en-US"]}},"deleted":false},"Theme:customTheme1":{"__typename":"Theme","id":"customTheme1"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bi0zNC0xM2k0MzE3N0Q2NjFBRDg5NDAy\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bi0zNC0xM2k0MzE3N0Q2NjFBRDg5NDAy","mimeType":"image/png"},"Category:category:Articles":{"__typename":"Category","id":"category:Articles","entityType":"CATEGORY","displayId":"Articles","nodeType":"category","depth":1,"title":"Articles","shortTitle":"Articles","parent":{"__ref":"Category:category:top"},"categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:top":{"__typename":"Category","id":"category:top","displayId":"top","nodeType":"category","depth":0,"title":"Top","entityType":"CATEGORY","shortTitle":"Top"},"Tkb:board:TechnicalArticles":{"__typename":"Tkb","id":"board:TechnicalArticles","entityType":"TKB","displayId":"TechnicalArticles","nodeType":"board","depth":2,"conversationStyle":"TKB","title":"Technical Articles","description":"F5 SMEs share good practice.","avatar":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bi0zNC0xM2k0MzE3N0Q2NjFBRDg5NDAy\"}"},"profileSettings":{"__typename":"ProfileSettings","language":null},"parent":{"__ref":"Category:category:Articles"},"ancestors":{"__typename":"CoreNodeConnection","edges":[{"__typename":"CoreNodeEdge","node":{"__ref":"Community:community:zihoc95639"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:Articles"}}]},"userContext":{"__typename":"NodeUserContext","canAddAttachments":false,"canUpdateNode":false,"canPostMessages":false,"isSubscribed":false},"boardPolicies":{"__typename":"BoardPolicies","canPublishArticleOnCreate":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","args":[]}},"canReadNode":{"__typename":"PolicyResult","failureReason":null}},"shortTitle":"Technical Articles","isManualSortOrderAvailable":false,"tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"repliesProperties":{"__typename":"RepliesProperties","sortOrder":"PUBLISH_TIME","repliesFormat":"threaded"},"eventPath":"category:Articles/community:zihoc95639board:TechnicalArticles/","tagProperties":{"__typename":"TagNodeProperties","tagsEnabled":{"__typename":"PolicyResult","failureReason":null}},"requireTags":true,"tagType":"FREEFORM_AND_PRESET"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/cmstMjgtQ3U0RXo2\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/cmstMjgtQ3U0RXo2","height":0,"width":0,"mimeType":"image/svg+xml"},"Rank:rank:28":{"__typename":"Rank","id":"rank:28","position":5,"name":"Employee","color":"C20025","icon":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/cmstMjgtQ3U0RXo2\"}"},"rankStyle":"OUTLINE"},"User:user:193857":{"__typename":"User","id":"user:193857","uid":193857,"login":"Matt_Dierick","deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/images/dS0xOTM4NTctMTk5ODBpQjM4NEUzMzg1RkUyOEZBMw"},"rank":{"__ref":"Rank:rank:28"},"email":"","messagesCount":366,"biography":null,"topicsCount":52,"kudosReceivedCount":76,"kudosGivenCount":37,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2012-11-20T00:00:00.000-08:00","confirmEmailStatus":null},"followersCount":null,"solutionsCount":1},"TkbTopicMessage:message:289251":{"__typename":"TkbTopicMessage","uid":289251,"subject":"Advanced WAF v16.0 - Declarative API","id":"message:289251","revisionNum":1,"repliesCount":2,"author":{"__ref":"User:user:193857"},"depth":0,"hasGivenKudo":false,"helpful":null,"board":{"__ref":"Tkb:board:TechnicalArticles"},"conversation":{"__ref":"Conversation:conversation:289251"},"messagePolicies":{"__typename":"MessagePolicies","canPublishArticleOnEdit":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","args":[]}},"canModerateSpamMessage":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","key":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","args":[]}}},"contentWorkflow":{"__typename":"ContentWorkflow","state":"PUBLISH","scheduledPublishTime":null,"scheduledTimezone":null,"userContext":{"__typename":"MessageWorkflowContext","canSubmitForReview":null,"canEdit":false,"canRecall":null,"canSubmitForPublication":null,"canReturnToAuthor":null,"canPublish":null,"canReturnToReview":null,"canSchedule":false},"shortScheduledTimezone":null},"readOnly":false,"editFrozen":false,"moderationData":{"__ref":"ModerationData:moderation_data:289251"},"teaser":"","body":"

Since v15.1 (in draft), F5® BIG-IP® Advanced WAF can import Declarative WAF policy in JSON format.

\n\n

The F5® BIG-IP® Advanced Web Application Firewall (Advanced WAF) security policies can be deployed using the declarative JSON format, facilitating easy integration into a CI/CD pipeline. The declarative policies are extracted from a source control system, for example Git, and imported into the BIG-IP.

\n\n

Using the provided declarative policy templates, you can modify the necessary parameters, save the JSON file, and import the updated security policy into your BIG-IP devices. The declarative policy copies the content of the template and adds the adjustments and modifications on to it. The templates therefore allow you to concentrate only on the specific settings that need to be adapted for the specific application that the policy protects.

\n\n

This Declarative WAF JSON policy is similar to NGINX App Protect policy. You can find more information on the Declarative Policy here :

\n\n\n\n

Audience

\n\n

This guide is written for IT professionals who need to automate their WAF policy and are familiar with Advanced WAF configuration. These IT professionals can fill a variety of roles:

\n\n\n\n

This article covers how to PUSH/PULL a declarative WAF policy in Advanced WAF:

\n\n\n\n


Table of contents

\n\n
  1. Upload Policy in BIG-IP
  2. Check the import
  3. Apply the policy
  4. OpenAPI Spec File import
  5. AS3 declaration
  6. CI/CD integration
  7. Find the Policy-ID
  8. Update an existing policy
  9. Video demonstration
\n \n\n

First of all, you need a JSON WAF policy, as below :

\n\n
\n{\n    \"policy\": {\n        \"name\": \"policy-api-arcadia\",\n        \"description\": \"Arcadia API\",\n        \"template\": {\n            \"name\": \"POLICY_TEMPLATE_API_SECURITY\"\n        },\n        \"enforcementMode\": \"blocking\",\n        \"server-technologies\": [\n            {\n                \"serverTechnologyName\": \"MySQL\"\n            },\n            {\n                \"serverTechnologyName\": \"Unix/Linux\"\n            },\n            {\n                \"serverTechnologyName\": \"MongoDB\"\n            }\n        ],\n        \"signature-settings\": {\n            \"signatureStaging\": false\n        },\n        \"policy-builder\": {\n            \"learnOnlyFromNonBotTraffic\": false\n        }\n    }\n}\n
\n\n


1. Upload Policy in BIG-IP

\n\n

There are 2 options to upload a JSON file into the BIG-IP:

\n\n

1.1 Either you PUSH the file into the BIG-IP and you IMPORT IT

\n\n

OR

\n\n

1.2 the BIG-IP PULL the file from a repository (and the IMPORT is included) <- BEST option

\n\n

1.1 PUSH JSON file into the BIG-IP

\n\n

The call is below. As you can notice, it requires a 'Content-Range' header. And the value is 0-(filesize-1)/filesize. In the example below, the file size is 662 bytes. This is not easy to integrate in a CICD pipeline, so we created the PULL method instead of the PUSH (in v16.0)

\n\n
\ncurl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/file-transfer/uploads/policy-api.json' \\\n--header 'Content-Range: 0-661/662' \\\n--header 'Authorization: Basic YWRtaW46YWRtaW4=' \\\n--header 'Content-Type: application/json' \\\n--data-binary '@/C:/Users/user/Desktop/policy-api.json'\n
\n\n

 

\n\n

At this stage, the policy is still a file ​​​​​​​in the BIG-IP file system. We need to import it into Adv. WAF. To do so, the next call is required.

\n\n

This call import the file \"policy-api.json\" uploaded previously. An CREATE the policy /Common/policy-api-arcadia

\n\n
\ncurl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \\\n--header 'Content-Type: application/javascript' \\\n--header 'Authorization: Basic YWRtaW46YWRtaW4=' \\\n--data-raw '{\n    \"filename\":\"policy-api.json\",\n    \"policy\":\n        {\n        \"fullPath\":\"/Common/policy-api-arcadia\"\n        }\n}'\n
\n\n

 

\n\n

1.2 PULL JSON file from a repository

\n\n

Here, the JSON file is hosted somewhere (in Gitlab or Github ...). And the BIG-IP will pull it

\n\n

The call is below. As you can notice, the call refers to the remote repo and the body is a JSON payload. Just change the link value with your JSON policy URL.

\n\n

With one call, the policy is PULLED and IMPORTED.

\n\n
\ncurl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \\\n--header 'Content-Type: application/json' \\\n--header 'Authorization: Basic YWRtaW46YWRtaW4=' \\\n--data-raw '{\n    \"fileReference\": { \n        \"link\": \"http://10.1.20.4/root/as3-waf/-/raw/master/policy-api.json\"\n    }\n}'\n
\n\n

 

\n\n

second version of this call exists, and refer to the fullPath of the policy. This will allow you to update the policy, from a second version of the JSON file, easily. One call for the creation and the update.

\n\n

As you can notice below, we add the \"policy\":\"fullPath\" directive. The value of the \"fullPath\" is the partition and the name of the policy set in the JSON policy file.

\n\n

This method is VERY USEFUL for CI/CD integrations. 

\n\n
\ncurl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \\\n--header 'Content-Type: application/json' \\\n--header 'Authorization: Basic YWRtaW46YWRtaW4=' \\\n--data-raw '{\n    \"fileReference\": { \n        \"link\": \"http://10.1.20.4/root/as3-waf/-/raw/master/policy-api.json\"\n    },\n    \"policy\":\n        {\n            \"fullPath\":\"/Common/policy-api-arcadia\"\n        }\n}'\n
\n\n


2. Check the IMPORT

\n\n

Check if the IMPORT worked. To do so, run the next call.

\n\n
\ncurl --location --request GET 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \\\n--header 'Authorization: Basic YWRtaW46YWRtaW4=' \\\n
\n\n

 

\n\n

You should see a 200 OK, with the content below (truncated in this example).
Please notice the 
\"status\":\"COMPLETED\".

\n\n
\n{\n    \"kind\": \"tm:asm:tasks:import-policy:import-policy-taskcollectionstate\",\n    \"selfLink\": \"https://localhost/mgmt/tm/asm/tasks/import-policy?ver=16.0.0\",\n    \"totalItems\": 11,\n    \"items\": [\n        {\n            \"isBase64\": false,\n            \"executionStartTime\": \"2020-07-21T15:50:22Z\",\n            \"status\": \"COMPLETED\",\n            \"lastUpdateMicros\": 1.595346627e+15,\n            \"getPolicyAttributesOnly\": false,\n...\n​
\n\n

From now, your policy is imported and created in the BIG-IP. You can assign it to a VS as usual (Imperative Call or AS3 Call). But in the next session, I will show you how to create a Service with AS3 including the WAF policy.

\n\n


3. APPLY the policy

\n\n

As you may know, a WAF policy needs to be applied after each change. This is the call.

\n\n
\ncurl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/apply-policy/' \\\n--header 'Content-Type: application/json' \\\n--header 'Authorization: Basic YWRtaW46YWRtaW4=' \\\n--data-raw '{\"policy\":{\"fullPath\":\"/Common/policy-api-arcadia\"}}'\n
\n\n


4. OpenAPI spec file IMPORT

\n\n

As you know, Adv. WAF supports OpenAPI spec (2.0 and 3.0). Now, with the declarative WAF, we can import the OAS file as well. The BEST solution, is to PULL the OAS file from a repo. And in most of the customer' projects, it will be the case.

\n\n

In the example below, the OAS file is hosted in SwaggerHub (Github for Swagger files). But the file could reside in a private Gitlab repo for instance.

\n\n
  1. The URL of the project is : https://app.swaggerhub.com/apis/F5EMEASSA/Arcadia-OAS3/1.0.0-oas3
  2. The URL of the OAS file is : https://api.swaggerhub.com/apis/F5EMEASSA/Arcadia-OAS3/1.0.0-oas3
\n\n

This swagger file (OpenAPI 3.0 Spec file) includes all the application URL and parameters. What's more, it includes the documentation (for NGINX APIm Dev Portal).

\n\n


Now, it is pretty easy to create a WAF JSON Policy with API Security template, referring to the OAS file.

\n\n

Below, you can notice the new section \"open-api-files\" with the link reference to SwaggerHub. And the new template POLICY_TEMPLATE_API_SECURITY.

\n\n

Now, when I upload / import and apply the policy, Adv. WAF will download the OAS file from SwaggerHub and create the policy based on API_Security template.

\n\n
\n{\n    \"policy\": {\n        \"name\": \"policy-api-arcadia\",\n        \"description\": \"Arcadia API\",\n        \"template\": {\n            \"name\": \"POLICY_TEMPLATE_API_SECURITY\"\n        },\n        \"enforcementMode\": \"blocking\",\n        \"server-technologies\": [\n            {\n                \"serverTechnologyName\": \"MySQL\"\n            },\n            {\n                \"serverTechnologyName\": \"Unix/Linux\"\n            },\n            {\n                \"serverTechnologyName\": \"MongoDB\"\n            }\n        ],\n        \"signature-settings\": {\n            \"signatureStaging\": false\n        },\n        \"policy-builder\": {\n            \"learnOnlyFromNonBotTraffic\": false\n        },\n        \"open-api-files\": [\n            {\n            \"link\": \"https://api.swaggerhub.com/apis/F5EMEASSA/Arcadia-OAS3/1.0.0-oas3\"\n            }\n        ]\n    }\n}\n
\n\n


5. AS3 declaration

\n\n

Now, it is time to learn how we can do all of these steps in one call with AS3 (3.18 minimum).

\n\n

The documentation is here : https://clouddocs.f5.com/products/extensions/f5-appsvcs-extension/latest/declarations/application-security.html?highlight=waf_policy#virtual-service-referencing-an-external-security-policy

\n\n

 

\n\n

With this AS3 declaration, we:

\n\n
  1. Import the WAF policy from a external repo
  2. Import the Swagger file (if the WAF policy refers to an OAS file) from an external repo
  3. Create the service
\n\n
\n{\n    \"class\": \"AS3\",\n    \"action\": \"deploy\",\n    \"persist\": true,\n    \"declaration\": {\n        \"class\": \"ADC\",\n        \"schemaVersion\": \"3.2.0\",\n        \"id\": \"Prod_API_AS3\",\n        \"API-Prod\": {\n            \"class\": \"Tenant\",\n            \"defaultRouteDomain\": 0,\n            \"API\": {\n                \"class\": \"Application\",\n                \"template\": \"generic\",\n                \"VS_API\": {\n                    \"class\": \"Service_HTTPS\",\n                    \"remark\": \"Accepts HTTPS/TLS connections on port 443\",\n                    \"virtualAddresses\": [\"10.1.10.27\"],\n                    \"redirect80\": false,\n                    \"pool\": \"pool_NGINX_API_AS3\",\n                    \"policyWAF\": {\n                        \"use\": \"Arcadia_WAF_API_policy\"\n                    },\n                    \"securityLogProfiles\": [{\n                        \"bigip\": \"/Common/Log all requests\"\n                    }],\n                    \"profileTCP\": {\n                        \"egress\": \"wan\",\n                        \"ingress\": { \"use\": \"TCP_Profile\" } },\n                    \"profileHTTP\": { \"use\": \"custom_http_profile\" },\n                    \"serverTLS\": { \"bigip\": \"/Common/arcadia_client_ssl\" }\n                },\n                \"Arcadia_WAF_API_policy\": {\n                    \"class\": \"WAF_Policy\",\n                    \"url\": \"http://10.1.20.4/root/as3-waf-api/-/raw/master/policy-api.json\",\n                    \"ignoreChanges\": true\n                },\n                \"pool_NGINX_API_AS3\": {\n                    \"class\": \"Pool\",\n                    \"monitors\": [\"http\"],\n                    \"members\": [{\n                        \"servicePort\": 8080,\n                        \"serverAddresses\": [\"10.1.20.9\"]\n                    }]\n                },\n                \"custom_http_profile\": {\n                    \"class\": \"HTTP_Profile\",\n                    \"xForwardedFor\": true\n                },\n                \"TCP_Profile\": {\n                    \"class\": \"TCP_Profile\",\n                    \"idleTimeout\": 60 }\n            }\n        }\n    }\n}\n
\n\n


6. CI/CID integration

\n\n

As you can notice, it is very easy to create a service with a WAF policy pulled from an external repo. So, it is easy to integrate these calls (or the AS3 call) into a CI/CD pipeline.

\n\n

Below, an Ansible playbook example. This playbook run the AS3 call above.
That's it :)

\n\n
\n---\n​\n    - hosts: bigip\n      connection: local\n      gather_facts: false\n      vars:\n        my_admin: \"admin\"\n        my_password: \"admin\"\n        bigip: \"10.1.1.12\"\n​\n      tasks:\n      - name: Deploy AS3 WebApp\n        uri:\n          url: \"https://{{ bigip }}/mgmt/shared/appsvcs/declare\"\n          method: POST\n          headers:\n            \"Content-Type\": \"application/json\"\n            \"Authorization\": \"Basic YWRtaW46YWRtaW4=\"\n          body: \"{{ lookup('file','as3.json') }}\"\n          body_format: json\n          validate_certs: no\n          status_code: 200\n
\n\n


7. FIND the Policy-ID

\n\n

When the policy is created, a Policy-ID is assigned. By default, this ID doesn't appear anywhere. Neither in the GUI, nor in the response after the creation.

\n\n

You have to calculate it or ask for it. This ID is required for several actions in a CI/CD pipeline.

\n\n

7.1 Calculate the Policy-ID

\n\n

We created this python script to calculate the Policy-ID. It is an hash from the Policy name (including the partition). For the previous created policy named \"/Common/policy-api-arcadia\", the policy ID is \"Ar5wrwmFRroUYsMA6DuxlQ\"

\n\n

Paste this python code in a new waf-policy-id.py file, and run the command python waf-policy-id.py \"/Common/policy-api-arcadia\"

\n\n

Outcome will be The Policy-ID for /Common/policy-api-arcadia is: Ar5wrwmFRroUYsMA6DuxlQ

\n\n
\n#!/usr/bin/python\n​\nfrom hashlib import md5\nimport base64\nimport sys\npname = sys.argv[1]\nprint 'The Policy-ID for', sys.argv[1], 'is:', base64.b64encode(md5(pname.encode()).digest()).replace(\"=\", \"\")\n
\n\n


7.2 Retrieve the Policy-ID and fullPath with a REST API call

\n\n

Make this call below, and you will see in the response, all the policy creations. Find yours and collect the PolicyReference directive. The Policy-ID is in the link value \"link\": \"https://localhost/mgmt/tm/asm/policies/Ar5wrwmFRroUYsMA6DuxlQ?ver=16.0.0\"

\n\n

You can see as well, at the end of the definition, the \"fileReference\" referring to the JSON file pulled by the BIG-IP.

\n\n

And please notice the \"fullPath\", required if you want to update your policy

\n\n
\ncurl --location --request GET 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \\\n--header 'Content-Range: 0-601/601' \\\n--header 'Authorization: Basic YWRtaW46YWRtaW4=' \\\n
\n\n
\n{\n    \"isBase64\": false,\n    \"executionStartTime\": \"2020-07-22T11:23:42Z\",\n    \"status\": \"COMPLETED\",\n    \"lastUpdateMicros\": 1.595417027e+15,\n    \"getPolicyAttributesOnly\": false,\n    \"kind\": \"tm:asm:tasks:import-policy:import-policy-taskstate\",\n    \"selfLink\": \"https://localhost/mgmt/tm/asm/tasks/import-policy/B45J0ySjSJ9y9fsPZ2JNvA?ver=16.0.0\",\n    \"filename\": \"\",\n    \"policyReference\": {\n        \"link\": \"https://localhost/mgmt/tm/asm/policies/Ar5wrwmFRroUYsMA6DuxlQ?ver=16.0.0\",\n        \"fullPath\": \"/Common/policy-api-arcadia\"\n    },\n    \"endTime\": \"2020-07-22T11:23:47Z\",\n    \"startTime\": \"2020-07-22T11:23:42Z\",\n    \"id\": \"B45J0ySjSJ9y9fsPZ2JNvA\",\n    \"retainInheritanceSettings\": false,\n    \"result\": {\n        \"policyReference\": {\n            \"link\": \"https://localhost/mgmt/tm/asm/policies/Ar5wrwmFRroUYsMA6DuxlQ?ver=16.0.0\",\n            \"fullPath\": \"/Common/policy-api-arcadia\"\n        },\n        \"message\": \"The operation was completed successfully. The security policy name is '/Common/policy-api-arcadia'. \"\n    },\n    \"fileReference\": {\n        \"link\": \"http://10.1.20.4/root/as3-waf/-/raw/master/policy-api.json\"\n    }\n},\n
\n\n


8 UPDATE an existing policy

\n\n

It is pretty easy to update the WAF policy from a new JSON file version. To do so, collect from the previous call 7.2 Retrieve the Policy-ID and fullPath with a REST API call the \"Policy\" and \"fullPath\" directive. This is the path of the Policy in the BIG-IP.

\n\n

Then run the call below, same as 1.2 PULL JSON file from a repository, ​​​​​​​but add the Policy and fullPath directives

\n\n

Don't forget to APPLY this new version of the policy 3. APPLY the policy

\n\n
\ncurl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \\\n--header 'Content-Type: application/json' \\\n--header 'Authorization: Basic YWRtaW46YWRtaW4=' \\\n--data-raw '{\n    \"fileReference\": { \n        \"link\": \"http://10.1.20.4/root/as3-waf/-/raw/master/policy-api.json\"\n    },\n    \"policy\":\n        {\n            \"fullPath\":\"/Common/policy-api-arcadia\"\n        }\n}'\n
\n\n


TIP : this call, above, can be used in place of the FIRST call when we created the policy \"1.2 PULL JSON file from a repository\". But be careful, the fullPath is the name set in the JSON policy file. 

\n\n

The 2 values need to match:

\n\n\n\n


9 Video demonstration

\n\n

In order to help you to understand how it looks with the BIG-IP, I created this video covering 4 topics explained in this article :

\n\n\n\n

At the end of this video, you will be able to adapt the REST Declarative API calls to your infrastructure, in order to deploy protected services with your CI/CD pipelines.

\n\n

Direct link to the video on DevCentral YouTube channel : https://youtu.be/EDvVwlwEFRw

\n\n\n

 

","body@stringLength":"27606","rawBody":"

Since v15.1 (in draft), F5® BIG-IP® Advanced WAF can import Declarative WAF policy in JSON format.

\n\n

The F5® BIG-IP® Advanced Web Application Firewall (Advanced WAF) security policies can be deployed using the declarative JSON format, facilitating easy integration into a CI/CD pipeline. The declarative policies are extracted from a source control system, for example Git, and imported into the BIG-IP.

\n\n

Using the provided declarative policy templates, you can modify the necessary parameters, save the JSON file, and import the updated security policy into your BIG-IP devices. The declarative policy copies the content of the template and adds the adjustments and modifications on to it. The templates therefore allow you to concentrate only on the specific settings that need to be adapted for the specific application that the policy protects.

\n\n

This Declarative WAF JSON policy is similar to NGINX App Protect policy. You can find more information on the Declarative Policy here :

\n\n\n\n

Audience

\n\n

This guide is written for IT professionals who need to automate their WAF policy and are familiar with Advanced WAF configuration. These IT professionals can fill a variety of roles:

\n\n\n\n

This article covers how to PUSH/PULL a declarative WAF policy in Advanced WAF:

\n\n\n\n


Table of contents

\n\n
  1. Upload Policy in BIG-IP
  2. Check the import
  3. Apply the policy
  4. OpenAPI Spec File import
  5. AS3 declaration
  6. CI/CD integration
  7. Find the Policy-ID
  8. Update an existing policy
  9. Video demonstration
\n \n\n

First of all, you need a JSON WAF policy, as below :

\n\n
\n{\n    \"policy\": {\n        \"name\": \"policy-api-arcadia\",\n        \"description\": \"Arcadia API\",\n        \"template\": {\n            \"name\": \"POLICY_TEMPLATE_API_SECURITY\"\n        },\n        \"enforcementMode\": \"blocking\",\n        \"server-technologies\": [\n            {\n                \"serverTechnologyName\": \"MySQL\"\n            },\n            {\n                \"serverTechnologyName\": \"Unix/Linux\"\n            },\n            {\n                \"serverTechnologyName\": \"MongoDB\"\n            }\n        ],\n        \"signature-settings\": {\n            \"signatureStaging\": false\n        },\n        \"policy-builder\": {\n            \"learnOnlyFromNonBotTraffic\": false\n        }\n    }\n}\n
\n\n


1. Upload Policy in BIG-IP

\n\n

There are 2 options to upload a JSON file into the BIG-IP:

\n\n

1.1 Either you PUSH the file into the BIG-IP and you IMPORT IT

\n\n

OR

\n\n

1.2 the BIG-IP PULL the file from a repository (and the IMPORT is included) <- BEST option

\n\n

1.1 PUSH JSON file into the BIG-IP

\n\n

The call is below. As you can notice, it requires a 'Content-Range' header. And the value is 0-(filesize-1)/filesize. In the example below, the file size is 662 bytes. This is not easy to integrate in a CICD pipeline, so we created the PULL method instead of the PUSH (in v16.0)

\n\n
\ncurl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/file-transfer/uploads/policy-api.json' \\\n--header 'Content-Range: 0-661/662' \\\n--header 'Authorization: Basic YWRtaW46YWRtaW4=' \\\n--header 'Content-Type: application/json' \\\n--data-binary '@/C:/Users/user/Desktop/policy-api.json'\n
\n\n

 

\n\n

At this stage, the policy is still a file ​​​​​​​in the BIG-IP file system. We need to import it into Adv. WAF. To do so, the next call is required.

\n\n

This call import the file \"policy-api.json\" uploaded previously. An CREATE the policy /Common/policy-api-arcadia

\n\n
\ncurl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \\\n--header 'Content-Type: application/javascript' \\\n--header 'Authorization: Basic YWRtaW46YWRtaW4=' \\\n--data-raw '{\n    \"filename\":\"policy-api.json\",\n    \"policy\":\n        {\n        \"fullPath\":\"/Common/policy-api-arcadia\"\n        }\n}'\n
\n\n

 

\n\n

1.2 PULL JSON file from a repository

\n\n

Here, the JSON file is hosted somewhere (in Gitlab or Github ...). And the BIG-IP will pull it

\n\n

The call is below. As you can notice, the call refers to the remote repo and the body is a JSON payload. Just change the link value with your JSON policy URL.

\n\n

With one call, the policy is PULLED and IMPORTED.

\n\n
\ncurl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \\\n--header 'Content-Type: application/json' \\\n--header 'Authorization: Basic YWRtaW46YWRtaW4=' \\\n--data-raw '{\n    \"fileReference\": { \n        \"link\": \"http://10.1.20.4/root/as3-waf/-/raw/master/policy-api.json\"\n    }\n}'\n
\n\n

 

\n\n

second version of this call exists, and refer to the fullPath of the policy. This will allow you to update the policy, from a second version of the JSON file, easily. One call for the creation and the update.

\n\n

As you can notice below, we add the \"policy\":\"fullPath\" directive. The value of the \"fullPath\" is the partition and the name of the policy set in the JSON policy file.

\n\n

This method is VERY USEFUL for CI/CD integrations. 

\n\n
\ncurl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \\\n--header 'Content-Type: application/json' \\\n--header 'Authorization: Basic YWRtaW46YWRtaW4=' \\\n--data-raw '{\n    \"fileReference\": { \n        \"link\": \"http://10.1.20.4/root/as3-waf/-/raw/master/policy-api.json\"\n    },\n    \"policy\":\n        {\n            \"fullPath\":\"/Common/policy-api-arcadia\"\n        }\n}'\n
\n\n


2. Check the IMPORT

\n\n

Check if the IMPORT worked. To do so, run the next call.

\n\n
\ncurl --location --request GET 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \\\n--header 'Authorization: Basic YWRtaW46YWRtaW4=' \\\n
\n\n

 

\n\n

You should see a 200 OK, with the content below (truncated in this example).
Please notice the 
\"status\":\"COMPLETED\".

\n\n
\n{\n    \"kind\": \"tm:asm:tasks:import-policy:import-policy-taskcollectionstate\",\n    \"selfLink\": \"https://localhost/mgmt/tm/asm/tasks/import-policy?ver=16.0.0\",\n    \"totalItems\": 11,\n    \"items\": [\n        {\n            \"isBase64\": false,\n            \"executionStartTime\": \"2020-07-21T15:50:22Z\",\n            \"status\": \"COMPLETED\",\n            \"lastUpdateMicros\": 1.595346627e+15,\n            \"getPolicyAttributesOnly\": false,\n...\n​
\n\n

From now, your policy is imported and created in the BIG-IP. You can assign it to a VS as usual (Imperative Call or AS3 Call). But in the next session, I will show you how to create a Service with AS3 including the WAF policy.

\n\n


3. APPLY the policy

\n\n

As you may know, a WAF policy needs to be applied after each change. This is the call.

\n\n
\ncurl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/apply-policy/' \\\n--header 'Content-Type: application/json' \\\n--header 'Authorization: Basic YWRtaW46YWRtaW4=' \\\n--data-raw '{\"policy\":{\"fullPath\":\"/Common/policy-api-arcadia\"}}'\n
\n\n


4. OpenAPI spec file IMPORT

\n\n

As you know, Adv. WAF supports OpenAPI spec (2.0 and 3.0). Now, with the declarative WAF, we can import the OAS file as well. The BEST solution, is to PULL the OAS file from a repo. And in most of the customer' projects, it will be the case.

\n\n

In the example below, the OAS file is hosted in SwaggerHub (Github for Swagger files). But the file could reside in a private Gitlab repo for instance.

\n\n
  1. The URL of the project is : https://app.swaggerhub.com/apis/F5EMEASSA/Arcadia-OAS3/1.0.0-oas3
  2. The URL of the OAS file is : https://api.swaggerhub.com/apis/F5EMEASSA/Arcadia-OAS3/1.0.0-oas3
\n\n

This swagger file (OpenAPI 3.0 Spec file) includes all the application URL and parameters. What's more, it includes the documentation (for NGINX APIm Dev Portal).

\n\n


Now, it is pretty easy to create a WAF JSON Policy with API Security template, referring to the OAS file.

\n\n

Below, you can notice the new section \"open-api-files\" with the link reference to SwaggerHub. And the new template POLICY_TEMPLATE_API_SECURITY.

\n\n

Now, when I upload / import and apply the policy, Adv. WAF will download the OAS file from SwaggerHub and create the policy based on API_Security template.

\n\n
\n{\n    \"policy\": {\n        \"name\": \"policy-api-arcadia\",\n        \"description\": \"Arcadia API\",\n        \"template\": {\n            \"name\": \"POLICY_TEMPLATE_API_SECURITY\"\n        },\n        \"enforcementMode\": \"blocking\",\n        \"server-technologies\": [\n            {\n                \"serverTechnologyName\": \"MySQL\"\n            },\n            {\n                \"serverTechnologyName\": \"Unix/Linux\"\n            },\n            {\n                \"serverTechnologyName\": \"MongoDB\"\n            }\n        ],\n        \"signature-settings\": {\n            \"signatureStaging\": false\n        },\n        \"policy-builder\": {\n            \"learnOnlyFromNonBotTraffic\": false\n        },\n        \"open-api-files\": [\n            {\n            \"link\": \"https://api.swaggerhub.com/apis/F5EMEASSA/Arcadia-OAS3/1.0.0-oas3\"\n            }\n        ]\n    }\n}\n
\n\n


5. AS3 declaration

\n\n

Now, it is time to learn how we can do all of these steps in one call with AS3 (3.18 minimum).

\n\n

The documentation is here : https://clouddocs.f5.com/products/extensions/f5-appsvcs-extension/latest/declarations/application-security.html?highlight=waf_policy#virtual-service-referencing-an-external-security-policy

\n\n

 

\n\n

With this AS3 declaration, we:

\n\n
  1. Import the WAF policy from a external repo
  2. Import the Swagger file (if the WAF policy refers to an OAS file) from an external repo
  3. Create the service
\n\n
\n{\n    \"class\": \"AS3\",\n    \"action\": \"deploy\",\n    \"persist\": true,\n    \"declaration\": {\n        \"class\": \"ADC\",\n        \"schemaVersion\": \"3.2.0\",\n        \"id\": \"Prod_API_AS3\",\n        \"API-Prod\": {\n            \"class\": \"Tenant\",\n            \"defaultRouteDomain\": 0,\n            \"API\": {\n                \"class\": \"Application\",\n                \"template\": \"generic\",\n                \"VS_API\": {\n                    \"class\": \"Service_HTTPS\",\n                    \"remark\": \"Accepts HTTPS/TLS connections on port 443\",\n                    \"virtualAddresses\": [\"10.1.10.27\"],\n                    \"redirect80\": false,\n                    \"pool\": \"pool_NGINX_API_AS3\",\n                    \"policyWAF\": {\n                        \"use\": \"Arcadia_WAF_API_policy\"\n                    },\n                    \"securityLogProfiles\": [{\n                        \"bigip\": \"/Common/Log all requests\"\n                    }],\n                    \"profileTCP\": {\n                        \"egress\": \"wan\",\n                        \"ingress\": { \"use\": \"TCP_Profile\" } },\n                    \"profileHTTP\": { \"use\": \"custom_http_profile\" },\n                    \"serverTLS\": { \"bigip\": \"/Common/arcadia_client_ssl\" }\n                },\n                \"Arcadia_WAF_API_policy\": {\n                    \"class\": \"WAF_Policy\",\n                    \"url\": \"http://10.1.20.4/root/as3-waf-api/-/raw/master/policy-api.json\",\n                    \"ignoreChanges\": true\n                },\n                \"pool_NGINX_API_AS3\": {\n                    \"class\": \"Pool\",\n                    \"monitors\": [\"http\"],\n                    \"members\": [{\n                        \"servicePort\": 8080,\n                        \"serverAddresses\": [\"10.1.20.9\"]\n                    }]\n                },\n                \"custom_http_profile\": {\n                    \"class\": \"HTTP_Profile\",\n                    \"xForwardedFor\": true\n                },\n                \"TCP_Profile\": {\n                    \"class\": \"TCP_Profile\",\n                    \"idleTimeout\": 60 }\n            }\n        }\n    }\n}\n
\n\n


6. CI/CID integration

\n\n

As you can notice, it is very easy to create a service with a WAF policy pulled from an external repo. So, it is easy to integrate these calls (or the AS3 call) into a CI/CD pipeline.

\n\n

Below, an Ansible playbook example. This playbook run the AS3 call above.
That's it :)

\n\n
\n---\n​\n    - hosts: bigip\n      connection: local\n      gather_facts: false\n      vars:\n        my_admin: \"admin\"\n        my_password: \"admin\"\n        bigip: \"10.1.1.12\"\n​\n      tasks:\n      - name: Deploy AS3 WebApp\n        uri:\n          url: \"https://{{ bigip }}/mgmt/shared/appsvcs/declare\"\n          method: POST\n          headers:\n            \"Content-Type\": \"application/json\"\n            \"Authorization\": \"Basic YWRtaW46YWRtaW4=\"\n          body: \"{{ lookup('file','as3.json') }}\"\n          body_format: json\n          validate_certs: no\n          status_code: 200\n
\n\n


7. FIND the Policy-ID

\n\n

When the policy is created, a Policy-ID is assigned. By default, this ID doesn't appear anywhere. Neither in the GUI, nor in the response after the creation.

\n\n

You have to calculate it or ask for it. This ID is required for several actions in a CI/CD pipeline.

\n\n

7.1 Calculate the Policy-ID

\n\n

We created this python script to calculate the Policy-ID. It is an hash from the Policy name (including the partition). For the previous created policy named \"/Common/policy-api-arcadia\", the policy ID is \"Ar5wrwmFRroUYsMA6DuxlQ\"

\n\n

Paste this python code in a new waf-policy-id.py file, and run the command python waf-policy-id.py \"/Common/policy-api-arcadia\"

\n\n

Outcome will be The Policy-ID for /Common/policy-api-arcadia is: Ar5wrwmFRroUYsMA6DuxlQ

\n\n
\n#!/usr/bin/python\n​\nfrom hashlib import md5\nimport base64\nimport sys\npname = sys.argv[1]\nprint 'The Policy-ID for', sys.argv[1], 'is:', base64.b64encode(md5(pname.encode()).digest()).replace(\"=\", \"\")\n
\n\n


7.2 Retrieve the Policy-ID and fullPath with a REST API call

\n\n

Make this call below, and you will see in the response, all the policy creations. Find yours and collect the PolicyReference directive. The Policy-ID is in the link value \"link\": \"https://localhost/mgmt/tm/asm/policies/Ar5wrwmFRroUYsMA6DuxlQ?ver=16.0.0\"

\n\n

You can see as well, at the end of the definition, the \"fileReference\" referring to the JSON file pulled by the BIG-IP.

\n\n

And please notice the \"fullPath\", required if you want to update your policy

\n\n
\ncurl --location --request GET 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \\\n--header 'Content-Range: 0-601/601' \\\n--header 'Authorization: Basic YWRtaW46YWRtaW4=' \\\n
\n\n
\n{\n    \"isBase64\": false,\n    \"executionStartTime\": \"2020-07-22T11:23:42Z\",\n    \"status\": \"COMPLETED\",\n    \"lastUpdateMicros\": 1.595417027e+15,\n    \"getPolicyAttributesOnly\": false,\n    \"kind\": \"tm:asm:tasks:import-policy:import-policy-taskstate\",\n    \"selfLink\": \"https://localhost/mgmt/tm/asm/tasks/import-policy/B45J0ySjSJ9y9fsPZ2JNvA?ver=16.0.0\",\n    \"filename\": \"\",\n    \"policyReference\": {\n        \"link\": \"https://localhost/mgmt/tm/asm/policies/Ar5wrwmFRroUYsMA6DuxlQ?ver=16.0.0\",\n        \"fullPath\": \"/Common/policy-api-arcadia\"\n    },\n    \"endTime\": \"2020-07-22T11:23:47Z\",\n    \"startTime\": \"2020-07-22T11:23:42Z\",\n    \"id\": \"B45J0ySjSJ9y9fsPZ2JNvA\",\n    \"retainInheritanceSettings\": false,\n    \"result\": {\n        \"policyReference\": {\n            \"link\": \"https://localhost/mgmt/tm/asm/policies/Ar5wrwmFRroUYsMA6DuxlQ?ver=16.0.0\",\n            \"fullPath\": \"/Common/policy-api-arcadia\"\n        },\n        \"message\": \"The operation was completed successfully. The security policy name is '/Common/policy-api-arcadia'. \"\n    },\n    \"fileReference\": {\n        \"link\": \"http://10.1.20.4/root/as3-waf/-/raw/master/policy-api.json\"\n    }\n},\n
\n\n


8 UPDATE an existing policy

\n\n

It is pretty easy to update the WAF policy from a new JSON file version. To do so, collect from the previous call 7.2 Retrieve the Policy-ID and fullPath with a REST API call the \"Policy\" and \"fullPath\" directive. This is the path of the Policy in the BIG-IP.

\n\n

Then run the call below, same as 1.2 PULL JSON file from a repository, ​​​​​​​but add the Policy and fullPath directives

\n\n

Don't forget to APPLY this new version of the policy 3. APPLY the policy

\n\n
\ncurl --location --request POST 'https://10.1.1.12/mgmt/tm/asm/tasks/import-policy/' \\\n--header 'Content-Type: application/json' \\\n--header 'Authorization: Basic YWRtaW46YWRtaW4=' \\\n--data-raw '{\n    \"fileReference\": { \n        \"link\": \"http://10.1.20.4/root/as3-waf/-/raw/master/policy-api.json\"\n    },\n    \"policy\":\n        {\n            \"fullPath\":\"/Common/policy-api-arcadia\"\n        }\n}'\n
\n\n


TIP : this call, above, can be used in place of the FIRST call when we created the policy \"1.2 PULL JSON file from a repository\". But be careful, the fullPath is the name set in the JSON policy file. 

\n\n

The 2 values need to match:

\n\n\n\n


9 Video demonstration

\n\n

In order to help you to understand how it looks with the BIG-IP, I created this video covering 4 topics explained in this article :

\n\n\n\n

At the end of this video, you will be able to adapt the REST Declarative API calls to your infrastructure, in order to deploy protected services with your CI/CD pipelines.

\n\n

Direct link to the video on DevCentral YouTube channel : https://youtu.be/EDvVwlwEFRw

\n\n\n

 

","kudosSumWeight":5,"postTime":"2020-07-30T08:43:08.000-07:00","images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"attachments":{"__typename":"AttachmentConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"tags":{"__typename":"TagConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[{"__typename":"TagEdge","cursor":"MjUuMnwyLjF8b3wxMHxfTlZffDE","node":{"__typename":"Tag","id":"tag:api","text":"api","time":"2022-01-24T02:30:03.977-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMnwyLjF8b3wxMHxfTlZffDI","node":{"__typename":"Tag","id":"tag:application delivery","text":"application delivery","time":"2021-06-30T01:48:44.000-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMnwyLjF8b3wxMHxfTlZffDM","node":{"__typename":"Tag","id":"tag:AS3","text":"AS3","time":"2022-11-28T02:35:02.758-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMnwyLjF8b3wxMHxfTlZffDQ","node":{"__typename":"Tag","id":"tag:ASM Advanced WAF","text":"ASM Advanced WAF","time":"2022-01-24T02:29:45.790-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMnwyLjF8b3wxMHxfTlZffDU","node":{"__typename":"Tag","id":"tag:declarative","text":"declarative","time":"2022-01-24T02:33:46.499-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMnwyLjF8b3wxMHxfTlZffDY","node":{"__typename":"Tag","id":"tag:SecOps","text":"SecOps","time":"2022-06-15T08:01:38.814-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMnwyLjF8b3wxMHxfTlZffDc","node":{"__typename":"Tag","id":"tag:security","text":"security","time":"2009-07-03T08:19:36.000-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMnwyLjF8b3wxMHxfTlZffDg","node":{"__typename":"Tag","id":"tag:series-devcentral-basics","text":"series-devcentral-basics","time":"2022-04-13T16:32:26.734-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMnwyLjF8b3wxMHxfTlZffDk","node":{"__typename":"Tag","id":"tag:waf","text":"waf","time":"2022-01-24T02:30:07.890-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}}]},"timeToRead":11,"rawTeaser":"","introduction":"","currentRevision":{"__ref":"Revision:revision:289251_1"},"latestVersion":{"__typename":"FriendlyVersion","major":"1","minor":"0"},"metrics":{"__typename":"MessageMetrics","views":3956},"visibilityScope":"PUBLIC","canonicalUrl":null,"seoTitle":null,"seoDescription":null,"placeholder":false,"originalMessageForPlaceholder":null,"contributors":{"__typename":"UserConnection","edges":[]},"nonCoAuthorContributors":{"__typename":"UserConnection","edges":[]},"coAuthors":{"__typename":"UserConnection","edges":[{"__typename":"UserEdge","node":{"__ref":"User:user:193857"}}]},"tkbMessagePolicies":{"__typename":"TkbMessagePolicies","canDoAuthoringActionsOnTkb":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.tkb.policy_can_do_authoring_action.accessDenied","key":"error.lithium.policies.tkb.policy_can_do_authoring_action.accessDenied","args":[]}}},"archivalData":null,"replies":{"__typename":"MessageConnection","edges":[{"__typename":"MessageEdge","cursor":"MjUuMnwyLjF8aXwxMHwzOToxfGludCwzMDk4MDIsMzA5ODAy","node":{"__ref":"TkbReplyMessage:message:309802"}},{"__typename":"MessageEdge","cursor":"MjUuMnwyLjF8aXwxMHwzOToxfGludCwzMDk4MDIsMzM1MDQw","node":{"__ref":"TkbReplyMessage:message:335040"}}],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"customFields":[],"revisions({\"constraints\":{\"isPublished\":{\"eq\":true}},\"first\":1})":{"__typename":"RevisionConnection","totalCount":1}},"Conversation:conversation:289251":{"__typename":"Conversation","id":"conversation:289251","solved":false,"topic":{"__ref":"TkbTopicMessage:message:289251"},"lastPostingActivityTime":"2024-10-03T06:56:43.549-07:00","lastPostTime":"2024-10-03T06:56:43.549-07:00","unreadReplyCount":2,"isSubscribed":false},"ModerationData:moderation_data:289251":{"__typename":"ModerationData","id":"moderation_data:289251","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"Revision:revision:289251_1":{"__typename":"Revision","id":"revision:289251_1","lastEditTime":"2020-07-30T08:43:08.000-07:00"},"CachedAsset:theme:customTheme1-1741989809765":{"__typename":"CachedAsset","id":"theme:customTheme1-1741989809765","value":{"id":"customTheme1","animation":{"fast":"150ms","normal":"250ms","slow":"500ms","slowest":"750ms","function":"cubic-bezier(0.07, 0.91, 0.51, 1)","__typename":"AnimationThemeSettings"},"avatar":{"borderRadius":"50%","collections":["custom"],"__typename":"AvatarThemeSettings"},"basics":{"browserIcon":{"imageAssetName":"JimmyPackets-512-1702592938213.png","imageLastModified":"1702592945815","__typename":"ThemeAsset"},"customerLogo":{"imageAssetName":"f5_logo_fix-1704824537976.svg","imageLastModified":"1704824540697","__typename":"ThemeAsset"},"maximumWidthOfPageContent":"1600px","oneColumnNarrowWidth":"800px","gridGutterWidthMd":"30px","gridGutterWidthXs":"10px","pageWidthStyle":"WIDTH_OF_PAGE_CONTENT","__typename":"BasicsThemeSettings"},"buttons":{"borderRadiusSm":"5px","borderRadius":"5px","borderRadiusLg":"5px","paddingY":"5px","paddingYLg":"7px","paddingYHero":"var(--lia-bs-btn-padding-y-lg)","paddingX":"12px","paddingXLg":"14px","paddingXHero":"42px","fontStyle":"NORMAL","fontWeight":"400","textTransform":"NONE","disabledOpacity":0.5,"primaryTextColor":"var(--lia-bs-white)","primaryTextHoverColor":"var(--lia-bs-white)","primaryTextActiveColor":"var(--lia-bs-white)","primaryBgColor":"var(--lia-bs-primary)","primaryBgHoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.85))","primaryBgActiveColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.7))","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","primaryBorderActive":"1px solid transparent","primaryBorderFocus":"1px solid var(--lia-bs-white)","primaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","secondaryTextColor":"var(--lia-bs-gray-900)","secondaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","secondaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","secondaryBgColor":"var(--lia-bs-gray-400)","secondaryBgHoverColor":"hsl(var(--lia-bs-gray-400-h), var(--lia-bs-gray-400-s), calc(var(--lia-bs-gray-400-l) * 0.96))","secondaryBgActiveColor":"hsl(var(--lia-bs-gray-400-h), var(--lia-bs-gray-400-s), calc(var(--lia-bs-gray-400-l) * 0.92))","secondaryBorder":"1px solid transparent","secondaryBorderHover":"1px solid transparent","secondaryBorderActive":"1px solid transparent","secondaryBorderFocus":"1px solid transparent","secondaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","tertiaryTextColor":"var(--lia-bs-gray-900)","tertiaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","tertiaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","tertiaryBgColor":"transparent","tertiaryBgHoverColor":"transparent","tertiaryBgActiveColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.04)","tertiaryBorder":"1px solid transparent","tertiaryBorderHover":"1px solid hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","tertiaryBorderActive":"1px solid transparent","tertiaryBorderFocus":"1px solid transparent","tertiaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","destructiveTextColor":"var(--lia-bs-danger)","destructiveTextHoverColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.95))","destructiveTextActiveColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.9))","destructiveBgColor":"var(--lia-bs-gray-300)","destructiveBgHoverColor":"hsl(var(--lia-bs-gray-300-h), var(--lia-bs-gray-300-s), calc(var(--lia-bs-gray-300-l) * 0.96))","destructiveBgActiveColor":"hsl(var(--lia-bs-gray-300-h), var(--lia-bs-gray-300-s), calc(var(--lia-bs-gray-300-l) * 0.92))","destructiveBorder":"1px solid transparent","destructiveBorderHover":"1px solid transparent","destructiveBorderActive":"1px solid transparent","destructiveBorderFocus":"1px solid transparent","destructiveBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","__typename":"ButtonsThemeSettings"},"border":{"color":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","mainContent":"NONE","sideContent":"NONE","radiusSm":"3px","radius":"5px","radiusLg":"9px","radius50":"100vw","__typename":"BorderThemeSettings"},"boxShadow":{"xs":"0 0 0 1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08), 0 3px 0 -1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08)","sm":"0 2px 4px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.06)","md":"0 5px 15px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.15)","lg":"0 10px 30px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.15)","__typename":"BoxShadowThemeSettings"},"cards":{"bgColor":"var(--lia-panel-bg-color)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":"var(--lia-box-shadow-xs)","__typename":"CardsThemeSettings"},"chip":{"maxWidth":"300px","height":"30px","__typename":"ChipThemeSettings"},"coreTypes":{"defaultMessageLinkColor":"var(--lia-bs-primary)","defaultMessageLinkDecoration":"none","defaultMessageLinkFontStyle":"NORMAL","defaultMessageLinkFontWeight":"400","defaultMessageFontStyle":"NORMAL","defaultMessageFontWeight":"400","forumColor":"#0C5C8D","forumFontFamily":"var(--lia-bs-font-family-base)","forumFontWeight":"var(--lia-default-message-font-weight)","forumLineHeight":"var(--lia-bs-line-height-base)","forumFontStyle":"var(--lia-default-message-font-style)","forumMessageLinkColor":"var(--lia-default-message-link-color)","forumMessageLinkDecoration":"var(--lia-default-message-link-decoration)","forumMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","forumMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","forumSolvedColor":"#62C026","blogColor":"#730015","blogFontFamily":"var(--lia-bs-font-family-base)","blogFontWeight":"var(--lia-default-message-font-weight)","blogLineHeight":"1.75","blogFontStyle":"var(--lia-default-message-font-style)","blogMessageLinkColor":"var(--lia-default-message-link-color)","blogMessageLinkDecoration":"var(--lia-default-message-link-decoration)","blogMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","blogMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","tkbColor":"#C20025","tkbFontFamily":"var(--lia-bs-font-family-base)","tkbFontWeight":"var(--lia-default-message-font-weight)","tkbLineHeight":"1.75","tkbFontStyle":"var(--lia-default-message-font-style)","tkbMessageLinkColor":"var(--lia-default-message-link-color)","tkbMessageLinkDecoration":"var(--lia-default-message-link-decoration)","tkbMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","tkbMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaColor":"#4099E2","qandaFontFamily":"var(--lia-bs-font-family-base)","qandaFontWeight":"var(--lia-default-message-font-weight)","qandaLineHeight":"var(--lia-bs-line-height-base)","qandaFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkColor":"var(--lia-default-message-link-color)","qandaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","qandaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaSolvedColor":"#3FA023","ideaColor":"#F3704B","ideaFontFamily":"var(--lia-bs-font-family-base)","ideaFontWeight":"var(--lia-default-message-font-weight)","ideaLineHeight":"var(--lia-bs-line-height-base)","ideaFontStyle":"var(--lia-default-message-font-style)","ideaMessageLinkColor":"var(--lia-default-message-link-color)","ideaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","ideaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","ideaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","contestColor":"#FCC845","contestFontFamily":"var(--lia-bs-font-family-base)","contestFontWeight":"var(--lia-default-message-font-weight)","contestLineHeight":"var(--lia-bs-line-height-base)","contestFontStyle":"var(--lia-default-message-link-font-style)","contestMessageLinkColor":"var(--lia-default-message-link-color)","contestMessageLinkDecoration":"var(--lia-default-message-link-decoration)","contestMessageLinkFontStyle":"ITALIC","contestMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","occasionColor":"#EE4B5B","occasionFontFamily":"var(--lia-bs-font-family-base)","occasionFontWeight":"var(--lia-default-message-font-weight)","occasionLineHeight":"var(--lia-bs-line-height-base)","occasionFontStyle":"var(--lia-default-message-font-style)","occasionMessageLinkColor":"var(--lia-default-message-link-color)","occasionMessageLinkDecoration":"var(--lia-default-message-link-decoration)","occasionMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","occasionMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","grouphubColor":"#491B62","categoryColor":"#949494","communityColor":"#FFFFFF","productColor":"#949494","__typename":"CoreTypesThemeSettings"},"colors":{"black":"#000000","white":"#FFFFFF","gray100":"#F7F7F7","gray200":"#F7F7F7","gray300":"#E8E8E8","gray400":"#D9D9D9","gray500":"#CCCCCC","gray600":"#949494","gray700":"#707070","gray800":"#545454","gray900":"#333333","dark":"#545454","light":"#F7F7F7","primary":"#0C5C8D","secondary":"#333333","bodyText":"#222222","bodyBg":"#F5F5F5","info":"#1D9CD3","success":"#62C026","warning":"#FFD651","danger":"#C20025","alertSystem":"#FF6600","textMuted":"#707070","highlight":"#FFFCAD","outline":"var(--lia-bs-primary)","custom":["#C20025","#081B85","#009639","#B3C6D7","#7CC0EB","#F29A36"],"__typename":"ColorsThemeSettings"},"divider":{"size":"3px","marginLeft":"4px","marginRight":"4px","borderRadius":"50%","bgColor":"var(--lia-bs-gray-600)","bgColorActive":"var(--lia-bs-gray-600)","__typename":"DividerThemeSettings"},"dropdown":{"fontSize":"var(--lia-bs-font-size-sm)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius-sm)","dividerBg":"var(--lia-bs-gray-300)","itemPaddingY":"5px","itemPaddingX":"20px","headerColor":"var(--lia-bs-gray-700)","__typename":"DropdownThemeSettings"},"email":{"link":{"color":"#0069D4","hoverColor":"#0061c2","decoration":"none","hoverDecoration":"underline","__typename":"EmailLinkSettings"},"border":{"color":"#e4e4e4","__typename":"EmailBorderSettings"},"buttons":{"borderRadiusLg":"5px","paddingXLg":"16px","paddingYLg":"7px","fontWeight":"700","primaryTextColor":"#ffffff","primaryTextHoverColor":"#ffffff","primaryBgColor":"#0069D4","primaryBgHoverColor":"#005cb8","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","__typename":"EmailButtonsSettings"},"panel":{"borderRadius":"5px","borderColor":"#e4e4e4","__typename":"EmailPanelSettings"},"__typename":"EmailThemeSettings"},"emoji":{"skinToneDefault":"#ffcd43","skinToneLight":"#fae3c5","skinToneMediumLight":"#e2cfa5","skinToneMedium":"#daa478","skinToneMediumDark":"#a78058","skinToneDark":"#5e4d43","__typename":"EmojiThemeSettings"},"heading":{"color":"var(--lia-bs-body-color)","fontFamily":"Inter","fontStyle":"NORMAL","fontWeight":"600","h1FontSize":"30px","h2FontSize":"25px","h3FontSize":"20px","h4FontSize":"18px","h5FontSize":"16px","h6FontSize":"16px","lineHeight":"1.2","subHeaderFontSize":"11px","subHeaderFontWeight":"500","h1LetterSpacing":"normal","h2LetterSpacing":"normal","h3LetterSpacing":"normal","h4LetterSpacing":"normal","h5LetterSpacing":"normal","h6LetterSpacing":"normal","subHeaderLetterSpacing":"2px","h1FontWeight":"var(--lia-bs-headings-font-weight)","h2FontWeight":"var(--lia-bs-headings-font-weight)","h3FontWeight":"var(--lia-bs-headings-font-weight)","h4FontWeight":"var(--lia-bs-headings-font-weight)","h5FontWeight":"var(--lia-bs-headings-font-weight)","h6FontWeight":"var(--lia-bs-headings-font-weight)","__typename":"HeadingThemeSettings"},"icons":{"size10":"10px","size12":"12px","size14":"14px","size16":"16px","size20":"20px","size24":"24px","size30":"30px","size40":"40px","size50":"50px","size60":"60px","size80":"80px","size120":"120px","size160":"160px","__typename":"IconsThemeSettings"},"imagePreview":{"bgColor":"var(--lia-bs-gray-900)","titleColor":"var(--lia-bs-white)","controlColor":"var(--lia-bs-white)","controlBgColor":"var(--lia-bs-gray-800)","__typename":"ImagePreviewThemeSettings"},"input":{"borderColor":"var(--lia-bs-gray-600)","disabledColor":"var(--lia-bs-gray-600)","focusBorderColor":"var(--lia-bs-primary)","labelMarginBottom":"10px","btnFontSize":"var(--lia-bs-font-size-sm)","focusBoxShadow":"0 0 0 3px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","checkLabelMarginBottom":"2px","checkboxBorderRadius":"3px","borderRadiusSm":"var(--lia-bs-border-radius-sm)","borderRadius":"var(--lia-bs-border-radius)","borderRadiusLg":"var(--lia-bs-border-radius-lg)","formTextMarginTop":"4px","textAreaBorderRadius":"var(--lia-bs-border-radius)","activeFillColor":"var(--lia-bs-primary)","__typename":"InputThemeSettings"},"loading":{"dotDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.2)","dotLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.5)","barDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.06)","barLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.4)","__typename":"LoadingThemeSettings"},"link":{"color":"var(--lia-bs-primary)","hoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) - 10%))","decoration":"none","hoverDecoration":"underline","__typename":"LinkThemeSettings"},"listGroup":{"itemPaddingY":"15px","itemPaddingX":"15px","borderColor":"var(--lia-bs-gray-300)","__typename":"ListGroupThemeSettings"},"modal":{"contentTextColor":"var(--lia-bs-body-color)","contentBg":"var(--lia-bs-white)","backgroundBg":"var(--lia-bs-black)","smSize":"440px","mdSize":"760px","lgSize":"1080px","backdropOpacity":0.3,"contentBoxShadowXs":"var(--lia-bs-box-shadow-sm)","contentBoxShadow":"var(--lia-bs-box-shadow)","headerFontWeight":"700","__typename":"ModalThemeSettings"},"navbar":{"position":"FIXED","background":{"attachment":null,"clip":null,"color":"var(--lia-bs-white)","imageAssetName":null,"imageLastModified":"0","origin":null,"position":"CENTER_CENTER","repeat":"NO_REPEAT","size":"COVER","__typename":"BackgroundProps"},"backgroundOpacity":0.8,"paddingTop":"15px","paddingBottom":"15px","borderBottom":"1px solid var(--lia-bs-border-color)","boxShadow":"var(--lia-bs-box-shadow-sm)","brandMarginRight":"30px","brandMarginRightSm":"10px","brandLogoHeight":"30px","linkGap":"10px","linkJustifyContent":"flex-start","linkPaddingY":"5px","linkPaddingX":"10px","linkDropdownPaddingY":"9px","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkColor":"var(--lia-bs-body-color)","linkHoverColor":"var(--lia-bs-primary)","linkFontSize":"var(--lia-bs-font-size-sm)","linkFontStyle":"NORMAL","linkFontWeight":"400","linkTextTransform":"NONE","linkLetterSpacing":"normal","linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkBgColor":"transparent","linkBgHoverColor":"transparent","linkBorder":"none","linkBorderHover":"none","linkBoxShadow":"none","linkBoxShadowHover":"none","linkTextBorderBottom":"none","linkTextBorderBottomHover":"none","dropdownPaddingTop":"10px","dropdownPaddingBottom":"15px","dropdownPaddingX":"10px","dropdownMenuOffset":"2px","dropdownDividerMarginTop":"10px","dropdownDividerMarginBottom":"10px","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","controllerIconColor":"var(--lia-bs-body-color)","controllerIconHoverColor":"var(--lia-bs-body-color)","controllerTextColor":"var(--lia-nav-controller-icon-color)","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","controllerHighlightColor":"hsla(30, 100%, 50%)","controllerHighlightTextColor":"var(--lia-yiq-light)","controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerColor":"var(--lia-nav-controller-icon-color)","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","hamburgerBgColor":"transparent","hamburgerBgHoverColor":"transparent","hamburgerBorder":"none","hamburgerBorderHover":"none","collapseMenuMarginLeft":"20px","collapseMenuDividerBg":"var(--lia-nav-link-color)","collapseMenuDividerOpacity":0.16,"__typename":"NavbarThemeSettings"},"pager":{"textColor":"var(--lia-bs-link-color)","textFontWeight":"var(--lia-font-weight-md)","textFontSize":"var(--lia-bs-font-size-sm)","__typename":"PagerThemeSettings"},"panel":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-bs-border-radius)","borderColor":"var(--lia-bs-border-color)","boxShadow":"none","__typename":"PanelThemeSettings"},"popover":{"arrowHeight":"8px","arrowWidth":"16px","maxWidth":"300px","minWidth":"100px","headerBg":"var(--lia-bs-white)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius)","boxShadow":"0 0.5rem 1rem hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.15)","__typename":"PopoverThemeSettings"},"prism":{"color":"#000000","bgColor":"#f5f2f0","fontFamily":"var(--font-family-monospace)","fontSize":"var(--lia-bs-font-size-base)","fontWeightBold":"var(--lia-bs-font-weight-bold)","fontStyleItalic":"italic","tabSize":2,"highlightColor":"#b3d4fc","commentColor":"#62707e","punctuationColor":"#6f6f6f","namespaceOpacity":"0.7","propColor":"#990055","selectorColor":"#517a00","operatorColor":"#906736","operatorBgColor":"hsla(0, 0%, 100%, 0.5)","keywordColor":"#0076a9","functionColor":"#d3284b","variableColor":"#c14700","__typename":"PrismThemeSettings"},"rte":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":" var(--lia-panel-box-shadow)","customColor1":"#bfedd2","customColor2":"#fbeeb8","customColor3":"#f8cac6","customColor4":"#eccafa","customColor5":"#c2e0f4","customColor6":"#2dc26b","customColor7":"#f1c40f","customColor8":"#e03e2d","customColor9":"#b96ad9","customColor10":"#3598db","customColor11":"#169179","customColor12":"#e67e23","customColor13":"#ba372a","customColor14":"#843fa1","customColor15":"#236fa1","customColor16":"#ecf0f1","customColor17":"#ced4d9","customColor18":"#95a5a6","customColor19":"#7e8c8d","customColor20":"#34495e","customColor21":"#000000","customColor22":"#ffffff","defaultMessageHeaderMarginTop":"14px","defaultMessageHeaderMarginBottom":"10px","defaultMessageItemMarginTop":"0","defaultMessageItemMarginBottom":"10px","diffAddedColor":"hsla(170, 53%, 51%, 0.4)","diffChangedColor":"hsla(43, 97%, 63%, 0.4)","diffNoneColor":"hsla(0, 0%, 80%, 0.4)","diffRemovedColor":"hsla(9, 74%, 47%, 0.4)","specialMessageHeaderMarginTop":"14px","specialMessageHeaderMarginBottom":"10px","specialMessageItemMarginTop":"0","specialMessageItemMarginBottom":"10px","__typename":"RteThemeSettings"},"tags":{"bgColor":"var(--lia-bs-gray-200)","bgHoverColor":"var(--lia-bs-gray-400)","borderRadius":"var(--lia-bs-border-radius-sm)","color":"var(--lia-bs-body-color)","hoverColor":"var(--lia-bs-body-color)","fontWeight":"var(--lia-font-weight-md)","fontSize":"var(--lia-font-size-xxs)","textTransform":"UPPERCASE","letterSpacing":"0.5px","__typename":"TagsThemeSettings"},"toasts":{"borderRadius":"var(--lia-bs-border-radius)","paddingX":"12px","__typename":"ToastsThemeSettings"},"typography":{"fontFamilyBase":"Atkinson Hyperlegible","fontStyleBase":"NORMAL","fontWeightBase":"400","fontWeightLight":"300","fontWeightNormal":"400","fontWeightMd":"500","fontWeightBold":"700","letterSpacingSm":"normal","letterSpacingXs":"normal","lineHeightBase":"1.3","fontSizeBase":"15px","fontSizeXxs":"11px","fontSizeXs":"12px","fontSizeSm":"13px","fontSizeLg":"20px","fontSizeXl":"24px","smallFontSize":"14px","customFonts":[],"__typename":"TypographyThemeSettings"},"unstyledListItem":{"marginBottomSm":"5px","marginBottomMd":"10px","marginBottomLg":"15px","marginBottomXl":"20px","marginBottomXxl":"25px","__typename":"UnstyledListItemThemeSettings"},"yiq":{"light":"#ffffff","dark":"#000000","__typename":"YiqThemeSettings"},"colorLightness":{"primaryDark":0.36,"primaryLight":0.74,"primaryLighter":0.89,"primaryLightest":0.95,"infoDark":0.39,"infoLight":0.72,"infoLighter":0.85,"infoLightest":0.93,"successDark":0.24,"successLight":0.62,"successLighter":0.8,"successLightest":0.91,"warningDark":0.39,"warningLight":0.68,"warningLighter":0.84,"warningLightest":0.93,"dangerDark":0.41,"dangerLight":0.72,"dangerLighter":0.89,"dangerLightest":0.95,"__typename":"ColorLightnessThemeSettings"},"localOverride":false,"__typename":"Theme"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-1740415735000","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:quilt:f5.prod:pages/kbs/TkbMessagePage:board:TechnicalArticles-1741989808042":{"__typename":"CachedAsset","id":"quilt:f5.prod:pages/kbs/TkbMessagePage:board:TechnicalArticles-1741989808042","value":{"id":"TkbMessagePage","container":{"id":"Common","headerProps":{"backgroundImageProps":null,"backgroundColor":null,"addComponents":null,"removeComponents":["community.widget.bannerWidget"],"componentOrder":null,"__typename":"QuiltContainerSectionProps"},"headerComponentProps":{"community.widget.breadcrumbWidget":{"disableLastCrumbForDesktop":false}},"footerProps":null,"footerComponentProps":null,"items":[{"id":"message-list","layout":"MAIN_SIDE","bgColor":"transparent","showTitle":true,"showDescription":true,"textPosition":"CENTER","textColor":"var(--lia-bs-body-color)","sectionEditLevel":null,"bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"MainSideQuiltSection","columnMap":{"main":[{"id":"tkbs.widget.tkbArticleWidget","className":"lia-tkb-container","props":{"contributorListType":"panel","showHelpfulness":false,"showTimestamp":true,"showGuideNavigationSection":true,"showVersion":true,"lazyLoad":false,"editLevel":"CONFIGURE"},"__typename":"QuiltComponent"}],"side":[{"id":"featuredWidgets.widget.featuredContentWidget","className":null,"props":{"instanceId":"featuredWidgets.widget.featuredContentWidget-1702666556326","layoutProps":{"layout":"card","layoutOptions":{"useRepliesCount":false,"useAuthorRank":false,"useTimeToRead":true,"useKudosCount":false,"useViewCount":true,"usePreviewMedia":true,"useBody":false,"useCenteredCardContent":false,"useTags":true,"useTimestamp":false,"useBoardLink":true,"useAuthorLink":false,"useSolvedBadge":true}},"titleSrOnly":false,"showPager":true,"pageSize":3,"lazyLoad":true},"__typename":"QuiltComponent"},{"id":"messages.widget.relatedContentWidget","className":null,"props":{"hideIfEmpty":true,"enablePagination":true,"useTitle":true,"listVariant":{"type":"listGroup"},"pageSize":3,"style":"list","pagerVariant":{"type":"loadMore"},"viewVariant":{"type":"inline","props":{"useRepliesCount":true,"useMedia":true,"useAuthorRank":false,"useNode":true,"useTimeToRead":true,"useSpoilerFreeBody":true,"useKudosCount":true,"useNodeLink":true,"useViewCount":true,"usePreviewMedia":false,"useBody":false,"timeStampType":"postTime","useTags":true,"clampSubjectLines":2,"useBoardIcon":false,"useMessageTimeLink":true,"clampBodyLines":3,"useTextBody":true,"useSolvedBadge":true,"useAvatar":true,"useAuthorLogin":true,"useUnreadCount":true}},"lazyLoad":true,"panelType":"divider"},"__typename":"QuiltComponent"}],"__typename":"MainSideSectionColumns"}}],"__typename":"QuiltContainer"},"__typename":"Quilt","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/EmailVerification-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/common/EmailVerification-1740415735000","value":{"email.verification.title":"Email Verification Required","email.verification.message.update.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. To change your email, visit My Settings.","email.verification.message.resend.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. Resend email."},"localOverride":false},"CachedAsset:text:en_US-pages/kbs/TkbMessagePage-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-pages/kbs/TkbMessagePage-1740415735000","value":{"title":"{contextMessageSubject} | {communityTitle}","errorMissing":"This article cannot be found","name":"TKB Message Page","section.message-list.title":"","archivedMessageTitle":"This Content Has Been Archived","section.erPqcf.title":"","section.erPqcf.description":"","section.message-list.description":""},"localOverride":false},"CachedAsset:quiltWrapper:f5.prod:Common:1741989724130":{"__typename":"CachedAsset","id":"quiltWrapper:f5.prod:Common:1741989724130","value":{"id":"Common","header":{"backgroundImageProps":{"assetName":"header.jpg","backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"LEFT_CENTER","lastModified":"1702932449000","__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"custom.widget.Beta_MetaNav","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"community.widget.navbarWidget","props":{"showUserName":false,"showRegisterLink":true,"style":{"boxShadow":"var(--lia-bs-box-shadow-sm)","linkFontWeight":"700","controllerHighlightColor":"hsla(30, 100%, 50%)","dropdownDividerMarginBottom":"10px","hamburgerBorderHover":"none","linkFontSize":"15px","linkBoxShadowHover":"none","backgroundOpacity":0.4,"controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerBgColor":"transparent","linkTextBorderBottom":"none","hamburgerColor":"var(--lia-nav-controller-icon-color)","brandLogoHeight":"48px","linkLetterSpacing":"normal","linkBgHoverColor":"transparent","collapseMenuDividerOpacity":0.16,"paddingBottom":"10px","dropdownPaddingBottom":"15px","dropdownMenuOffset":"2px","hamburgerBgHoverColor":"transparent","borderBottom":"0","hamburgerBorder":"none","dropdownPaddingX":"10px","brandMarginRightSm":"10px","linkBoxShadow":"none","linkJustifyContent":"center","linkColor":"var(--lia-bs-primary)","collapseMenuDividerBg":"var(--lia-nav-link-color)","dropdownPaddingTop":"10px","controllerHighlightTextColor":"var(--lia-yiq-dark)","background":{"imageAssetName":"","color":"var(--lia-bs-white)","size":"COVER","repeat":"NO_REPEAT","position":"CENTER_CENTER","imageLastModified":""},"linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkHoverColor":"var(--lia-bs-primary)","position":"FIXED","linkBorder":"none","linkTextBorderBottomHover":"2px solid #0C5C8D","brandMarginRight":"30px","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","linkBorderHover":"none","collapseMenuMarginLeft":"20px","linkFontStyle":"NORMAL","linkPaddingX":"10px","paddingTop":"10px","linkPaddingY":"5px","linkTextTransform":"NONE","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkBgColor":"transparent","linkDropdownPaddingY":"9px","controllerIconColor":"#0C5C8D","dropdownDividerMarginTop":"10px","linkGap":"10px","controllerIconHoverColor":"#0C5C8D"},"links":{"sideLinks":[],"mainLinks":[{"children":[{"linkType":"INTERNAL","id":"migrated-link-1","params":{"boardId":"TechnicalForum","categoryId":"Forums"},"routeName":"ForumBoardPage"},{"linkType":"INTERNAL","id":"migrated-link-2","params":{"boardId":"WaterCooler","categoryId":"Forums"},"routeName":"ForumBoardPage"}],"linkType":"INTERNAL","id":"migrated-link-0","params":{"categoryId":"Forums"},"routeName":"CategoryPage"},{"children":[{"linkType":"INTERNAL","id":"migrated-link-4","params":{"boardId":"codeshare","categoryId":"CrowdSRC"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"migrated-link-5","params":{"boardId":"communityarticles","categoryId":"CrowdSRC"},"routeName":"TkbBoardPage"}],"linkType":"INTERNAL","id":"migrated-link-3","params":{"categoryId":"CrowdSRC"},"routeName":"CategoryPage"},{"children":[{"linkType":"INTERNAL","id":"migrated-link-7","params":{"boardId":"TechnicalArticles","categoryId":"Articles"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"article-series","params":{"boardId":"article-series","categoryId":"Articles"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"security-insights","params":{"boardId":"security-insights","categoryId":"Articles"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"migrated-link-8","params":{"boardId":"DevCentralNews","categoryId":"Articles"},"routeName":"TkbBoardPage"}],"linkType":"INTERNAL","id":"migrated-link-6","params":{"categoryId":"Articles"},"routeName":"CategoryPage"},{"children":[{"linkType":"INTERNAL","id":"migrated-link-10","params":{"categoryId":"CommunityGroups"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"migrated-link-11","params":{"categoryId":"F5-Groups"},"routeName":"CategoryPage"}],"linkType":"INTERNAL","id":"migrated-link-9","params":{"categoryId":"GroupsCategory"},"routeName":"CategoryPage"},{"children":[],"linkType":"INTERNAL","id":"migrated-link-12","params":{"boardId":"Events","categoryId":"top"},"routeName":"EventBoardPage"},{"children":[],"linkType":"INTERNAL","id":"migrated-link-13","params":{"boardId":"Suggestions","categoryId":"top"},"routeName":"IdeaBoardPage"},{"children":[],"linkType":"EXTERNAL","id":"Common-external-link","url":"https://community.f5.com/c/how-do-i","target":"SELF"}]},"className":"QuiltComponent_lia-component-edit-mode__lQ9Z6","showSearchIcon":false},"__typename":"QuiltComponent"},{"id":"community.widget.bannerWidget","props":{"backgroundColor":"transparent","visualEffects":{"showBottomBorder":false},"backgroundImageProps":{"backgroundSize":"COVER","backgroundPosition":"CENTER_CENTER","backgroundRepeat":"NO_REPEAT"},"fontColor":"#222222"},"__typename":"QuiltComponent"},{"id":"community.widget.breadcrumbWidget","props":{"backgroundColor":"var(--lia-bs-primary)","linkHighlightColor":"#FFFFFF","visualEffects":{"showBottomBorder":false},"backgroundOpacity":60,"linkTextColor":"#FFFFFF"},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"footer":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"var(--lia-bs-body-color)","items":[{"id":"custom.widget.Beta_Footer","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.Tag_Manager_Helper","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.Consent_Blackbar","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"__typename":"QuiltWrapper","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/ActionFeedback-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/common/ActionFeedback-1740415735000","value":{"joinedGroupHub.title":"Welcome","joinedGroupHub.message":"You are now a member of this group and are subscribed to updates.","groupHubInviteNotFound.title":"Invitation Not Found","groupHubInviteNotFound.message":"Sorry, we could not find your invitation to the group. The owner may have canceled the invite.","groupHubNotFound.title":"Group Not Found","groupHubNotFound.message":"The grouphub you tried to join does not exist. It may have been deleted.","existingGroupHubMember.title":"Already Joined","existingGroupHubMember.message":"You are already a member of this group.","accountLocked.title":"Account Locked","accountLocked.message":"Your account has been locked due to multiple failed attempts. Try again in {lockoutTime} minutes.","editedGroupHub.title":"Changes Saved","editedGroupHub.message":"Your group has been updated.","leftGroupHub.title":"Goodbye","leftGroupHub.message":"You are no longer a member of this group and will not receive future updates.","deletedGroupHub.title":"Deleted","deletedGroupHub.message":"The group has been deleted.","groupHubCreated.title":"Group Created","groupHubCreated.message":"{groupHubName} is ready to use","accountClosed.title":"Account Closed","accountClosed.message":"The account has been closed and you will now be redirected to the homepage","resetTokenExpired.title":"Reset Password Link has Expired","resetTokenExpired.message":"Try resetting your password again","invalidUrl.title":"Invalid URL","invalidUrl.message":"The URL you're using is not recognized. Verify your URL and try again.","accountClosedForUser.title":"Account Closed","accountClosedForUser.message":"{userName}'s account is closed","inviteTokenInvalid.title":"Invitation Invalid","inviteTokenInvalid.message":"Your invitation to the community has been canceled or expired.","inviteTokenError.title":"Invitation Verification Failed","inviteTokenError.message":"The url you are utilizing is not recognized. Verify your URL and try again","pageNotFound.title":"Access Denied","pageNotFound.message":"You do not have access to this area of the community or it doesn't exist","eventAttending.title":"Responded as Attending","eventAttending.message":"You'll be notified when there's new activity and reminded as the event approaches","eventInterested.title":"Responded as Interested","eventInterested.message":"You'll be notified when there's new activity and reminded as the event approaches","eventNotFound.title":"Event Not Found","eventNotFound.message":"The event you tried to respond to does not exist.","redirectToRelatedPage.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.message":"The content you are trying to access is archived","redirectToRelatedPage.message":"The content you are trying to access is archived","relatedUrl.archivalLink.flyoutMessage":"The content you are trying to access is archived View Archived Content"},"localOverride":false},"CachedAsset:component:custom.widget.Beta_MetaNav-en-1741989830575":{"__typename":"CachedAsset","id":"component:custom.widget.Beta_MetaNav-en-1741989830575","value":{"component":{"id":"custom.widget.Beta_MetaNav","template":{"id":"Beta_MetaNav","markupLanguage":"HANDLEBARS","style":null,"texts":null,"defaults":{"config":{"applicablePages":[],"description":"MetaNav menu at the top of every page.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Beta_MetaNav","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"MetaNav menu at the top of every page.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Beta_Footer-en-1741989830575":{"__typename":"CachedAsset","id":"component:custom.widget.Beta_Footer-en-1741989830575","value":{"component":{"id":"custom.widget.Beta_Footer","template":{"id":"Beta_Footer","markupLanguage":"HANDLEBARS","style":null,"texts":null,"defaults":{"config":{"applicablePages":[],"description":"DevCentral´s custom footer.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Beta_Footer","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"DevCentral´s custom footer.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Tag_Manager_Helper-en-1741989830575":{"__typename":"CachedAsset","id":"component:custom.widget.Tag_Manager_Helper-en-1741989830575","value":{"component":{"id":"custom.widget.Tag_Manager_Helper","template":{"id":"Tag_Manager_Helper","markupLanguage":"HANDLEBARS","style":null,"texts":null,"defaults":{"config":{"applicablePages":[],"description":"Helper widget to inject Tag Manager scripts into head element","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Tag_Manager_Helper","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"Helper widget to inject Tag Manager scripts into head element","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Consent_Blackbar-en-1741989830575":{"__typename":"CachedAsset","id":"component:custom.widget.Consent_Blackbar-en-1741989830575","value":{"component":{"id":"custom.widget.Consent_Blackbar","template":{"id":"Consent_Blackbar","markupLanguage":"HTML","style":null,"texts":null,"defaults":{"config":{"applicablePages":[],"description":"","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Consent_Blackbar","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"TEXTHTML","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:text:en_US-components/community/Breadcrumb-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/community/Breadcrumb-1740415735000","value":{"navLabel":"Breadcrumbs","dropdown":"Additional parent page navigation"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBanner-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBanner-1740415735000","value":{"messageMarkedAsSpam":"This post has been marked as spam","messageMarkedAsSpam@board:TKB":"This article has been marked as spam","messageMarkedAsSpam@board:BLOG":"This post has been marked as spam","messageMarkedAsSpam@board:FORUM":"This discussion has been marked as spam","messageMarkedAsSpam@board:OCCASION":"This event has been marked as spam","messageMarkedAsSpam@board:IDEA":"This idea has been marked as spam","manageSpam":"Manage Spam","messageMarkedAsAbuse":"This post has been marked as abuse","messageMarkedAsAbuse@board:TKB":"This article has been marked as abuse","messageMarkedAsAbuse@board:BLOG":"This post has been marked as abuse","messageMarkedAsAbuse@board:FORUM":"This discussion has been marked as abuse","messageMarkedAsAbuse@board:OCCASION":"This event has been marked as abuse","messageMarkedAsAbuse@board:IDEA":"This idea has been marked as abuse","preModCommentAuthorText":"This comment will be published as soon as it is approved","preModCommentModeratorText":"This comment is awaiting moderation","messageMarkedAsOther":"This post has been rejected due to other reasons","messageMarkedAsOther@board:TKB":"This article has been rejected due to other reasons","messageMarkedAsOther@board:BLOG":"This post has been rejected due to other reasons","messageMarkedAsOther@board:FORUM":"This discussion has been rejected due to other reasons","messageMarkedAsOther@board:OCCASION":"This event has been rejected due to other reasons","messageMarkedAsOther@board:IDEA":"This idea has been rejected due to other reasons","messageArchived":"This post was archived on {date}","relatedUrl":"View Related Content","relatedContentText":"Showing related content","archivedContentLink":"View Archived Content"},"localOverride":false},"CachedAsset:text:en_US-components/tkbs/TkbArticleWidget-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/tkbs/TkbArticleWidget-1740415735000","value":{},"localOverride":false},"Category:category:Forums":{"__typename":"Category","id":"category:Forums","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Forum:board:TechnicalForum":{"__typename":"Forum","id":"board:TechnicalForum","forumPolicies":{"__typename":"ForumPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Forum:board:WaterCooler":{"__typename":"Forum","id":"board:WaterCooler","forumPolicies":{"__typename":"ForumPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:DevCentralNews":{"__typename":"Tkb","id":"board:DevCentralNews","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:GroupsCategory":{"__typename":"Category","id":"category:GroupsCategory","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:F5-Groups":{"__typename":"Category","id":"category:F5-Groups","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:CommunityGroups":{"__typename":"Category","id":"category:CommunityGroups","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Occasion:board:Events":{"__typename":"Occasion","id":"board:Events","boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"occasionPolicies":{"__typename":"OccasionPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Idea:board:Suggestions":{"__typename":"Idea","id":"board:Suggestions","boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"ideaPolicies":{"__typename":"IdeaPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:CrowdSRC":{"__typename":"Category","id":"category:CrowdSRC","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:codeshare":{"__typename":"Tkb","id":"board:codeshare","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:communityarticles":{"__typename":"Tkb","id":"board:communityarticles","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:security-insights":{"__typename":"Tkb","id":"board:security-insights","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:article-series":{"__typename":"Tkb","id":"board:article-series","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"TkbTopicMessage:message:286776":{"__typename":"TkbTopicMessage","id":"message:286776","uid":286776,"subject":"L3/4/DNS DDoS Reporting with Elastic Search and Kibana","board":{"__ref":"Tkb:board:TechnicalArticles"}},"Guide:guide:4":{"__typename":"Guide","id":"guide:4","lastArticle":{"__ref":"TkbTopicMessage:message:286776"}},"TkbTopicMessage:message:279496":{"__typename":"TkbTopicMessage","id":"message:279496","uid":279496,"subject":"1. SYN Cookie: Intro","board":{"__ref":"Tkb:board:TechnicalArticles"}},"Guide:guide:6":{"__typename":"Guide","id":"guide:6","firstArticle":{"__ref":"TkbTopicMessage:message:279496"}},"Guide:guide:5":{"__typename":"Guide","id":"guide:5","title":"DevCentral Basics","node":{"__ref":"Tkb:board:article-series"},"previousGuide":{"__ref":"Guide:guide:4"},"nextGuide":{"__ref":"Guide:guide:6"}},"Chapter:chapter:51":{"__typename":"Chapter","id":"chapter:51","guide":{"__ref":"Guide:guide:5"}},"TkbTopicMessage:message:283890":{"__typename":"TkbTopicMessage","id":"message:283890","uid":283890,"subject":"Getting Started with iControl: History","board":{"__ref":"Tkb:board:TechnicalArticles"}},"TkbTopicMessage:message:286022":{"__typename":"TkbTopicMessage","id":"message:286022","uid":286022,"subject":"From ASM to Advanced WAF: Advancing your Application Security","board":{"__ref":"Tkb:board:TechnicalArticles"}},"CachedAsset:text:en_US-components/community/Navbar-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/community/Navbar-1740415735000","value":{"community":"Community Home","inbox":"Inbox","manageContent":"Manage Content","tos":"Terms of Service","forgotPassword":"Forgot Password","themeEditor":"Theme Editor","edit":"Edit Navigation Bar","skipContent":"Skip to content","migrated-link-9":"Groups","migrated-link-7":"Technical Articles","migrated-link-8":"DevCentral News","migrated-link-1":"Technical Forum","migrated-link-10":"Community Groups","migrated-link-2":"Water Cooler","migrated-link-11":"F5 Groups","Common-external-link":"How Do I...?","migrated-link-0":"Forums","article-series":"Article Series","migrated-link-5":"Community Articles","migrated-link-6":"Articles","security-insights":"Security Insights","migrated-link-3":"CrowdSRC","migrated-link-4":"CodeShare","migrated-link-12":"Events","migrated-link-13":"Suggestions"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarHamburgerDropdown-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarHamburgerDropdown-1740415735000","value":{"hamburgerLabel":"Side Menu"},"localOverride":false},"CachedAsset:text:en_US-components/community/BrandLogo-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/community/BrandLogo-1740415735000","value":{"logoAlt":"Khoros","themeLogoAlt":"Brand Logo"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarTextLinks-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarTextLinks-1740415735000","value":{"more":"More"},"localOverride":false},"CachedAsset:text:en_US-components/authentication/AuthenticationLink-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/authentication/AuthenticationLink-1740415735000","value":{"title.login":"Sign In","title.registration":"Register","title.forgotPassword":"Forgot Password","title.multiAuthLogin":"Sign In"},"localOverride":false},"CachedAsset:text:en_US-components/nodes/NodeLink-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/nodes/NodeLink-1740415735000","value":{"place":"Place {name}"},"localOverride":false},"QueryVariables:TopicReplyList:message:289251:1":{"__typename":"QueryVariables","id":"TopicReplyList:message:289251:1","value":{"id":"message:289251","first":10,"sorts":{"postTime":{"direction":"ASC"}},"repliesFirst":3,"repliesFirstDepthThree":1,"repliesSorts":{"postTime":{"direction":"ASC"}},"useAvatar":true,"useAuthorLogin":true,"useAuthorRank":true,"useBody":true,"useKudosCount":true,"useTimeToRead":false,"useMedia":false,"useReadOnlyIcon":false,"useRepliesCount":true,"useSearchSnippet":false,"useAcceptedSolutionButton":false,"useSolvedBadge":false,"useAttachments":false,"attachmentsFirst":5,"useTags":true,"useNodeAncestors":false,"useUserHoverCard":false,"useNodeHoverCard":false,"useModerationStatus":true,"usePreviewSubjectModal":false,"useMessageStatus":true}},"ROOT_MUTATION":{"__typename":"Mutation"},"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/QueryHandler-1740415735000","value":{"title":"Query Handler"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarDropdownToggle-1740415735000","value":{"ariaLabelClosed":"Press the down arrow to open the menu"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageView/MessageViewStandard-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageView/MessageViewStandard-1740415735000","value":{"anonymous":"Anonymous","author":"{messageAuthorLogin}","authorBy":"{messageAuthorLogin}","board":"{messageBoardTitle}","replyToUser":" to {parentAuthor}","showMoreReplies":"Show More","replyText":"Reply","repliesText":"Replies","markedAsSolved":"Marked as Solved","movedMessagePlaceholder.BLOG":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.TKB":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.FORUM":"{count, plural, =0 {This reply has been} other {These replies have been} }","movedMessagePlaceholder.IDEA":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.OCCASION":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholderUrlText":"moved.","messageStatus":"Status: ","statusChanged":"Status changed: {previousStatus} to {currentStatus}","statusAdded":"Status added: {status}","statusRemoved":"Status removed: {status}","labelExpand":"expand replies","labelCollapse":"collapse replies","unhelpfulReason.reason1":"Content is outdated","unhelpfulReason.reason2":"Article is missing information","unhelpfulReason.reason3":"Content is for a different Product","unhelpfulReason.reason4":"Doesn't match what I was searching for"},"localOverride":false},"CachedAsset:text:en_US-components/messages/ThreadedReplyList-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/ThreadedReplyList-1740415735000","value":{"title":"{count, plural, one{# Reply} other{# Replies}}","title@board:BLOG":"{count, plural, one{# Comment} other{# Comments}}","title@board:TKB":"{count, plural, one{# Comment} other{# Comments}}","title@board:IDEA":"{count, plural, one{# Comment} other{# Comments}}","title@board:OCCASION":"{count, plural, one{# Comment} other{# Comments}}","noRepliesTitle":"No Replies","noRepliesTitle@board:BLOG":"No Comments","noRepliesTitle@board:TKB":"No Comments","noRepliesTitle@board:IDEA":"No Comments","noRepliesTitle@board:OCCASION":"No Comments","noRepliesDescription":"Be the first to reply","noRepliesDescription@board:BLOG":"Be the first to comment","noRepliesDescription@board:TKB":"Be the first to comment","noRepliesDescription@board:IDEA":"Be the first to comment","noRepliesDescription@board:OCCASION":"Be the first to comment","messageReadOnlyAlert:BLOG":"Comments have been turned off for this post","messageReadOnlyAlert:TKB":"Comments have been turned off for this article","messageReadOnlyAlert:IDEA":"Comments have been turned off for this idea","messageReadOnlyAlert:FORUM":"Replies have been turned off for this discussion","messageReadOnlyAlert:OCCASION":"Comments have been turned off for this event"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyCallToAction-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyCallToAction-1740415735000","value":{"leaveReply":"Leave a reply...","leaveReply@board:BLOG@message:root":"Leave a comment...","leaveReply@board:TKB@message:root":"Leave a comment...","leaveReply@board:IDEA@message:root":"Leave a comment...","leaveReply@board:OCCASION@message:root":"Leave a comment...","repliesTurnedOff.FORUM":"Replies are turned off for this topic","repliesTurnedOff.BLOG":"Comments are turned off for this topic","repliesTurnedOff.TKB":"Comments are turned off for this topic","repliesTurnedOff.IDEA":"Comments are turned off for this topic","repliesTurnedOff.OCCASION":"Comments are turned off for this topic","infoText":"Stop poking me!"},"localOverride":false},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/cmstMjktRWl0NU5q\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/cmstMjktRWl0NU5q","height":24,"width":21,"mimeType":"image/png"},"Rank:rank:29":{"__typename":"Rank","id":"rank:29","position":6,"name":"MVP","color":"7CC0EB","icon":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/cmstMjktRWl0NU5q\"}"},"rankStyle":"FILLED"},"User:user:305752":{"__typename":"User","id":"user:305752","uid":305752,"login":"Nikoolayy1","biography":null,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2019-10-15T01:14:48.000-07:00"},"deleted":false,"email":"","avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/images/dS0zMDU3NTItd2tMWnln?image-coordinates=3%2C3%2C176%2C176"},"rank":{"__ref":"Rank:rank:29"},"entityType":"USER","eventPath":"community:zihoc95639/user:305752"},"ModerationData:moderation_data:309802":{"__typename":"ModerationData","id":"moderation_data:309802","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"TkbReplyMessage:message:309802":{"__typename":"TkbReplyMessage","author":{"__ref":"User:user:305752"},"id":"message:309802","revisionNum":3,"uid":309802,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Tkb:board:TechnicalArticles"},"parent":{"__ref":"TkbTopicMessage:message:289251"},"conversation":{"__ref":"Conversation:conversation:289251"},"subject":"Re: Advanced WAF v16.0 - Declarative API","moderationData":{"__ref":"ModerationData:moderation_data:309802"},"body":"

Thanks! Is there a way to push JSON file with F5 Ansible module like \"bigip_asm_policy_import\". I know that probably the URI Ansbile module will do the trick but I am looking for a native way to push the ASM policy and then use the new \" bigip_as3_deploy\" module (the new way to push AS3 Declarations and I made an article about it https://community.f5.com/t5/codeshare/comparison-between-deploying-as3-or-fast-iapp-declarations-with/ta-p/309613 ) to deploy the AS3 declaration that will reference the pushed policy.

\n

 

\n

I tried to replace \"url\": \"http://10.1.20.4/root/as3-waf-api/-/raw/master/policy-api.json\" with the ASM policy but if I do not want to host the ASM polcy on git then I see the option I mentioned as pushing the ASM policy to the F5 and then referencing it in the AS3.

\n

 

\n

Edit:

\n

 

\n

I think with the Ansible URI module I can script the file upload commands (the bigip_asm_policy_import seems to have issues so the URI module seems the better option for file upload and then making the asm policy from the file upload) as have for other stuff but still a native Ansible module that can also auto calculate the \"Content-Range\" header for file upload will really be helpfull but as you mentioned using the \"Pull\" could be an option.

\n

 

\n

Managed to make it work with the URI module, just for some reason the F5 thinks the files are the wrong falue and this seems like a bug.

\n

 

\n

\"message\": \"Chunk byte count 402 in Content-Range header different from received buffer length 394\",

\n

 

\n

└─# stat -c%s asm_policy.json
665

\n

 

\n

 

\n

tasks:

\n


- name: PUSH FILE WAF

\n

uri:

\n

url: \"https://{{ ansible_host }}/mgmt/tm/asm/file-transfer/uploads/asm_policy.json\"

\n

method: POST

\n

body: \"{{ lookup('template','asm_policy.json', split_lines=False) }}\"

\n

status_code: 200

\n

timeout: 300

\n

body_format: json

\n

force_basic_auth: yes

\n

user: \"{{ ansible_user }}\"

\n

password: \"{{ ansible_httpapi_password }}\"

\n

validate_certs: no

\n

headers:
Content-Range: 0-393/394
Content-Type: application/octet-stream

\n

 

\n

- name: PUSH WAF

\n

uri:

\n

url: \"https://{{ ansible_host }}/mgmt/tm/asm/tasks/import-policy\"

\n

method: POST

\n

body: \"{{ lookup('template','asm_config.json', split_lines=False) }}\"

\n

status_code: 201

\n

timeout: 300

\n

body_format: json

\n

force_basic_auth: yes

\n

user: \"{{ ansible_user }}\"

\n

password: \"{{ ansible_httpapi_password }}\"

\n

validate_certs: no

\n

headers:
Content-Type: application/javascript

","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"203","kudosSumWeight":0,"repliesCount":0,"postTime":"2023-02-06T04:54:30.417-08:00","lastPublishTime":"2023-02-07T04:17:09.304-08:00","metrics":{"__typename":"MessageMetrics","views":1911},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"TKB_REPLY","eventPath":"category:Articles/community:zihoc95639board:TechnicalArticles/message:289251/message:309802","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"customFields":[],"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/cmstMzktSU1FU1l6\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/cmstMzktSU1FU1l6","height":0,"width":0,"mimeType":"image/svg+xml"},"Rank:rank:39":{"__typename":"Rank","id":"rank:39","position":16,"name":"Altocumulus","color":"CCCCCC","icon":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/cmstMzktSU1FU1l6\"}"},"rankStyle":"FILLED"},"User:user:190835":{"__typename":"User","id":"user:190835","uid":190835,"login":"B_Earp","biography":null,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2012-08-16T01:00:00.000-07:00"},"deleted":false,"email":"","avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/m_assets/avatars/default/avatar-6.svg?time=0"},"rank":{"__ref":"Rank:rank:39"},"entityType":"USER","eventPath":"community:zihoc95639/user:190835"},"ModerationData:moderation_data:335040":{"__typename":"ModerationData","id":"moderation_data:335040","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"TkbReplyMessage:message:335040":{"__typename":"TkbReplyMessage","author":{"__ref":"User:user:190835"},"id":"message:335040","revisionNum":1,"uid":335040,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Tkb:board:TechnicalArticles"},"parent":{"__ref":"TkbTopicMessage:message:289251"},"conversation":{"__ref":"Conversation:conversation:289251"},"subject":"Re: Advanced WAF v16.0 - Declarative API","moderationData":{"__ref":"ModerationData:moderation_data:335040"},"body":"

Using the uri option in the declaration it is unclear how the policy arrives at the BIG-IP.

 \"My_ASM_Policy\": {\n        \"class\": \"WAF_Policy\",\n        \"url\": \"https://example.com/asm-policy.xml\",\n        \"ignoreChanges\": true

How does the data from that url get uploaded/downloaded to the big-ip.

  1. PUSH: Does the AS3 software include the json data from that url as part of it's declaration?
  2. PULL: Does the BIG-IP download the json from that url?
","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"203","kudosSumWeight":0,"repliesCount":0,"postTime":"2024-10-03T06:56:43.549-07:00","lastPublishTime":"2024-10-03T06:56:43.549-07:00","metrics":{"__typename":"MessageMetrics","views":11},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"TKB_REPLY","eventPath":"category:Articles/community:zihoc95639board:TechnicalArticles/message:289251/message:335040","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"customFields":[],"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"CachedAsset:text:en_US-components/messages/MessageSubject-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageSubject-1740415735000","value":{"noSubject":"(no subject)"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBody-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBody-1740415735000","value":{"showMessageBody":"Show More","mentionsErrorTitle":"{mentionsType, select, board {Board} user {User} message {Message} other {}} No Longer Available","mentionsErrorMessage":"The {mentionsType} you are trying to view has been removed from the community.","videoProcessing":"Video is being processed. Please try again in a few minutes.","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCustomFields-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCustomFields-1740415735000","value":{"CustomField.default.label":"Value of {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageRevision-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageRevision-1740415735000","value":{"lastUpdatedDatePublished":"{publishCount, plural, one{Published} other{Updated}} {date}","lastUpdatedDateDraft":"Created {date}","version":"Version {major}.{minor}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyButton-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyButton-1740415735000","value":{"repliesCount":"{count}","title":"Reply","title@board:BLOG@message:root":"Comment","title@board:TKB@message:root":"Comment","title@board:IDEA@message:root":"Comment","title@board:OCCASION@message:root":"Comment"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageAuthorBio-1740415735000","value":{"sendMessage":"Send Message","actionMessage":"Follow this blog board to get notified when there's new activity","coAuthor":"CO-PUBLISHER","contributor":"CONTRIBUTOR","userProfile":"View Profile","iconlink":"Go to {name} {type}"},"localOverride":false},"CachedAsset:text:en_US-components/guides/GuideBottomNavigation-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/guides/GuideBottomNavigation-1740415735000","value":{"nav.label":"Previous/Next Page","nav.previous":"Previous","nav.next":"Next"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserLink-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserLink-1740415735000","value":{"authorName":"View Profile: {author}","anonymous":"Anonymous"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserRank-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserRank-1740415735000","value":{"rankName":"{rankName}","userRank":"Author rank {rankName}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTime-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTime-1740415735000","value":{"postTime":"Published: {time}","lastPublishTime":"Last Update: {time}","conversation.lastPostingActivityTime":"Last posting activity time: {time}","conversation.lastPostTime":"Last post time: {time}","moderationData.rejectTime":"Rejected time: {time}"},"localOverride":false},"CachedAsset:text:en_US-components/customComponent/CustomComponent-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/customComponent/CustomComponent-1740415735000","value":{"errorMessage":"Error rendering component id: {customComponentId}","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserAvatar-1740415735000","value":{"altText":"{login}'s avatar","altTextGeneric":"User's avatar"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/ranks/UserRankLabel-1740415735000","value":{"altTitle":"Icon for {rankName} rank"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserRegistrationDate-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserRegistrationDate-1740415735000","value":{"noPrefix":"{date}","withPrefix":"Joined {date}"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1740415735000":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagView/TagViewChip-1740415735000","value":{"tagLabelName":"Tag name {tagName}"},"localOverride":false}}}},"page":"/kbs/TkbMessagePage/TkbMessagePage","query":{"guideId":"guide:5","boardId":"technicalarticles","messageSubject":"advanced-waf-v16-0---declarative-api","messageId":"289251"},"buildId":"G6LFdF6Y8sb5g8rZyM3sC","runtimeConfig":{"buildInformationVisible":false,"logLevelApp":"info","logLevelMetrics":"info","openTelemetryClientEnabled":false,"openTelemetryConfigName":"f5","openTelemetryServiceVersion":"25.2.0","openTelemetryUniverse":"prod","openTelemetryCollector":"http://localhost:4318","openTelemetryRouteChangeAllowedTime":"5000","apolloDevToolsEnabled":false,"inboxMuteWipFeatureEnabled":false},"isFallback":false,"isExperimentalCompile":false,"dynamicIds":["./components/customComponent/CustomComponent/CustomComponent.tsx","./components/community/Navbar/NavbarWidget.tsx","./components/community/Breadcrumb/BreadcrumbWidget.tsx","./components/tkbs/TkbArticleWidget/TkbArticleWidget.tsx","./components/messages/MessageView/MessageViewStandard/MessageViewStandard.tsx","./components/messages/ThreadedReplyList/ThreadedReplyList.tsx","./components/customComponent/CustomComponentContent/TemplateContent.tsx","../shared/client/components/common/List/UnstyledList/UnstyledList.tsx","./components/messages/MessageView/MessageView.tsx","./components/customComponent/CustomComponentContent/HtmlContent.tsx","./components/customComponent/CustomComponentContent/CustomComponentScripts.tsx","../shared/client/components/common/List/UnwrappedList/UnwrappedList.tsx","./components/tags/TagView/TagView.tsx","./components/tags/TagView/TagViewChip/TagViewChip.tsx"],"appGip":true,"scriptLoader":[]}