{"id":19873066,"url":"https://github.com/checkpointsw/policycleanup","last_synced_at":"2025-08-27T15:19:27.299Z","repository":{"id":50151147,"uuid":"167817059","full_name":"CheckPointSW/PolicyCleanUp","owner":"CheckPointSW","description":"Check Point PolicyCleanUp tool allows automatic cleanup of your policy based on hits count.","archived":false,"fork":false,"pushed_at":"2023-10-19T12:31:52.000Z","size":29,"stargazers_count":27,"open_issues_count":1,"forks_count":12,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-05-02T09:49:03.655Z","etag":null,"topics":["management-api"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CheckPointSW.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-01-27T14:18:44.000Z","updated_at":"2025-03-20T10:54:02.000Z","dependencies_parsed_at":"2025-05-02T09:39:55.825Z","dependency_job_id":"c58d578c-1867-4018-84d1-a24fc65e6456","html_url":"https://github.com/CheckPointSW/PolicyCleanUp","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/CheckPointSW/PolicyCleanUp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CheckPointSW%2FPolicyCleanUp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CheckPointSW%2FPolicyCleanUp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CheckPointSW%2FPolicyCleanUp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CheckPointSW%2FPolicyCleanUp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CheckPointSW","download_url":"https://codeload.github.com/CheckPointSW/PolicyCleanUp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CheckPointSW%2FPolicyCleanUp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272343673,"owners_count":24917895,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-27T02:00:09.397Z","response_time":76,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["management-api"],"created_at":"2024-11-12T16:17:41.720Z","updated_at":"2025-08-27T15:19:27.275Z","avatar_url":"https://github.com/CheckPointSW.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PolicyCleanUp\nCheck Point PolicyCleanUp tool allows automatic cleanup of your policy based on hits count. The tool runs on a policy \nand a domain that you named.\n\n*   If a rule was not hit for the number of days that you configured, the rule is a candidate to be disabled.\n*   If a rule is disabled for the number of days that you configured, the rule is a candidate to be deleted.\n\nYou can adjust the code according to your organization’s policy / needs.\n\n  - This tool can be executed on Management Server / Multi-Domain servers of version of R80.10 and up.\n\n## Instructions\nClone the repository with this command:\n```git\ngit clone https://github.com/CheckPointSW/PolicyCleanUp\n``` \nor by clicking the _‘Download ZIP’_ button. \n\nDownload and install the [Check Point API Python SDK](https://github.com/CheckPointSW/cp_mgmt_api_python_sdk) \nrepository, follow the instructions in the SDK repository.\n\n## Main Options\n*__More options and details can be found with the '-h' option by running:__ python policyCleanUp.py –h*\n*   [--package \u0026nbsp; ,\u0026nbsp; -k]\u0026emsp; The name of the policy package to clean from zero-hit rules. The default is all \npolicies.\n*   [--operation , -op]\u0026emsp;   The operation mode in which the tool runs. The default is plan.\n\u003cbr\u003e\u0026emsp;\u0026emsp;There are 3 modes:\u003cbr\u003e  \n    *  plan: tool runs without performing changes in the policy. The output file is in Json format. The output file \n    holds rules that are candidates for deletion or to be disabled.\n    *  apply: tool runs and makes changes in the policy. The rules are disabled and deleted according to the plan. \n    At the end of this operation, publish is executed.\n    *  apply without publish: tool runs and makes changes but without publish. In this mode, \n    you can login from SmartConsole to this session and explore changes before they are published.\n*   [--import-plan-file , -i]\u0026emsp; A file that holds output of execution of the ‘plan’ operation. \nYou can use this file only on apply or apply_without_publish operations. Tip: using this option saves time of the ‘apply’ \noperation if you already executed a ‘plan’.\n*   [--disable-after]\u0026emsp; Time in days in which if there are no hits, the rule is a candidate for disabling. \nDefault is 180 days. Learn how to change the default in ‘Technical Details’ section.\n*   [--delete-after]\u0026emsp;  Time in days for a disabled rule to be a candidate for deletion. Only rules that \nwere disabled by the tool are candidates for deletion. Default is 60 days. Learn how to change the default in ‘Technical \nDetails’ section.\n*   [--output-file]\u0026emsp;   Name of the output file. The file is in Json format. This file helps you understand \nwhich rules were affected. If not supplied, the default file name is _‘policyCleanUp-\u003cunix-timestamp\u003e.json’_. \nTo use it in ‘apply’ operations, pass it as 'import plan file'.\n\n## Examples\n*   Running the tool on a remote management server using username \u0026 password: \n\u003cbr\u003e```python policyCleanUp.py  -m 172.23.78.160 -u James -p MySecretPassword!```\n\u003cbr\u003eThe tool runs on a remote management server with IP address 172.23.78.160 and the operation is ‘plan’ (default).\n*   Running the tool on a remote management server using API key: \n\u003cbr\u003e```python policyCleanUp.py  -m 172.23.78.160 --api-key JpPA+eJ5gekQBY8DF27+ZQ==```\n*   Running the tool on a Multi-Domain Server for a specific domain and a specific policy package: \n\u003cbr\u003e```python policyCleanUp.py  -d 172.23.78.152 –k Standard -u James -p MySecretPassword!```\n*   Running the tool on a Security Management Server with operation plan: \n\u003cbr\u003e```python policyCleanUp.py  -o plan_output_file.json -op plan -u James -p MySecretPassword!```\n\u003cbr\u003eThe tool runs in plan mode and creates a json output file named “plan_output_file.json” as noted. This file can \n    be used later on as an ‘import-plan-file’ for ‘apply’ mode.\n*   Running the tool on a Security Management Server and applying the import-plan-file:\n\u003cbr\u003e```python policyCleanUp.py  -i plan_output_file.json  -op apply -u James -p MySecretPassword!```\n\u003cbr\u003eThe tool runs in apply mode. Rules are disabled / deleted according to the import-plan-file “plan_output_file.json”._\n*   Running the tool on a Security Management Server with operation apply-without-publish, set specific disable/deleted thresholds and session name:\n\u003cbr\u003e```python policyCleanUp.py -op apply_without_publish –-root true --disable-after 20 --delete-after 40 --session-name “Policy Cleanup script”```\n\u003cbr\u003eThe tool runs in ‘apply without publish’ mode which means publish is not executed at the end but changes will be saved n private session.\nYou can connect to SmartConsole, find the session named “session_name” and explore the changes before publishing the session.\u003cbr\u003e\nThis run will not use default thresholds but instead these are the thresholds:\n\u003cbr\u003e\u0026emsp;- Disabled rules whose last hits were 20 days ago.\n\u003cbr\u003e\u0026emsp;- Deleted rules which were disabled by the tool 40 days ago.\n\n## Output\nThe tool’s output is a file in a Json format that holds the following information:\n1.\tList of packages that were scanned\n\u003cbr\u003e\u0026emsp;- Each package holds its layers and installation targets\n\u003cbr\u003e\u0026emsp;- Each layer in the package contains:\n\u003cbr\u003e\u0026emsp;- disabled rules, deleted rules and skipped rules (and reason). \n\u003cbr\u003e\u0026emsp;- objects-dictionary (for rules)\n2.\tList of skipped packages with reasons\n3.\tThreshold values\n4.\tOperation mode in which the tool was ran\n\nExample of Output:\n```Git\n{\n    \"operation\": \"plan\", \n    \"packages\": [\n        {\n            \"access-layers\": [\n                {\n                    \"delete-rules\": {\n                        \"rules\": [], \n                        \"total\": 0\n                    }, \n                    \"disable-rules\": {\n                        \"rules\": [...], \n                        \"total\": 7\n                    }, \n                    \"name\": \"Branch_Office_Policy Network\", \n                    \"objects-dictionary\": [...], \n                    \"shared\": false, \n                    \"skipped-rules\": {\n                        \"rules\": [...], \n                        \"total\": 3\n                    }, \n                    \"type\": \"access-layer\", \n                    \"uid\": \"13a747d1-7fda-483b-afca-f8d996a4a574\"\n                }, \n            ], \n            \"installation-targets\": [...], \n            \"name\": \"Branch_Office_Policy\", \n            \"type\": \"package\", \n            \"uid\": \"89368746-46bd-418e-a625-2e848040c76f\"\n        }\n    ], \n    \"skipped-packages\": [\n        {\n            \"name\": \"Corporate_Policy\", \n            \"skipped-reason\": \"All package targets are invalid\", \n            \"type\": \"package\", \n            \"uid\": \"e187eb39-f6dd-4ee3-93c3-ce4df3e2e393\"\n        }\n    ], \n    \"thresholds\": {\n        \"delete-after\": 6, \n        \"disable-after\": 4\n    }\n}\n\n```\nIf you run the tool with plan mode the output can be used as input for import-plan-file for the tool with apply/ apply without publish.  \n\n\n## Technical Details\n* The default values for‘--disable-after’ and ‘--delete-after’ are part of the python script (policyCleanUp.py). \nTo change values, search for the following thresholds in code:\n```python\n# Defaults for global disable \u0026 delete thresholds\nDEFAULT_DISABLE_THRESHOLD = 180\nDEFAULT_DELETE_THRESHOLD = 60\n```\n\n\n* Relevant functions in the script that you can change to adjust the logic to your needs:\n\u003cbr\u003e\u0026emsp;1.\u003ci\u003e‘apply_plan’\u003c/i\u003e – a function that applies the changes per rule. If the rule was a candidate for disabling, it calls the ‘disable_rule’ function and if the rule candidate for deletion it calls the ‘delete_rule’ function. In both these functions the changes affect on the rule. \n\u003cbr\u003e\u0026emsp;2.\u003ci\u003e‘rule_should_be_disabled’\u003c/i\u003e – a function that determines if rule should be disabled. A rule should be disabled if it’s last hit date or last modified date (the closest date) is before today’s date minus the threshold. The thresholds are determined by global thresholds or overrides thresholds.\n\u003cbr\u003e\u0026emsp;3.\u003ci\u003e‘rule_should_be_deleted’\u003c/i\u003e – a function that determines if a rule should be deleted. A rule should be deleted if the date it was disabled by the tool is before today’s date minus the threshold. The thresholds are determined by global thresholds or overrides thresholds\n\u003cbr\u003e\u0026emsp;4.\u003ci\u003e‘validate_rule’\u003c/i\u003e – a function that checks if the install-on list contains invalid target and that the rule was not modified after it was installed on targets.\n\n* Example for a simple code adjustment:\n\u003cbr\u003e\u0026emsp;\u003cu\u003eObjective:\u003c/u\u003e  As part of rule disabling, set it to the bottom of the rulebase. \n\u003cbr\u003e\u0026emsp;\u003cu\u003eSolution:\u003c/u\u003e\n\u003cbr\u003e\u0026emsp;- Find ‘disable_rule’ function.\n\u003cbr\u003e\u0026emsp;- Find the API call that disables the rule (‘set-access-rule’ command). \n\u003cbr\u003e\u0026emsp;- Add ‘new-position’ argument to existing command and set it to bottom.\n\n\u003cbr\u003e\u0026emsp;\u0026emsp;\u0026emsp;Before:\n```python\n# Set rule changes\n# *** If you wold like to your logic as part of rule disabling. This is the place ***\n# *** For example: set rule position to bottom, you need add to API call 'new-position' parameter with value bottom.***\ndef disable_rule(rule, layer, api_client):\n    global DATETIME_NOW\n    global DATETIME_FORMAT\n\n    # Disable rule \u0026 set disabled-time \u0026 add comment\n    set_rule_res = api_client.api_call(\"set-access-rule\",\n                                       {\"uid\": rule['uid'], \"layer\": layer['uid'], \"enabled\": \"false\",\n                                        \"custom-fields\": {\"field-3\": DATETIME_NOW.strftime(DATETIME_FORMAT)},\n                                        \"comments\": rule['comments'] + \" -This rule changed automatically by the policyCleanUp tool\"})\n\n    return not is_failure(\"    Failed to set rule No.{} with UID {}.\".format(rule['rule-number'], rule['uid']), set_rule_res)\n\n```\n\u003cbr\u003e\u0026emsp;\u0026emsp;\u0026emsp;After:\n```python\n# Set rule changes\n# *** If you wold like to your logic as part of rule disabling. This is the place ***\n# *** For example: set rule position to bottom, you need add to API call 'new-position' parameter with value bottom.***\ndef disable_rule(rule, layer, api_client):\n    global DATETIME_NOW\n    global DATETIME_FORMAT\n\n    # Disable rule \u0026 set disabled-time \u0026 add comment\n    set_rule_res = api_client.api_call(\"set-access-rule\",\n                                       {\"uid\": rule['uid'], \"layer\": layer['uid'], \"enabled\": \"false\",\n                                        \"custom-fields\": {\"field-3\": DATETIME_NOW.strftime(DATETIME_FORMAT)},\n                                        \"comments\": rule['comments'] + \" -This rule changed automatically by the policyCleanUp tool\",\n                                        \"new-position\": \"bottom\"})\n\n    return not is_failure(\"    Failed to set rule No.{} with UID {}.\".format(rule['rule-number'], rule['uid']), set_rule_res)\n\n```\n\n\u003cb\u003eNotice!\u003c/b\u003e The tool uses the custom fields of rule (within SmartConsole - \u003ci\u003eSecurity Policies \u003e Access Control \u003e Policy \u003e Summary tab\u003c/i\u003e) \n\n## Development Environment\nThe tool is developed using Python language 2.7.14 and [Check Point API Python SDK](https://github.com/CheckPointSW/cp_mgmt_api_python_sdk).\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcheckpointsw%2Fpolicycleanup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcheckpointsw%2Fpolicycleanup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcheckpointsw%2Fpolicycleanup/lists"}