A misconfigured authorization policy can silently break production traffic -- blocking legitimate requests or allowing unauthorized access. Trial mode lets you validate an authorization policy against live traffic without enforcing it. Confirm the policy behaves as expected before it starts rejecting requests.
How trial mode works
When you enable trial mode on an authorization policy, Service Mesh (ASM) evaluates every request against the policy and logs the decision, but does not allow or deny traffic based on the result. This lets you:
Verify that the policy matches the intended requests.
Identify false positives (legitimate requests that would be denied) or false negatives (unauthorized requests that would be allowed).
Fine-tune policy rules before enforcement.
After the logs confirm correct behavior, disable trial mode to start enforcement.
We recommend enabling trial mode for every new authorization policy before enforcing it in production. Deploying a policy directly without validation can deny legitimate traffic or allow unauthorized access, with no warning until users report issues.
Prerequisites
Before you begin, make sure that you have:
An ASM instance (v1.14 or later) with a cluster added. To check or update your ASM version, see Update an ASM instance
A namespace named
foowith automatic sidecar proxy injection enabled. For details, see Manage global namespaces
Step 1: Deploy sample applications and verify connectivity
This walkthrough uses two applications -- sleep (a curl client) and httpbin (an HTTP echo server) -- to demonstrate trial mode end to end.
-
Create a file named
sleep.yamlwith the following content: -
Connect to your cluster with kubectl and deploy the sleep application in the
foonamespace. For connection instructions, see Obtain the kubeconfig file of a cluster and use kubectl to connect to the cluster.kubectl apply -f sleep.yaml -n foo -
Create a file named
httpbin.yamlwith the following content: -
Deploy the httpbin application in the
foonamespace:kubectl apply -f httpbin.yaml -n foo -
Send 20 requests from the sleep pod to httpbin to confirm connectivity:
for i in {1..20}; do kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl http://httpbin.foo:8000/headers -s -o /dev/null -w "%{http_code}\n"; doneExpected output:
200 200 200 ...Every request returns
200, confirming that the sleep pod can reach httpbin over the mesh.
Step 2: Create an authorization policy with trial mode enabled
-
Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.
-
On the Mesh Management page, click the name of your ASM instance. In the left-side navigation pane, choose Mesh Security Center > AuthorizationPolicy. Click Create.
-
Configure the authorization policy to deny the target requests, enable trial mode (the Commissioning mode toggle), and click Create.

Step 3: Verify trial mode results
With trial mode enabled, the authorization policy logs its decisions without blocking traffic. Verify results through proxy logs.
Check proxy logs
-
Send the same 20 requests from the sleep pod to httpbin:
for i in {1..20}; do kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl http://httpbin.foo:8000/headers -s -o /dev/null -w "%{http_code}\n"; doneExpected output:
200 200 200 ...All requests still return
200because the policy is in trial mode -- it evaluates each request but does not enforce the deny action. -
Set the RBAC log level of the httpbin sidecar proxy to
debugto surface trial mode decisions:kubectl exec "$(kubectl get pod -l app=httpbin -n foo -o jsonpath={.items..metadata.name})" -c istio-proxy -n foo -- curl -X POST 127.0.0.1:15000/logging?rbac=debugVerify that the output includes
rbac: debug:active loggers: ... rbac: debug ... -
Filter the sidecar proxy logs for
shadow deniedentries -- requests that *would* have been denied if the policy were enforced:kubectl logs "$(kubectl -n foo -l app=httpbin get pods -o jsonpath={.items..metadata.name})" -c istio-proxy -n foo | grep "shadow denied"Example output:
2023-12-20T03:58:47.107915Z debug envoy rbac external/envoy/source/extensions/filters/http/rbac/rbac_filter.cc:130 shadow denied, matched policy ns[foo]-policy[test]-rule[0] thread=32 2023-12-20T03:58:48.800098Z debug envoy rbac external/envoy/source/extensions/filters/http/rbac/rbac_filter.cc:130 shadow denied, matched policy ns[foo]-policy[test]-rule[0] thread=33 2023-12-20T03:58:50.420179Z debug envoy rbac external/envoy/source/extensions/filters/http/rbac/rbac_filter.cc:130 shadow denied, matched policy ns[foo]-policy[test]-rule[0] thread=32Each
shadow deniedlog entry confirms that the authorization policy matched the request and would have denied it. Review these entries to make sure the policy targets only the intended traffic.
We recommend keeping trial mode enabled for an extended period to test the policy against a representative sample of production traffic before enforcing it.
Step 4: Disable trial mode to enforce the policy
After the logs confirm that the authorization policy matches only the intended requests, disable trial mode to start enforcement.
-
Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.
-
On the Mesh Management page, click the name of your ASM instance. In the left-side navigation pane, choose Mesh Security Center > AuthorizationPolicy.
-
Find the authorization policy created in Step 2. Turn off the switch in the Commissioning mode column, then click OK in the Submit dialog.
-
Send 20 requests again to verify that the policy now rejects traffic:
for i in {1..20}; do kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl http://httpbin.foo:8000/headers -s -o /dev/null -w "%{http_code}\n"; doneExpected output:
403 403 403 ...Every request now returns
403, confirming that the authorization policy is active. -
Restore the sidecar proxy RBAC log level to
warning:kubectl exec "$(kubectl get pod -l app=httpbin -n foo -o jsonpath={.items..metadata.name})" -c istio-proxy -n foo -- curl -X POST 127.0.0.1:15000/logging?rbac=warningVerify that the output includes
rbac: warning:active loggers: ... rbac: warning ...