diff --git a/proxies/live/apiproxy/policies/FlowCalloutSingleASIDApply.xml b/proxies/live/apiproxy/policies/FlowCalloutSingleASIDApply.xml
new file mode 100644
index 0000000..7041fef
--- /dev/null
+++ b/proxies/live/apiproxy/policies/FlowCalloutSingleASIDApply.xml
@@ -0,0 +1,7 @@
+
+
+ FlowCallout.SingleASIDApply
+
+
+ SingleASIDApply
+
diff --git a/proxies/live/apiproxy/proxies/default.xml b/proxies/live/apiproxy/proxies/default.xml
index 876f6d9..af0a813 100644
--- a/proxies/live/apiproxy/proxies/default.xml
+++ b/proxies/live/apiproxy/proxies/default.xml
@@ -1,167 +1,193 @@
+
-
-
-
-
- FlowCallout.UserRoleService
-
-
-
-
- AssignMessage.AddPayloadToPing
-
-
- proxy.pathsuffix MatchesPath "/user-role-service"
-
-
-
-
- FlowCallout.UserRoleServiceV2.CustomHeader
-
-
-
-
- AssignMessage.AddPayloadToPing
-
-
- proxy.pathsuffix MatchesPath "/user-role-service-v2-custom-header"
-
-
-
-
- FlowCallout.UserRoleServiceV2.DefaultHeader
-
-
-
-
- AssignMessage.AddPayloadToPing
-
-
- proxy.pathsuffix MatchesPath "/user-role-service-v2-default-header"
-
-
-
-
-
- AssignMessage.AddCors
-
-
- (request.verb = "OPTIONS") and (request.header.origin != null) and (request.header.Access-Control-Request-Method != null)
-
-
-
-
-
-
- AssignMessage.AddPayloadToPing
-
-
- (proxy.pathsuffix MatchesPath "/_ping") and ((request.verb = "GET") or (request.verb = "HEAD"))
-
-
-
-
- request.header.apikey = null or private.common.status-endpoint-api-key != request.header.apikey
- RaiseFault.401Unauthorized
-
-
- ServiceCallout.CallHealthcheckEndpoint
-
-
-
-
- javascript.SetStatusResponse
-
-
- (proxy.pathsuffix MatchesPath "/_status") and ((request.verb = "GET") or (request.verb = "HEAD"))
+
+
+
+
+ FlowCallout.UserRoleService
+
+
+
+
+ AssignMessage.AddPayloadToPing
+
+
+ proxy.pathsuffix MatchesPath "/user-role-service"
+
+
+
+
+ FlowCallout.UserRoleServiceV2.CustomHeader
+
+
+
+
+ AssignMessage.AddPayloadToPing
+
+
+ proxy.pathsuffix MatchesPath "/user-role-service-v2-custom-header"
+
+
+
+
+ FlowCallout.UserRoleServiceV2.DefaultHeader
+
+
+
+
+ AssignMessage.AddPayloadToPing
+
+
+ proxy.pathsuffix MatchesPath "/user-role-service-v2-default-header"
+
+
+
+
+
+ AssignMessage.AddCors
+
+
+ (request.verb = "OPTIONS") and (request.header.origin != null) and (request.header.Access-Control-Request-Method != null)
+
+
+
+
+
+
+ AssignMessage.AddPayloadToPing
+
+
+ (proxy.pathsuffix MatchesPath "/_ping") and ((request.verb = "GET") or (request.verb = "HEAD"))
+
+
+
+
+ request.header.apikey = null or private.common.status-endpoint-api-key != request.header.apikey
+ RaiseFault.401Unauthorized
+
+
+ ServiceCallout.CallHealthcheckEndpoint
+
+
+
+
+ javascript.SetStatusResponse
+
+
+ (proxy.pathsuffix MatchesPath "/_status") and ((request.verb = "GET") or (request.verb = "HEAD"))
-
-
-
-
- OauthV2.VerifyAccessToken
-
-
- AssignMessage.Swap.RequestHeaders
-
-
- (proxy.pathsuffix MatchesPath "/splunk-test") and ((request.verb = "GET") or (request.verb = "HEAD"))
-
-
-
-
- VerifyApiKey.Apikey
-
-
- (proxy.pathsuffix MatchesPath "/apikey-protected") and ((request.verb = "GET") or (request.verb = "HEAD"))
-
-
- (proxy.pathsuffix MatchesPath "/open-access") and ((request.verb = "GET") or (request.verb = "HEAD"))
-
-
-
-
- OauthV2.VerifyAccessToken
-
-
- FlowCallout.ExtendedAttributes
-
-
-
-
- AssignMessage.AddPayloadToPing
-
-
- (proxy.pathsuffix MatchesPath "/extended-attributes") and ((request.verb = "GET") or (request.verb = "HEAD"))
-
-
-
-
- FlowCallout.EnhancedVerifyApiKey
-
-
- (proxy.pathsuffix MatchesPath "/enhanced-verify-api-key") and ((request.verb = "GET") or (request.verb = "HEAD"))
-
-
-
-
-
-
- FlowCallout.LogToSplunk
-
-
-
-
- {{ SERVICE_BASE_PATH }}
- secure
-
-
- (request.verb = "OPTIONS") and (request.header.origin != null) and (request.header.Access-Control-Request-Method != null)
-
-
- (proxy.pathsuffix MatchesPath "/_ping") and ((request.verb = "GET") or (request.verb = "HEAD"))
-
-
- (proxy.pathsuffix MatchesPath "/_status") and ((request.verb = "GET") or (request.verb = "HEAD"))
-
-
- (proxy.pathsuffix MatchesPath "/user-role-service") and ((request.verb = "GET") or (request.verb = "HEAD"))
-
-
- (proxy.pathsuffix MatchesPath "/user-role-service-v2-custom-header") and ((request.verb = "GET") or (request.verb = "HEAD"))
-
-
- (proxy.pathsuffix MatchesPath "/user-role-service-v2-default-header") and ((request.verb = "GET") or (request.verb = "HEAD"))
-
-
- (proxy.pathsuffix MatchesPath "/extended-attributes") and ((request.verb = "GET") or (request.verb = "HEAD"))
-
-
- shared-flow-testing-target
-
-
-
- AssignMessage.Errors.CatchAllMessage
-
-
-
+
+
+
+
+ OauthV2.VerifyAccessToken
+
+
+ AssignMessage.Swap.RequestHeaders
+
+
+ (proxy.pathsuffix MatchesPath "/splunk-test") and ((request.verb = "GET") or (request.verb = "HEAD"))
+
+
+
+
+ VerifyApiKey.Apikey
+
+
+ (proxy.pathsuffix MatchesPath "/apikey-protected") and ((request.verb = "GET") or (request.verb = "HEAD"))
+
+
+ (proxy.pathsuffix MatchesPath "/open-access") and ((request.verb = "GET") or (request.verb = "HEAD"))
+
+
+
+
+ OauthV2.VerifyAccessToken
+
+
+ FlowCallout.ExtendedAttributes
+
+
+
+
+ AssignMessage.AddPayloadToPing
+
+
+ (proxy.pathsuffix MatchesPath "/extended-attributes") and ((request.verb = "GET") or (request.verb = "HEAD"))
+
+
+
+
+ FlowCallout.EnhancedVerifyApiKey
+
+
+ (proxy.pathsuffix MatchesPath "/enhanced-verify-api-key") and ((request.verb = "GET") or (request.verb = "HEAD"))
+
+
+
+
+
+ OauthV2.VerifyAccessToken
+
+
+ FlowCalloutExtendedAttributes
+
+
+ FlowCalloutSingleASIDApply
+
+
+
+ (proxy.pathsuffix MatchesPath "/single-asid") and ((request.verb = "GET") or (request.verb = "HEAD"))
+
+
+
+
+
+ AssignMessage.SetApimGuids
+
+
+
+
+
+
+ FlowCallout.LogToSplunk
+
+
+
+
+ shared-flow-testing
+ secure
+
+
+ (request.verb = "OPTIONS") and (request.header.origin != null) and (request.header.Access-Control-Request-Method != null)
+
+
+ (proxy.pathsuffix MatchesPath "/_ping") and ((request.verb = "GET") or (request.verb = "HEAD"))
+
+
+ (proxy.pathsuffix MatchesPath "/_status") and ((request.verb = "GET") or (request.verb = "HEAD"))
+
+
+ (proxy.pathsuffix MatchesPath "/user-role-service") and ((request.verb = "GET") or (request.verb = "HEAD"))
+
+
+ (proxy.pathsuffix MatchesPath "/user-role-service-v2-custom-header") and ((request.verb = "GET") or (request.verb = "HEAD"))
+
+
+ (proxy.pathsuffix MatchesPath "/user-role-service-v2-default-header") and ((request.verb = "GET") or (request.verb = "HEAD"))
+
+
+ (proxy.pathsuffix MatchesPath "/extended-attributes") and ((request.verb = "GET") or (request.verb = "HEAD"))
+
+
+ (proxy.pathsuffix MatchesPath "/single-asid") and ((request.verb = "GET") or (request.verb = "HEAD"))
+
+
+ shared-flow-testing-target
+
+
+
+ AssignMessage.Errors.CatchAllMessage
+
+
+
\ No newline at end of file
diff --git a/tests/test_single_asid_apply.py b/tests/test_single_asid_apply.py
new file mode 100644
index 0000000..d3fdcf1
--- /dev/null
+++ b/tests/test_single_asid_apply.py
@@ -0,0 +1,31 @@
+import pytest
+import requests
+import jwt
+
+from uuid import uuid4
+from time import time
+
+from tests.utils.config import ENV
+from tests.utils.helpers import get_variable_from_trace
+
+
+class TestSingleAsidApply:
+ """Test Single Asid Apply are available"""
+ @pytest.mark.parametrize("expected_status_code, expected_message", [(400, "no_headers")])
+ def test_no_header_present(
+ self,
+ nhsd_apim_proxy_url,
+ expected_status_code,
+ expected_message
+ ):
+ # Create test app and don't define any apiProducts
+
+ proxy_resp = requests.get(
+ url=f"{nhsd_apim_proxy_url}/single-asid",
+ timeout=60
+ )
+
+ assert proxy_resp.status_code == expected_status_code
+ assert proxy_resp.json().get("error") == expected_message
+
+