API Security: How to implement API Access Control with F5
Introduction
Organizations use API as a de facto standard to connect services and transfer data. Gartner predicts that by 2022, API attacks will become the most-frequent attack vector, causing data breaches for enterprise web applications.
According to Gartner (table below), providing effective security for API falls into two broad aspects: API Threat Protection and API Access Control.
API Threat Protection means detecting and blocking attacks on API, while API Access Control means controlling which application and users can access API.
F5 has a couple of product offerings that can address either aspect of API security as defined by Gartner.
Specifically, the Web Application and API Protection (WAAP) service offered via the F5 Distributed Cloud (F5 XC) addresses API Threat Protection and is consumed as SaaS. Please take a high-level overview here.
For API Access Control, the good old and ever evolving F5 BIG-IP Access Policy Manager (APM) rises again to the occasion. In this article, I will focus at length on how we can leverage BIG-IP APM to provide API access control.
Pre-words
Before I get started, I would like to acknowledge the excellent work and coverage on this topic already done by James Lee, who has authored a three part article series titled ‘Advanced API Access Control with BIG-IP APM’. James has also provided tremendous assistance for my work effort while I was researching this very topic. THANK YOU, James!
The purpose of this article is to hit the topic really hard one more time, hoping to further uncover the intricacies associated with the realm of API access control.
Mechanism for API Access Control
The OAuth 2.0 protocol is broadly used as a mechanism to provide API access control. It provides functions such as authentication, as well as authorization, which are pivotal to implementing control on API access.
The OAuth 2.0 specification defines four roles, and it is the four roles working together to get the job done.
I won’t bore you with the specs itself, in layman’s terms, I have described them as below.
Resource Owner: This is the end user. e.g., you and I
Resource Server: This is the API server that also understands OAuth. In many scenarios, API servers only know how to serve API requests, one way to add OAuth capability is via offloading that function to something else. Hint: BIG-IP APM
Client: This is the application that makes API calls to your API server. The confusion part is Client here refers to OAuth Client. The application itself is an API client and for it to also act as an OAuth client, it needs to add OAuth Client function as well
Authorization Server: This is who OAuth Client talks to to get an access token. The Authorization Server usually authenticates the OAuth Client prior to giving it the token.
A high-level traffic flow would be like this,
Client (Your application with OAuth component acting as OAuth Client) reaches out to the Authorization Server for an access token
Authorization Server checks the incoming request from Client, usually authenticates the Client as well, if successful, gives Client an access token.
Client sends the API request, with the access token included, to the Resource Server
Resource Server verifies the access token and answers the API request
Note: There are several variations to the above flow, depending upon the type of the application and associated capabilities (e.g., browser, mobile or machine based). The above flow is most suited to non-interactive machine-to-machine API traffic.
API Access Control with BIG-IP APM
If you are looking at adding API Access Control to your API servers that do not understand OAuth, leveraging the BIG-IP APM is surely a great way to bring in that capability.
In addition, the Web Application and API Protection as a SaaS offering brings in API Threat Protection capability, which means you effectively kill two birds with one stone and can completely nail API security with a consolidated single vendor solution.
In the succeeding sections, I will walk through the BIG-IP APM configuration, allowing it to function as an Authorization Server, as well as offloading Resource Server capability for your API servers.
Authorization Server
The role of Authorization Server is to provide an access token to Client if things check out. The kind of things that must check out is dependent upon the OAuth grant type being implemented. The popular grant types include the ones listed below but are not limited to these four:
Authorization Code grant
Implicit grant
Resource Owner Password Credential (ROPC) grant
Client Credentials grant
The APM supports all four grant types, with the Client Credentials grant requiring a bit of iRule magic.
Step-wise, we first create a LB VIP, and then attach it with an access profile that turns it into an Authorization Server.
Prior to creating the access profile, we must create associated prerequisites.
Under Access => Federation => OAuth Authorization Server, create a ‘Client Application’ and a ‘Resource Server’, followed by creating an ‘OAuth Profile’ that binds the ‘Client Application’ and ‘Resource Server’ together. The logic is that the authorization server needs to know its registered client application, as well as the participating resource server. This allows for Resource Server reaching out to Authorization Server for token validation as part of the flow.
For this specific article, we select ‘Resource Owner Password Credentials’ (ROPC) grant type. There are plenty of resources on the Internet that talk about these different grants in great details but for the purpose of non-interactive machine to machine API traffic, the most suited grant type is Client Credentials.
The BIG-IP APM does not natively handle Client Credentials grant type. However, it is very similar to ROPC grant type, which is natively handled. The idea is that we let the client application use ‘Client Credentials’ grant when talking to the Authorization Server, and once traffic arrives at the APM, we use an iRule to convert it to ROPC so the APM can process that traffic.
ROPC requires that the Client (API client application) to send in username, password, client_id and client_secret. Client Credentials only requires client_id and client_secret to be sent.
With Client Credentials grant, since no username or password is needed, the iRule simply adds them as dummies so the request looks like a ROPC grant request.
Below are a couple of screenshots for your reference, as well as the iRule that you can readily use.
Figure 1 - Create a Client Application
Figure 2 - Create a Resource Server
This iRule below is based on an excellent solution shared by DevCentral user youssef1. This is all his work, and I am simply referencing it here for this article.
when HTTP_REQUEST {
set grant_type null
if { ( [string tolower [HTTP::uri]] equals "/f5-oauth2/v1/token" ) and ( [HTTP::method] equals "POST" ) } {
set grant_type "client_credentials"
HTTP::collect [HTTP::header Content-Length]
}
}
when HTTP_REQUEST_DATA {
if {$grant_type contains "client_credentials" } {
set payload [HTTP::payload]
if { [HTTP::payload] contains "grant_type=client_credentials" } {
# log local0. "Old Payload: [HTTP::payload]"
HTTP::payload replace 0 [HTTP::header Content-Length] [string map {"grant_type=client_credentials" "grant_type=password&username=xxx&password=xxx"} $payload]
# log local0. "New Payload: [HTTP::payload]"
HTTP::release
}
}
}
The above concludes the Authorization Server configuration.
Resource Server
If your API servers do not understand OAuth, you can offload OAuth function to the BIG-IP APM by putting them behind it. Specifically, create a LB VIP for your API servers and attach an access profile so that together they act as a Resource Server.
The Resource Server is responsible for checking the access token presented by the Client (application) as part of its API request, if the token checks out, API request is answered, otherwise denied.
Depending on the type of the access token, if it is in the form of an opaque token, meaning it carries no information on its own, the Resource Server will need to present this token to the Authorization Server and in return it gets the information.
If the access token is in the form of a JSON Web Token (JWT), the Resource Server verifies the signature of the token and then reads the embedded information off it. The Resource Server won’t need to reach out to the Authorization Server in this case.
The APM supports both opaque token and JWT token, and by default the opaque token is used. The opaque token provides certain benefits such as it is revokable, hides the actual information and is probably smaller in size when compared to a JWT token. The downside is the Resource Server will need to talk to the Authorization Server for token validation and introspection. The JWT token does not need the extra roundtrip of communication, and therefore cuts down on latency, due to information is already embedded inside the token. However, it may not be suitable if you are transmitting sensitive information or require revoking a token after one is issued.
Just as a side note, the BIG-IP APM can receive an opaque token, validates it against an external party, and then issue a JWT token downstream, as part of its SSO capability. This is not related to our use case here, but I will mention it for awareness.
To offload Resource Server function to the BIG-IP APM, go to Access => Federation => OAuth Client / Resource Server, create a ‘Provider’ and an ‘OAuth Server’ configuration.
The idea is that with a provider, it has all the information on Authorization Server, so Resource Server knows how to communicate with it. E.g., what URL to hit when validating a token
Figure 4 - Create a Provider
https://as.abbagmbh.de points to the LB VIP we created earlier on for the Authorization Server.
When creating the ‘OAuth Server’ configuration, fill in the ‘Resource Server ID’ and ‘Resource Server Secret’ values by copying them from the previous step when we configured under the ‘OAuth Authorization Server’ menu.
Figure 5 - Create an OAuth Server (Resource Server)
The above concludes the Resource Server configuration.
Access Profiles
We need to create two access profiles, one for Authorization Server and the other for Resource Server.
For Authorization Server, select ‘LTM-APM’ type, associate an OAuth Profile created earlier and leave the rest as default.
The Access policy shown below is simple, the result is that an access token will be issued if client_id and client_secret in the request check out.
Figure 6 – Access policy for Authorization Server
For Resource Server, select ‘LTM-APM’ type and leave the rest as default.
For the access policy, use ‘OAuth Scope’ type (I renamed it as OAuth Token Check), set token validation mode as ‘external’, select the Resource Server we created earlier on.
Figure 7 - Resource Server access policy
Figure 8 - Token validation
The above concludes a very basic setup of Resource Server.
Scope
In OAuth 2.0, scope is used to limit the level of access granted to an access token. For instance, you can use a ‘READ’ scope that allows API calls via HTTP GET, and a ‘WRITE’ scope that allows HTTP POST API calls.
The full list of supported scopes should be communicated to the Client as defined on the Authorization Server.
When Client is asking for an access token, it will include scope as part of the request parameter. If scope is not included, the Authorization Server either process the request using a pre-defined default value or fail the request indicating an invalid scope.
Once access token is issued with the requested scope, it is sent to the Resource Server and it is incumbent upon the Resource Server to do something about it.
Take the prior ‘READ’ and ‘WRITE’ scopes as an example, the Resource Server will need to block POST API calls if the scope is ‘READ’.
Scope in essense is a literal string of key value pair, the string itself is defined per implementation. Once it is defined on the Authorization Server, it needs to be communicated to the Client, so the Client will know what scopes are available to use; it also needs to be communicated to the Resource Server as well, as it will implement enforcement per design.
In this article, I am only introducing scope at a conceptual level to keep it short.
The BIG-IP APM does however provide a full set of functions to support scope management.
Testing
So far, we have created two LB VIP’s, one as an Authorization Server, and the other as a Resource Server.
Figure 9 - LB VIP
We created two access profiles, with each attached to the associated LB VIP.
Figure 14 - Postman send API request with access token
The API server is programmed to print out the API request itself.
Figure 15 - API server response
On the APM, if you go to Access => Overview => OAuth Reports => Tokens, you will see the token as ‘ACTIVE’.
Figure 16 - APM OAuth Token report
Conclusion
In this article, we started at high level on what comprises API security defined by Gartner, which comes down to API Threat Protection and API Access Control.
F5 has WAAP as a SaaS offering to address API Threat Protection and the BIG-IP APM provides a highly capable solution for API Access Control.
I have explained the concept around API Access Control using OAuth 2.0, as well as a specific use case on non-interactive machine to machine API access control.
I hope you will find this article of value and please reach out with comments or your sales team if you have a need around implementing API Security.
"}},"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:306666\"],\"name\":\"TkbMessagePage\",\"props\":{},\"url\":\"https://community.f5.com/kb/technicalarticles/api-security-how-to-implement-api-access-control-with-f5/306666\"}}})":{"__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:306666\"],\"name\":\"TkbMessagePage\",\"props\":{},\"url\":\"https://community.f5.com/kb/technicalarticles/api-security-how-to-implement-api-access-control-with-f5/306666\"}}})":{"__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\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/QueryHandler\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"components/community/NavbarDropdownToggle\"]})":[{"__ref":"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageView/MessageViewStandard\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageView/MessageViewStandard-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/ThreadedReplyList\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/ThreadedReplyList-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageReplyCallToAction\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageReplyCallToAction-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageSubject\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageSubject-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageBody\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageBody-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageCustomFields\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageCustomFields-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageRevision\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageRevision-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageReplyButton\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageReplyButton-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageAuthorBio\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"components/guides/GuideBottomNavigation\"]})":[{"__ref":"CachedAsset:text:en_US-components/guides/GuideBottomNavigation-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"components/customComponent/CustomComponent\"]})":[{"__ref":"CachedAsset:text:en_US-components/customComponent/CustomComponent-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserLink\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserLink-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserRank\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserRank-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserRegistrationDate\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserRegistrationDate-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"components/tags/TagView/TagViewChip\"]})":[{"__ref":"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1744046279002"}],"cachedText({\"lastModified\":\"1744046279002\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/ranks/UserRankLabel\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1744046279002"}]},"CachedAsset:pages-1743756125778":{"__typename":"CachedAsset","id":"pages-1743756125778","value":[{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"HowDoI.GetInvolved.MvpProgram","type":"COMMUNITY","urlPath":"/c/how-do-i/get-involved/mvp-program","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"BlogViewAllPostsPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId/all-posts/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"CasePortalPage","type":"CASE_PORTAL","urlPath":"/caseportal","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"CreateGroupHubPage","type":"GROUP_HUB","urlPath":"/groups/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"CaseViewPage","type":"CASE_DETAILS","urlPath":"/case/:caseId/:caseNumber","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"InboxPage","type":"COMMUNITY","urlPath":"/inbox","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"HowDoI.GetInvolved.AdvocacyProgram","type":"COMMUNITY","urlPath":"/c/how-do-i/get-involved/advocacy-program","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"HowDoI.GetHelp.NonCustomer","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/non-customer","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"HelpFAQPage","type":"COMMUNITY","urlPath":"/help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"HowDoI.GetHelp.F5Customer","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/f5-customer","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"IdeaMessagePage","type":"IDEA_POST","urlPath":"/idea/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"IdeaViewAllIdeasPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/all-ideas/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"LoginPage","type":"USER","urlPath":"/signin","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"BlogPostPage","type":"BLOG","urlPath":"/category/:categoryId/blogs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"HowDoI.GetInvolved","type":"COMMUNITY","urlPath":"/c/how-do-i/get-involved","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"HowDoI.Learn","type":"COMMUNITY","urlPath":"/c/how-do-i/learn","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1739501996000,"localOverride":null,"page":{"id":"Test","type":"CUSTOM","urlPath":"/custom-test-2","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"ThemeEditorPage","type":"COMMUNITY","urlPath":"/designer/themes","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"TkbViewAllArticlesPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId/all-articles/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"OccasionEditPage","type":"EVENT","urlPath":"/event/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"OAuthAuthorizationAllowPage","type":"USER","urlPath":"/auth/authorize/allow","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"PageEditorPage","type":"COMMUNITY","urlPath":"/designer/pages","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"PostPage","type":"COMMUNITY","urlPath":"/category/:categoryId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"ForumBoardPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"TkbBoardPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"EventPostPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"UserBadgesPage","type":"COMMUNITY","urlPath":"/users/:login/:userId/badges","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"GroupHubMembershipAction","type":"GROUP_HUB","urlPath":"/membership/join/:nodeId/:membershipType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"MaintenancePage","type":"COMMUNITY","urlPath":"/maintenance","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"IdeaReplyPage","type":"IDEA_REPLY","urlPath":"/idea/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"UserSettingsPage","type":"USER","urlPath":"/mysettings/:userSettingsTab","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"GroupHubsPage","type":"GROUP_HUB","urlPath":"/groups","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"ForumPostPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"OccasionRsvpActionPage","type":"OCCASION","urlPath":"/event/:boardId/:messageSubject/:messageId/rsvp/:responseType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"VerifyUserEmailPage","type":"USER","urlPath":"/verifyemail/:userId/:verifyEmailToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"AllOccasionsPage","type":"OCCASION","urlPath":"/category/:categoryId/events/:boardId/all-events/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"EventBoardPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"TkbReplyPage","type":"TKB_REPLY","urlPath":"/kb/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"IdeaBoardPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"CommunityGuideLinesPage","type":"COMMUNITY","urlPath":"/communityguidelines","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"CaseCreatePage","type":"SALESFORCE_CASE_CREATION","urlPath":"/caseportal/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"TkbEditPage","type":"TKB","urlPath":"/kb/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"ForgotPasswordPage","type":"USER","urlPath":"/forgotpassword","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"IdeaEditPage","type":"IDEA","urlPath":"/idea/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"TagPage","type":"COMMUNITY","urlPath":"/tag/:tagName","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"BlogBoardPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"OccasionMessagePage","type":"OCCASION_TOPIC","urlPath":"/event/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"ManageContentPage","type":"COMMUNITY","urlPath":"/managecontent","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"ClosedMembershipNodeNonMembersPage","type":"GROUP_HUB","urlPath":"/closedgroup/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"HowDoI.GetHelp.Community","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/community","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"CommunityPage","type":"COMMUNITY","urlPath":"/","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"HowDoI.GetInvolved.ContributeCode","type":"COMMUNITY","urlPath":"/c/how-do-i/get-involved/contribute-code","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"ForumMessagePage","type":"FORUM_TOPIC","urlPath":"/discussions/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"IdeaPostPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"BlogMessagePage","type":"BLOG_ARTICLE","urlPath":"/blog/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"RegistrationPage","type":"USER","urlPath":"/register","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"EditGroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"ForumEditPage","type":"FORUM","urlPath":"/discussions/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"ResetPasswordPage","type":"USER","urlPath":"/resetpassword/:userId/:resetPasswordToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"TkbMessagePage","type":"TKB_ARTICLE","urlPath":"/kb/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"HowDoI.Learn.AboutIrules","type":"COMMUNITY","urlPath":"/c/how-do-i/learn/about-irules","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"BlogEditPage","type":"BLOG","urlPath":"/blog/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"HowDoI.GetHelp.F5Support","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/f5-support","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"ManageUsersPage","type":"USER","urlPath":"/users/manage/:tab?/:manageUsersTab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"ForumReplyPage","type":"FORUM_REPLY","urlPath":"/discussions/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"PrivacyPolicyPage","type":"COMMUNITY","urlPath":"/privacypolicy","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"NotificationPage","type":"COMMUNITY","urlPath":"/notifications","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"UserPage","type":"USER","urlPath":"/users/:login/:userId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"HealthCheckPage","type":"COMMUNITY","urlPath":"/health","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"OccasionReplyPage","type":"OCCASION_REPLY","urlPath":"/event/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"ManageMembersPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/manage/:tab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"SearchResultsPage","type":"COMMUNITY","urlPath":"/search","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"BlogReplyPage","type":"BLOG_REPLY","urlPath":"/blog/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"GroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"TermsOfServicePage","type":"COMMUNITY","urlPath":"/termsofservice","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"HowDoI.GetHelp","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"HowDoI.GetHelp.SecurityIncident","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/security-incident","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"CategoryPage","type":"CATEGORY","urlPath":"/category/:categoryId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"ForumViewAllTopicsPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/all-topics/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"TkbPostPage","type":"TKB","urlPath":"/category/:categoryId/kbs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"localOverride":null,"page":{"id":"GroupHubPostPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743756125778,"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"},"tagProperties":{"__typename":"TagNodeProperties","tagsEnabled":{"__typename":"PolicyResult","failureReason":null}},"requireTags":true,"tagType":"FREEFORM_AND_PRESET"},"Rank:rank:27":{"__typename":"Rank","id":"rank:27","position":2,"name":"Ret. Employee","color":"949494","icon":null,"rankStyle":"OUTLINE"},"User:user:49440":{"__typename":"User","id":"user:49440","uid":49440,"login":"Chris_Zhang","deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/m_assets/avatars/default/avatar-1.svg?time=0"},"rank":{"__ref":"Rank:rank:27"},"email":"","messagesCount":31,"biography":null,"topicsCount":10,"kudosReceivedCount":38,"kudosGivenCount":15,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2019-05-15T17:51:49.000-07:00","confirmEmailStatus":null},"followersCount":null,"solutionsCount":0},"TkbTopicMessage:message:306666":{"__typename":"TkbTopicMessage","uid":306666,"subject":"API Security: How to implement API Access Control with F5","id":"message:306666","revisionNum":9,"repliesCount":0,"author":{"__ref":"User:user:49440"},"depth":0,"hasGivenKudo":false,"helpful":null,"board":{"__ref":"Tkb:board:TechnicalArticles"},"conversation":{"__ref":"Conversation:conversation:306666"},"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:306666"},"teaser":"
Per Gartner, API Security comprises two aspects: API Threat Protection and API Access Control. API Threat Protection is addressed with measures such as API L7 firewall, bot protection, DDoS mitigation, etc. API Access Control is most comprehensively addressed via OAuth 2.0. This article will see our attention focused on API Access Control, and how F5 APM can be leverage for this universal challenge when protecting API.
","body":"
\n
Introduction
\n
Organizations use API as a de facto standard to connect services and transfer data. Gartner predicts that by 2022, API attacks will become the most-frequent attack vector, causing data breaches for enterprise web applications.
\n
According to Gartner (table below), providing effective security for API falls into two broad aspects: API Threat Protection and API Access Control.
\n
\n
API Threat Protection means detecting and blocking attacks on API, while API Access Control means controlling which application and users can access API.
\n
F5 has a couple of product offerings that can address either aspect of API security as defined by Gartner.
\n
Specifically, the Web Application and API Protection (WAAP) service offered via the F5 Distributed Cloud (F5 XC) addresses API Threat Protection and is consumed as SaaS. Please take a high-level overview here.
\n
For API Access Control, the good old and ever evolving F5 BIG-IP Access Policy Manager (APM) rises again to the occasion. In this article, I will focus at length on how we can leverage BIG-IP APM to provide API access control.
\n
Pre-words
\n
Before I get started, I would like to acknowledge the excellent work and coverage on this topic already done by James Lee, who has authored a three part article series titled ‘Advanced API Access Control with BIG-IP APM’. James has also provided tremendous assistance for my work effort while I was researching this very topic. THANK YOU, James!
\n
The purpose of this article is to hit the topic really hard one more time, hoping to further uncover the intricacies associated with the realm of API access control.
\n
Mechanism for API Access Control
\n
The OAuth 2.0 protocol is broadly used as a mechanism to provide API access control. It provides functions such as authentication, as well as authorization, which are pivotal to implementing control on API access.
\n
The OAuth 2.0 specification defines four roles, and it is the four roles working together to get the job done.
\n
I won’t bore you with the specs itself, in layman’s terms, I have described them as below.
\n
Resource Owner: This is the end user. e.g., you and I
\n
Resource Server: This is the API server that also understands OAuth. In many scenarios, API servers only know how to serve API requests, one way to add OAuth capability is via offloading that function to something else. Hint: BIG-IP APM
\n
Client: This is the application that makes API calls to your API server. The confusion part is Client here refers to OAuth Client. The application itself is an API client and for it to also act as an OAuth client, it needs to add OAuth Client function as well
\n
Authorization Server: This is who OAuth Client talks to to get an access token. The Authorization Server usually authenticates the OAuth Client prior to giving it the token.
\n
A high-level traffic flow would be like this,
\n\n
Client (Your application with OAuth component acting as OAuth Client) reaches out to the Authorization Server for an access token
\n
Authorization Server checks the incoming request from Client, usually authenticates the Client as well, if successful, gives Client an access token.
\n
Client sends the API request, with the access token included, to the Resource Server
\n
Resource Server verifies the access token and answers the API request
\n\n
Note: There are several variations to the above flow, depending upon the type of the application and associated capabilities (e.g., browser, mobile or machine based). The above flow is most suited to non-interactive machine-to-machine API traffic.
\n
API Access Control with BIG-IP APM
\n
If you are looking at adding API Access Control to your API servers that do not understand OAuth, leveraging the BIG-IP APM is surely a great way to bring in that capability.
\n
In addition, the Web Application and API Protection as a SaaS offering brings in API Threat Protection capability, which means you effectively kill two birds with one stone and can completely nail API security with a consolidated single vendor solution.
\n
In the succeeding sections, I will walk through the BIG-IP APM configuration, allowing it to function as an Authorization Server, as well as offloading Resource Server capability for your API servers.
\n
Authorization Server
\n
The role of Authorization Server is to provide an access token to Client if things check out. The kind of things that must check out is dependent upon the OAuth grant type being implemented. The popular grant types include the ones listed below but are not limited to these four:
\n\n
Authorization Code grant
\n
Implicit grant
\n
Resource Owner Password Credential (ROPC) grant
\n
Client Credentials grant
\n\n
The APM supports all four grant types, with the Client Credentials grant requiring a bit of iRule magic.
\n
Step-wise, we first create a LB VIP, and then attach it with an access profile that turns it into an Authorization Server.
\n
Prior to creating the access profile, we must create associated prerequisites.
\n
Under Access => Federation => OAuth Authorization Server, create a ‘Client Application’ and a ‘Resource Server’, followed by creating an ‘OAuth Profile’ that binds the ‘Client Application’ and ‘Resource Server’ together. The logic is that the authorization server needs to know its registered client application, as well as the participating resource server. This allows for Resource Server reaching out to Authorization Server for token validation as part of the flow.
\n
For this specific article, we select ‘Resource Owner Password Credentials’ (ROPC) grant type. There are plenty of resources on the Internet that talk about these different grants in great details but for the purpose of non-interactive machine to machine API traffic, the most suited grant type is Client Credentials.
\n
The BIG-IP APM does not natively handle Client Credentials grant type. However, it is very similar to ROPC grant type, which is natively handled. The idea is that we let the client application use ‘Client Credentials’ grant when talking to the Authorization Server, and once traffic arrives at the APM, we use an iRule to convert it to ROPC so the APM can process that traffic.
\n
ROPC requires that the Client (API client application) to send in username, password, client_id and client_secret. Client Credentials only requires client_id and client_secret to be sent.
\n
With Client Credentials grant, since no username or password is needed, the iRule simply adds them as dummies so the request looks like a ROPC grant request.
\n
Below are a couple of screenshots for your reference, as well as the iRule that you can readily use.
\n
\n
Figure 1 - Create a Client Application
\n
\n
Figure 2 - Create a Resource Server
\n
This iRule below is based on an excellent solution shared by DevCentral user youssef1. This is all his work, and I am simply referencing it here for this article.
\n
when HTTP_REQUEST {\n\n set grant_type null\n\n if { ( [string tolower [HTTP::uri]] equals \"/f5-oauth2/v1/token\" ) and ( [HTTP::method] equals \"POST\" ) } {\n set grant_type \"client_credentials\"\n HTTP::collect [HTTP::header Content-Length]\n }\n\n}\n\nwhen HTTP_REQUEST_DATA {\n\n if {$grant_type contains \"client_credentials\" } {\n set payload [HTTP::payload]\n\n if { [HTTP::payload] contains \"grant_type=client_credentials\" } {\n # log local0. \"Old Payload: [HTTP::payload]\"\n HTTP::payload replace 0 [HTTP::header Content-Length] [string map {\"grant_type=client_credentials\" \"grant_type=password&username=xxx&password=xxx\"} $payload]\n # log local0. \"New Payload: [HTTP::payload]\"\n HTTP::release\n }\n }\n}
\n
The above concludes the Authorization Server configuration.
\n
Resource Server
\n
If your API servers do not understand OAuth, you can offload OAuth function to the BIG-IP APM by putting them behind it. Specifically, create a LB VIP for your API servers and attach an access profile so that together they act as a Resource Server.
\n
The Resource Server is responsible for checking the access token presented by the Client (application) as part of its API request, if the token checks out, API request is answered, otherwise denied.
\n
Depending on the type of the access token, if it is in the form of an opaque token, meaning it carries no information on its own, the Resource Server will need to present this token to the Authorization Server and in return it gets the information.
\n
If the access token is in the form of a JSON Web Token (JWT), the Resource Server verifies the signature of the token and then reads the embedded information off it. The Resource Server won’t need to reach out to the Authorization Server in this case.
\n
The APM supports both opaque token and JWT token, and by default the opaque token is used. The opaque token provides certain benefits such as it is revokable, hides the actual information and is probably smaller in size when compared to a JWT token. The downside is the Resource Server will need to talk to the Authorization Server for token validation and introspection. The JWT token does not need the extra roundtrip of communication, and therefore cuts down on latency, due to information is already embedded inside the token. However, it may not be suitable if you are transmitting sensitive information or require revoking a token after one is issued.
\n
Just as a side note, the BIG-IP APM can receive an opaque token, validates it against an external party, and then issue a JWT token downstream, as part of its SSO capability. This is not related to our use case here, but I will mention it for awareness.
\n
To offload Resource Server function to the BIG-IP APM, go to Access => Federation => OAuth Client / Resource Server, create a ‘Provider’ and an ‘OAuth Server’ configuration.
\n
The idea is that with a provider, it has all the information on Authorization Server, so Resource Server knows how to communicate with it. E.g., what URL to hit when validating a token
\n
\n
Figure 4 - Create a Provider
\n
https://as.abbagmbh.de points to the LB VIP we created earlier on for the Authorization Server.
\n
When creating the ‘OAuth Server’ configuration, fill in the ‘Resource Server ID’ and ‘Resource Server Secret’ values by copying them from the previous step when we configured under the ‘OAuth Authorization Server’ menu.
\n
\n
Figure 5 - Create an OAuth Server (Resource Server)
\n
The above concludes the Resource Server configuration.
\n
Access Profiles
\n
We need to create two access profiles, one for Authorization Server and the other for Resource Server.
\n
For Authorization Server, select ‘LTM-APM’ type, associate an OAuth Profile created earlier and leave the rest as default.
\n
The Access policy shown below is simple, the result is that an access token will be issued if client_id and client_secret in the request check out.
\n
\n
\n
\n
\n
Figure 6 – Access policy for Authorization Server
\n
For Resource Server, select ‘LTM-APM’ type and leave the rest as default.
\n
For the access policy, use ‘OAuth Scope’ type (I renamed it as OAuth Token Check), set token validation mode as ‘external’, select the Resource Server we created earlier on.
\n
Figure 7 - Resource Server access policy
\n
\n
Figure 8 - Token validation
\n
The above concludes a very basic setup of Resource Server.
\n
Scope
\n
In OAuth 2.0, scope is used to limit the level of access granted to an access token. For instance, you can use a ‘READ’ scope that allows API calls via HTTP GET, and a ‘WRITE’ scope that allows HTTP POST API calls.
\n
The full list of supported scopes should be communicated to the Client as defined on the Authorization Server.
\n
When Client is asking for an access token, it will include scope as part of the request parameter. If scope is not included, the Authorization Server either process the request using a pre-defined default value or fail the request indicating an invalid scope.
\n
Once access token is issued with the requested scope, it is sent to the Resource Server and it is incumbent upon the Resource Server to do something about it.
\n
Take the prior ‘READ’ and ‘WRITE’ scopes as an example, the Resource Server will need to block POST API calls if the scope is ‘READ’.
\n
Scope in essense is a literal string of key value pair, the string itself is defined per implementation. Once it is defined on the Authorization Server, it needs to be communicated to the Client, so the Client will know what scopes are available to use; it also needs to be communicated to the Resource Server as well, as it will implement enforcement per design.
\n
In this article, I am only introducing scope at a conceptual level to keep it short.
\n
The BIG-IP APM does however provide a full set of functions to support scope management.
\n
Testing
\n
So far, we have created two LB VIP’s, one as an Authorization Server, and the other as a Resource Server.
\n
\n
Figure 9 - LB VIP
\n
We created two access profiles, with each attached to the associated LB VIP.
Figure 14 - Postman send API request with access token
\n
The API server is programmed to print out the API request itself.
\n
\n
Figure 15 - API server response
\n
On the APM, if you go to Access => Overview => OAuth Reports => Tokens, you will see the token as ‘ACTIVE’.
\n
\n
Figure 16 - APM OAuth Token report
\n
Conclusion
\n
In this article, we started at high level on what comprises API security defined by Gartner, which comes down to API Threat Protection and API Access Control.
\n
F5 has WAAP as a SaaS offering to address API Threat Protection and the BIG-IP APM provides a highly capable solution for API Access Control.
\n
I have explained the concept around API Access Control using OAuth 2.0, as well as a specific use case on non-interactive machine to machine API access control.
\n
I hope you will find this article of value and please reach out with comments or your sales team if you have a need around implementing API Security.
\n
","body@stringLength":"28448","rawBody":"
\n
Introduction
\n
Organizations use API as a de facto standard to connect services and transfer data. Gartner predicts that by 2022, API attacks will become the most-frequent attack vector, causing data breaches for enterprise web applications.
\n
According to Gartner (table below), providing effective security for API falls into two broad aspects: API Threat Protection and API Access Control.
\n
\n
API Threat Protection means detecting and blocking attacks on API, while API Access Control means controlling which application and users can access API.
\n
F5 has a couple of product offerings that can address either aspect of API security as defined by Gartner.
\n
Specifically, the Web Application and API Protection (WAAP) service offered via the F5 Distributed Cloud (F5 XC) addresses API Threat Protection and is consumed as SaaS. Please take a high-level overview here.
\n
For API Access Control, the good old and ever evolving F5 BIG-IP Access Policy Manager (APM) rises again to the occasion. In this article, I will focus at length on how we can leverage BIG-IP APM to provide API access control.
\n
Pre-words
\n
Before I get started, I would like to acknowledge the excellent work and coverage on this topic already done by James Lee, who has authored a three part article series titled ‘Advanced API Access Control with BIG-IP APM’. James has also provided tremendous assistance for my work effort while I was researching this very topic. THANK YOU, James!
\n
The purpose of this article is to hit the topic really hard one more time, hoping to further uncover the intricacies associated with the realm of API access control.
\n
Mechanism for API Access Control
\n
The OAuth 2.0 protocol is broadly used as a mechanism to provide API access control. It provides functions such as authentication, as well as authorization, which are pivotal to implementing control on API access.
\n
The OAuth 2.0 specification defines four roles, and it is the four roles working together to get the job done.
\n
I won’t bore you with the specs itself, in layman’s terms, I have described them as below.
\n
Resource Owner: This is the end user. e.g., you and I
\n
Resource Server: This is the API server that also understands OAuth. In many scenarios, API servers only know how to serve API requests, one way to add OAuth capability is via offloading that function to something else. Hint: BIG-IP APM
\n
Client: This is the application that makes API calls to your API server. The confusion part is Client here refers to OAuth Client. The application itself is an API client and for it to also act as an OAuth client, it needs to add OAuth Client function as well
\n
Authorization Server: This is who OAuth Client talks to to get an access token. The Authorization Server usually authenticates the OAuth Client prior to giving it the token.
\n
A high-level traffic flow would be like this,
\n\n
Client (Your application with OAuth component acting as OAuth Client) reaches out to the Authorization Server for an access token
\n
Authorization Server checks the incoming request from Client, usually authenticates the Client as well, if successful, gives Client an access token.
\n
Client sends the API request, with the access token included, to the Resource Server
\n
Resource Server verifies the access token and answers the API request
\n\n
Note: There are several variations to the above flow, depending upon the type of the application and associated capabilities (e.g., browser, mobile or machine based). The above flow is most suited to non-interactive machine-to-machine API traffic.
\n
API Access Control with BIG-IP APM
\n
If you are looking at adding API Access Control to your API servers that do not understand OAuth, leveraging the BIG-IP APM is surely a great way to bring in that capability.
\n
In addition, the Web Application and API Protection as a SaaS offering brings in API Threat Protection capability, which means you effectively kill two birds with one stone and can completely nail API security with a consolidated single vendor solution.
\n
In the succeeding sections, I will walk through the BIG-IP APM configuration, allowing it to function as an Authorization Server, as well as offloading Resource Server capability for your API servers.
\n
Authorization Server
\n
The role of Authorization Server is to provide an access token to Client if things check out. The kind of things that must check out is dependent upon the OAuth grant type being implemented. The popular grant types include the ones listed below but are not limited to these four:
\n\n
Authorization Code grant
\n
Implicit grant
\n
Resource Owner Password Credential (ROPC) grant
\n
Client Credentials grant
\n\n
The APM supports all four grant types, with the Client Credentials grant requiring a bit of iRule magic.
\n
Step-wise, we first create a LB VIP, and then attach it with an access profile that turns it into an Authorization Server.
\n
Prior to creating the access profile, we must create associated prerequisites.
\n
Under Access => Federation => OAuth Authorization Server, create a ‘Client Application’ and a ‘Resource Server’, followed by creating an ‘OAuth Profile’ that binds the ‘Client Application’ and ‘Resource Server’ together. The logic is that the authorization server needs to know its registered client application, as well as the participating resource server. This allows for Resource Server reaching out to Authorization Server for token validation as part of the flow.
\n
For this specific article, we select ‘Resource Owner Password Credentials’ (ROPC) grant type. There are plenty of resources on the Internet that talk about these different grants in great details but for the purpose of non-interactive machine to machine API traffic, the most suited grant type is Client Credentials.
\n
The BIG-IP APM does not natively handle Client Credentials grant type. However, it is very similar to ROPC grant type, which is natively handled. The idea is that we let the client application use ‘Client Credentials’ grant when talking to the Authorization Server, and once traffic arrives at the APM, we use an iRule to convert it to ROPC so the APM can process that traffic.
\n
ROPC requires that the Client (API client application) to send in username, password, client_id and client_secret. Client Credentials only requires client_id and client_secret to be sent.
\n
With Client Credentials grant, since no username or password is needed, the iRule simply adds them as dummies so the request looks like a ROPC grant request.
\n
Below are a couple of screenshots for your reference, as well as the iRule that you can readily use.
\n
\n
Figure 1 - Create a Client Application
\n
\n
Figure 2 - Create a Resource Server
\n
This iRule below is based on an excellent solution shared by DevCentral user youssef1. This is all his work, and I am simply referencing it here for this article.
The above concludes the Authorization Server configuration.
\n
Resource Server
\n
If your API servers do not understand OAuth, you can offload OAuth function to the BIG-IP APM by putting them behind it. Specifically, create a LB VIP for your API servers and attach an access profile so that together they act as a Resource Server.
\n
The Resource Server is responsible for checking the access token presented by the Client (application) as part of its API request, if the token checks out, API request is answered, otherwise denied.
\n
Depending on the type of the access token, if it is in the form of an opaque token, meaning it carries no information on its own, the Resource Server will need to present this token to the Authorization Server and in return it gets the information.
\n
If the access token is in the form of a JSON Web Token (JWT), the Resource Server verifies the signature of the token and then reads the embedded information off it. The Resource Server won’t need to reach out to the Authorization Server in this case.
\n
The APM supports both opaque token and JWT token, and by default the opaque token is used. The opaque token provides certain benefits such as it is revokable, hides the actual information and is probably smaller in size when compared to a JWT token. The downside is the Resource Server will need to talk to the Authorization Server for token validation and introspection. The JWT token does not need the extra roundtrip of communication, and therefore cuts down on latency, due to information is already embedded inside the token. However, it may not be suitable if you are transmitting sensitive information or require revoking a token after one is issued.
\n
Just as a side note, the BIG-IP APM can receive an opaque token, validates it against an external party, and then issue a JWT token downstream, as part of its SSO capability. This is not related to our use case here, but I will mention it for awareness.
\n
To offload Resource Server function to the BIG-IP APM, go to Access => Federation => OAuth Client / Resource Server, create a ‘Provider’ and an ‘OAuth Server’ configuration.
\n
The idea is that with a provider, it has all the information on Authorization Server, so Resource Server knows how to communicate with it. E.g., what URL to hit when validating a token
\n
\n
Figure 4 - Create a Provider
\n
https://as.abbagmbh.de points to the LB VIP we created earlier on for the Authorization Server.
\n
When creating the ‘OAuth Server’ configuration, fill in the ‘Resource Server ID’ and ‘Resource Server Secret’ values by copying them from the previous step when we configured under the ‘OAuth Authorization Server’ menu.
\n
\n
Figure 5 - Create an OAuth Server (Resource Server)
\n
The above concludes the Resource Server configuration.
\n
Access Profiles
\n
We need to create two access profiles, one for Authorization Server and the other for Resource Server.
\n
For Authorization Server, select ‘LTM-APM’ type, associate an OAuth Profile created earlier and leave the rest as default.
\n
The Access policy shown below is simple, the result is that an access token will be issued if client_id and client_secret in the request check out.
\n
\n
\n
\n
\n
Figure 6 – Access policy for Authorization Server
\n
For Resource Server, select ‘LTM-APM’ type and leave the rest as default.
\n
For the access policy, use ‘OAuth Scope’ type (I renamed it as OAuth Token Check), set token validation mode as ‘external’, select the Resource Server we created earlier on.
\n
Figure 7 - Resource Server access policy
\n
\n
Figure 8 - Token validation
\n
The above concludes a very basic setup of Resource Server.
\n
Scope
\n
In OAuth 2.0, scope is used to limit the level of access granted to an access token. For instance, you can use a ‘READ’ scope that allows API calls via HTTP GET, and a ‘WRITE’ scope that allows HTTP POST API calls.
\n
The full list of supported scopes should be communicated to the Client as defined on the Authorization Server.
\n
When Client is asking for an access token, it will include scope as part of the request parameter. If scope is not included, the Authorization Server either process the request using a pre-defined default value or fail the request indicating an invalid scope.
\n
Once access token is issued with the requested scope, it is sent to the Resource Server and it is incumbent upon the Resource Server to do something about it.
\n
Take the prior ‘READ’ and ‘WRITE’ scopes as an example, the Resource Server will need to block POST API calls if the scope is ‘READ’.
\n
Scope in essense is a literal string of key value pair, the string itself is defined per implementation. Once it is defined on the Authorization Server, it needs to be communicated to the Client, so the Client will know what scopes are available to use; it also needs to be communicated to the Resource Server as well, as it will implement enforcement per design.
\n
In this article, I am only introducing scope at a conceptual level to keep it short.
\n
The BIG-IP APM does however provide a full set of functions to support scope management.
\n
Testing
\n
So far, we have created two LB VIP’s, one as an Authorization Server, and the other as a Resource Server.
\n
\n
Figure 9 - LB VIP
\n
We created two access profiles, with each attached to the associated LB VIP.
Figure 14 - Postman send API request with access token
\n
The API server is programmed to print out the API request itself.
\n
\n
Figure 15 - API server response
\n
On the APM, if you go to Access => Overview => OAuth Reports => Tokens, you will see the token as ‘ACTIVE’.
\n
\n
Figure 16 - APM OAuth Token report
\n
Conclusion
\n
In this article, we started at high level on what comprises API security defined by Gartner, which comes down to API Threat Protection and API Access Control.
\n
F5 has WAAP as a SaaS offering to address API Threat Protection and the BIG-IP APM provides a highly capable solution for API Access Control.
\n
I have explained the concept around API Access Control using OAuth 2.0, as well as a specific use case on non-interactive machine to machine API access control.
\n
I hope you will find this article of value and please reach out with comments or your sales team if you have a need around implementing API Security.
Per Gartner, API Security comprises two aspects: API Threat Protection and API Access Control. API Threat Protection is addressed with measures such as API L7 firewall, bot protection, DDoS mitigation, etc. API Access Control is most comprehensively addressed via OAuth 2.0. This article will see our attention focused on API Access Control, and how F5 APM can be leverage for this universal challenge when protecting API.
","introduction":"","currentRevision":{"__ref":"Revision:revision:306666_9"},"latestVersion":{"__typename":"FriendlyVersion","major":"1","minor":"0"},"metrics":{"__typename":"MessageMetrics","views":5560},"visibilityScope":"PUBLIC","canonicalUrl":null,"seoTitle":"API Access Control","seoDescription":"Per Gartner, API Security comprises two aspects: API Threat Protection and API Access Control. API Threat Protection is addressed with measures such as API L7 firewall, bot protection, DDoS mitigation, etc. API Access Control is most comprehensively addressed via OAuth 2.0. This article will see our attention focused on API Access Control, and how F5 BIG-IP APM can be leveraged for this universal challenge when protecting API.","placeholder":false,"originalMessageForPlaceholder":null,"contributors":{"__typename":"UserConnection","edges":[]},"nonCoAuthorContributors":{"__typename":"UserConnection","edges":[]},"coAuthors":{"__typename":"UserConnection","edges":[]},"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":[],"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:306666":{"__typename":"Conversation","id":"conversation:306666","solved":false,"topic":{"__ref":"TkbTopicMessage:message:306666"},"lastPostingActivityTime":"2023-01-19T05:00:00.025-08:00","lastPostTime":"2023-01-19T05:00:00.025-08:00","unreadReplyCount":0,"isSubscribed":false},"ModerationData:moderation_data:306666":{"__typename":"ModerationData","id":"moderation_data:306666","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNTZpMzU4MzY5MzZBRDE2QTc5MA?revision=9\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNTZpMzU4MzY5MzZBRDE2QTc5MA?revision=9","title":"Screen Shot 2022-12-16 at 6.12.39 pm.png","associationType":"BODY","width":919,"height":366,"altText":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNTdpQjQxREU1QTIyQjM4RENGMw?revision=9\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNTdpQjQxREU1QTIyQjM4RENGMw?revision=9","title":"Screen Shot 2022-12-16 at 6.30.39 pm.png","associationType":"BODY","width":1594,"height":1680,"altText":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNThpMzJCQ0Y0RDRCQURDRDE1Mg?revision=9\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNThpMzJCQ0Y0RDRCQURDRDE1Mg?revision=9","title":"Screen Shot 2022-12-16 at 6.33.08 pm.png","associationType":"BODY","width":1594,"height":734,"altText":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNTlpQzI3NjUyMEVGMTdENzgzMg?revision=9\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNTlpQzI3NjUyMEVGMTdENzgzMg?revision=9","title":"Screen Shot 2022-12-16 at 6.37.40 pm.png","associationType":"BODY","width":1256,"height":1038,"altText":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNjBpRjIzQjE4Qzg1QTM2ODRERQ?revision=9\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNjBpRjIzQjE4Qzg1QTM2ODRERQ?revision=9","title":"Screen Shot 2022-12-16 at 6.39.09 pm.png","associationType":"BODY","width":1430,"height":1402,"altText":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNjFpQ0E2NjMyRUZENkYwODZDMw?revision=9\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNjFpQ0E2NjMyRUZENkYwODZDMw?revision=9","title":"Screen Shot 2022-12-16 at 6.41.33 pm.png","associationType":"BODY","width":1430,"height":350,"altText":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNjJpOEMxQUM3OTIyQkU5RTM2Mg?revision=9\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNjJpOEMxQUM3OTIyQkU5RTM2Mg?revision=9","title":"Screen Shot 2022-12-16 at 6.42.59 pm.png","associationType":"BODY","width":1430,"height":350,"altText":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNjNpRkY3RDY2NjNCM0VBOTFBRQ?revision=9\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNjNpRkY3RDY2NjNCM0VBOTFBRQ?revision=9","title":"Screen Shot 2022-12-16 at 6.44.03 pm.png","associationType":"BODY","width":1770,"height":564,"altText":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNzRpMUU0MkY4OUMwMDFDQkJCMA?revision=9\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNzRpMUU0MkY4OUMwMDFDQkJCMA?revision=9","title":"Screen Shot 2022-12-19 at 11.58.21 am.png","associationType":"BODY","width":1336,"height":62,"altText":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNDlpODE0RTlDRTU4ODQ5QzdDMQ?revision=9\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNDlpODE0RTlDRTU4ODQ5QzdDMQ?revision=9","title":"Chris_Zhang_10-1671174530632.png","associationType":"BODY","width":539,"height":61,"altText":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNTBpRTcyQzE2QzYzRTU0MTdBNA?revision=9\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNTBpRTcyQzE2QzYzRTU0MTdBNA?revision=9","title":"Chris_Zhang_11-1671174530632.png","associationType":"BODY","width":539,"height":61,"altText":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNzVpOTdDNEVCOEI3RUYxMDhERA?revision=9\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNzVpOTdDNEVCOEI3RUYxMDhERA?revision=9","title":"Screen Shot 2022-12-19 at 12.01.35 pm.png","associationType":"BODY","width":1252,"height":1000,"altText":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNzZpMzdFODdEOEFGQzM1QkE1Rg?revision=9\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNzZpMzdFODdEOEFGQzM1QkE1Rg?revision=9","title":"Screen Shot 2022-12-19 at 12.03.25 pm.png","associationType":"BODY","width":1880,"height":1060,"altText":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNzdpOENFNDZBOUQ2RTBCMDQzNg?revision=9\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNzdpOENFNDZBOUQ2RTBCMDQzNg?revision=9","title":"Screen Shot 2022-12-19 at 12.04.46 pm.png","associationType":"BODY","width":1880,"height":834,"altText":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNzhpOUE1NTFBOUI1NkY5OTRBRQ?revision=9\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNzhpOUE1NTFBOUI1NkY5OTRBRQ?revision=9","title":"Screen Shot 2022-12-19 at 12.05.45 pm.png","associationType":"BODY","width":1880,"height":620,"altText":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNzlpMUFDNjVFMzhDNzE4RURDRA?revision=9\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMDY2NjYtMjEyNzlpMUFDNjVFMzhDNzE4RURDRA?revision=9","title":"Screen Shot 2022-12-19 at 12.06.54 pm.png","associationType":"BODY","width":2638,"height":848,"altText":null},"Revision:revision:306666_9":{"__typename":"Revision","id":"revision:306666_9","lastEditTime":"2023-01-10T22:18:58.880-08:00"},"CachedAsset:theme:customTheme1-1743756125333":{"__typename":"CachedAsset","id":"theme:customTheme1-1743756125333","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-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-1744046279002","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:quilt:f5.prod:pages/kbs/TkbMessagePage:board:TechnicalArticles-1744046279014":{"__typename":"CachedAsset","id":"quilt:f5.prod:pages/kbs/TkbMessagePage:board:TechnicalArticles-1744046279014","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-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/common/EmailVerification-1744046279002","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-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-pages/kbs/TkbMessagePage-1744046279002","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:1743756026601":{"__typename":"CachedAsset","id":"quiltWrapper:f5.prod:Common:1743756026601","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-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/common/ActionFeedback-1744046279002","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-1743756141111":{"__typename":"CachedAsset","id":"component:custom.widget.Beta_MetaNav-en-1743756141111","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-1743756141111":{"__typename":"CachedAsset","id":"component:custom.widget.Beta_Footer-en-1743756141111","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-1743756141111":{"__typename":"CachedAsset","id":"component:custom.widget.Tag_Manager_Helper-en-1743756141111","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-1743756141111":{"__typename":"CachedAsset","id":"component:custom.widget.Consent_Blackbar-en-1743756141111","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-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/community/Breadcrumb-1744046279002","value":{"navLabel":"Breadcrumbs","dropdown":"Additional parent page navigation"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBanner-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBanner-1744046279002","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-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/tkbs/TkbArticleWidget-1744046279002","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}}},"CachedAsset:text:en_US-components/community/Navbar-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/community/Navbar-1744046279002","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-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarHamburgerDropdown-1744046279002","value":{"hamburgerLabel":"Side Menu"},"localOverride":false},"CachedAsset:text:en_US-components/community/BrandLogo-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/community/BrandLogo-1744046279002","value":{"logoAlt":"Khoros","themeLogoAlt":"Brand Logo"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarTextLinks-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarTextLinks-1744046279002","value":{"more":"More"},"localOverride":false},"CachedAsset:text:en_US-components/authentication/AuthenticationLink-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/authentication/AuthenticationLink-1744046279002","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-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/nodes/NodeLink-1744046279002","value":{"place":"Place {name}"},"localOverride":false},"QueryVariables:TopicReplyList:message:306666:9":{"__typename":"QueryVariables","id":"TopicReplyList:message:306666:9","value":{"id":"message:306666","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-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/QueryHandler-1744046279002","value":{"title":"Query Handler"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarDropdownToggle-1744046279002","value":{"ariaLabelClosed":"Press the down arrow to open the menu"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageView/MessageViewStandard-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageView/MessageViewStandard-1744046279002","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-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/messages/ThreadedReplyList-1744046279002","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-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyCallToAction-1744046279002","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},"CachedAsset:text:en_US-components/messages/MessageSubject-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageSubject-1744046279002","value":{"noSubject":"(no subject)"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBody-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBody-1744046279002","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-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCustomFields-1744046279002","value":{"CustomField.default.label":"Value of {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageRevision-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageRevision-1744046279002","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-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyButton-1744046279002","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-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageAuthorBio-1744046279002","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-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/guides/GuideBottomNavigation-1744046279002","value":{"nav.label":"Previous/Next Page","nav.previous":"Previous","nav.next":"Next"},"localOverride":false},"CachedAsset:text:en_US-components/customComponent/CustomComponent-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/customComponent/CustomComponent-1744046279002","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-components/users/UserLink-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserLink-1744046279002","value":{"authorName":"View Profile: {author}","anonymous":"Anonymous"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserRank-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserRank-1744046279002","value":{"rankName":"{rankName}","userRank":"Author rank {rankName}"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserRegistrationDate-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserRegistrationDate-1744046279002","value":{"noPrefix":"{date}","withPrefix":"Joined {date}"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagView/TagViewChip-1744046279002","value":{"tagLabelName":"Tag name {tagName}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserAvatar-1744046279002","value":{"altText":"{login}'s avatar","altTextGeneric":"User's avatar"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1744046279002":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/ranks/UserRankLabel-1744046279002","value":{"altTitle":"Icon for {rankName} rank"},"localOverride":false}}}},"page":"/kbs/TkbMessagePage/TkbMessagePage","query":{"boardId":"technicalarticles","messageSubject":"api-security-how-to-implement-api-access-control-with-f5","messageId":"306666"},"buildId":"q_bLpq2mflH0BeZigxpj6","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","./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":[]}