|
| 1 | +--- |
| 2 | +description: Learn how to use policy activity logs to gain visibility into policy and rule activity. |
| 3 | +--- |
| 4 | + |
| 5 | +# Policy activity logs |
| 6 | + |
| 7 | +:::note |
| 8 | + |
| 9 | +This feature is in tech preview. Tech preview features may be subject to significant changes before they become GA. |
| 10 | + |
| 11 | +::: |
| 12 | + |
| 13 | +## About policy activity logs |
| 14 | + |
| 15 | +Policy activity logs provide granular visibility into network policy behavior within your cluster. By tracking exactly which rules are evaluated and triggered, these logs offer policy-centric context that complements standard Flow Logs. |
| 16 | + |
| 17 | +Regularly reviewing policy activity, especially unused policies and rules, helps you maintain a clean and secure cluster by identifying and removing obsolete resources. |
| 18 | + |
| 19 | +## Log structure |
| 20 | + |
| 21 | +Each log entry contains the following key fields: |
| 22 | + |
| 23 | +| Field | Description | Example | |
| 24 | +| ----------------- | -------------------------------------------------------------------------------------------- | -------------------------------- | |
| 25 | +| `policy.kind` | The type of the policy. Possible values: `NetworkPolicy`, `GlobalNetworkPolicy`, `KubernetesNetworkPolicy`, `KubernetesAdminNetworkPolicy`, `KubernetesBaselineAdminNetworkPolicy`, `StagedNetworkPolicy`, `StagedGlobalNetworkPolicy`, `StagedKubernetesNetworkPolicy` | `NetworkPolicy` | |
| 26 | +| `policy.namespace`| The namespace where the policy is defined. | `my-test` | |
| 27 | +| `policy.name` | The unique name of the policy. | `my-tier.my-networkpolicy` | |
| 28 | +| `rule` | The identifier for the specific rule that was triggered, formatted as `{generation}-{direction}-{rule_index}`. | `2-ingress-4` | |
| 29 | +| `cluster` | The name of the cluster where the activity occurred. | `cluster` | |
| 30 | +| `last_evaluated` | The timestamp when the rule was last evaluated. | `2025-12-01T23:09:28.384714204Z` | |
| 31 | + |
| 32 | + |
| 33 | +:::note |
| 34 | + |
| 35 | +The generation number in the `rule` identifier (e.g., the `2` in `2-ingress-4`) reflects the `metadata.generation` of the policy at the time of evaluation. |
| 36 | + |
| 37 | +It increments whenever the spec of the policy is updated, allowing you to correlate activity logs with the exact policy configuration that was active when the traffic occurred. |
| 38 | + |
| 39 | +::: |
| 40 | + |
| 41 | +## Find unused policies |
| 42 | + |
| 43 | +Policy activity logs record only policies and rules that have been evaluated by actual network traffic. To identify unused policies or rules in your cluster, follow these steps: |
| 44 | + |
| 45 | +### Step 1: Retrieve active policies/rules |
| 46 | + |
| 47 | +Use the following Elasticsearch query to list all policies that have been evaluated in the last 90 days: |
| 48 | + |
| 49 | +``` |
| 50 | +POST /tigera_secure_ee_policy_activity*/_search |
| 51 | +{ |
| 52 | + "size": 0, |
| 53 | + "query": { |
| 54 | + "range": { |
| 55 | + "last_evaluated": { |
| 56 | + "gte": "now-90d" |
| 57 | + } |
| 58 | + } |
| 59 | + }, |
| 60 | + "aggs": { |
| 61 | + "active_policies": { |
| 62 | + "composite": { |
| 63 | + "size": 1000, |
| 64 | + "sources": [ |
| 65 | + { "kind": { "terms": { "field": "policy.kind" } } }, |
| 66 | + { "namespace": { "terms": { "field": "policy.namespace" } } }, |
| 67 | + { "name": { "terms": { "field": "policy.name" } } } |
| 68 | + ] |
| 69 | + }, |
| 70 | + "aggs": { |
| 71 | + "latest_activity": { |
| 72 | + "max": { |
| 73 | + "field": "last_evaluated" |
| 74 | + } |
| 75 | + } |
| 76 | + } |
| 77 | + } |
| 78 | + } |
| 79 | +} |
| 80 | +``` |
| 81 | + |
| 82 | +To see which rules have been triggered in the last 90 days, use this query: |
| 83 | + |
| 84 | +``` |
| 85 | +POST /tigera_secure_ee_policy_activity*/_search |
| 86 | +{ |
| 87 | + "size": 10000, |
| 88 | + "query": { |
| 89 | + "range": { |
| 90 | + "last_evaluated": { |
| 91 | + "gte": "now-90d" |
| 92 | + } |
| 93 | + } |
| 94 | + } |
| 95 | +} |
| 96 | +``` |
| 97 | + |
| 98 | +::: note |
| 99 | + |
| 100 | +If you need to retrieve more than 10,000 logs, do not simply increase the size. Instead, use pagination (especially `scroll API`) to scroll through results efficiently. |
| 101 | + |
| 102 | +[Learn more](https://www.elastic.co/docs/reference/elasticsearch/rest-apis/paginate-search-results) |
| 103 | +::: |
| 104 | + |
| 105 | +### Step 2: Retrieve all network policies and rules |
| 106 | + |
| 107 | +Export your current policy and rule inventory using `kubectl get ...` commands. |
| 108 | + |
| 109 | +### Step 3: Compare lists |
| 110 | + |
| 111 | +Compare the output from the steps above to identify unused resources: |
| 112 | +- Match: Check if each policy (or specific rule ID) in your Cluster exists in the active lists from Elasticsearch. |
| 113 | +- Identify Unused: Any policy or rule present in the inventory but missing from the active list has not been evaluated by traffic in the last 90 days. |
| 114 | +- Verify: Before deleting any resource, ensure it is not a newly deployed policy that simply hasn't received traffic yet. |
| 115 | + |
| 116 | +## Limitations |
| 117 | + |
| 118 | +- **Logs require traffic**: Policy activity logs are only generated when a rule is evaluated by traffic. Resources that have never been hit will not appear in these logs. You cannot identify them by querying for "old" logs; you must identify them by their absence from the active log data (as performed in the comparison steps above). |
| 119 | +- **Long-lived connections**: A policy evaluation is logged only when a connection is established. If a connection remains open for a long duration (e.g., longer than your 90-day query window), the associated policy may not generate new logs, potentially making it appear "unused" despite actively carrying traffic. |
0 commit comments