{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Palo Alto Cortex XDR Distribution","description":"Control the power of AI Agents in runtime.","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"palo-alto-cortex-xdr-distribution","__idx":0},"children":["Palo Alto Cortex XDR Distribution"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Deploy Capsule Security hooks for AI coding assistants across your fleet using Palo Alto Cortex XDR or Cortex XSIAM as the delivery channel. This guide covers deployment for Cursor, Devin (Windsurf), GitHub Copilot, Claude Code, and Codex on both Windows and macOS using the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Agent Script Library"]}," and the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Run Endpoint Script"]}," action."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Cortex XDR is not an MDM. It has no policy engine that applies a configuration continuously to every device that joins your fleet - what it has is a one-shot response action that runs a script on the endpoints you select. Everything in this guide is built on that action, so read ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#key-considerations"},"children":["Key Considerations"]}," before planning a rollout."]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This guide is about using Cortex XDR to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["push Capsule hooks to endpoints"]},". It is unrelated to the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/cortex-xdr"},"children":["Palo Alto Cortex XDR Integration"]}," guide, which connects your Cortex tenant to Capsule as a read-only data source for device inventory and shadow-AI discovery. The two can be used together or independently."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"prerequisites","__idx":1},"children":["Prerequisites"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Access to the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Cortex XDR"]}," or ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Cortex XSIAM"]}," console"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["On Cortex XDR, a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Cortex XDR Pro per Endpoint"]}," license - script execution is unavailable on a Prevent tenant. Palo Alto states no equivalent license gate for Cortex XSIAM"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Cortex XDR agent ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["7.1 or later"]}," on every target endpoint"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Agent Script Library"]}," permission at ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["View/Edit"]},", with the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Run High Risk Scripts"]}," and ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Script Configurations"]}," action checkboxes. Companion permissions: ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Action Center"]}," at View (without it the Script Library page is unreachable) and ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Agent Administrations"]}," at View (required to select endpoints)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["subprocess"]}," present in the supported-modules list shown in the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["New Script"]}," dialog. Cortex parses every uploaded script and rejects any that imports a module outside that list, and the list is only visible in the dialog itself. Open the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["supported modules"]}," link there and confirm ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["subprocess"]}," is listed before you build a rollout on the wrapper pattern below"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Script execution still enabled on the target agents. It is disabled permanently if the agent was installed with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["RESTRICT_SCRIPT_EXECUTION=1"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["RESTRICT_RESPONSE_ACTIONS=1"]},", or was later disabled through Endpoint Administration. Re-enabling requires reinstalling the agent"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Capsule Security"]}," account with admin access"]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"how-cortex-runs-these-scripts","__idx":2},"children":["How Cortex Runs These Scripts"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"three-different-things-in-cortex-are-called-scripts","__idx":3},"children":["Three different things in Cortex are called \"scripts\""]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Only the first one reaches an endpoint."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Feature"},"children":["Feature"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Where it runs"},"children":["Where it runs"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Use it here?"},"children":["Use it here?"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Agent Script Library"]}," (Investigation & Response > Response > Action Center)"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["On the endpoint, via the agent. Python 3.7 only"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes - this is the fleet channel"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Live Terminal > Command Line"]}," (Investigation & Response > Response)"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["On the endpoint, interactively. PowerShell 5.0 or later on Windows, the shell on macOS"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["For testing one machine, see below"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Automation > Scripts"]}," (Investigation & Response > Automation)"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["On the Cortex server, in a Docker container. JavaScript, Python, or PowerShell"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No - it never touches an endpoint"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Agent Script Library accepts ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Python 3.7 scripts only"]},". You cannot upload a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".ps1"]}," or a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".sh"]}," file to it, and there is no language selector in the upload dialog. Capsule's deployment artifacts are PowerShell and bash, so each one travels inside a short Python wrapper that writes it to a file on the endpoint and executes it."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Scripts run as ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["SYSTEM"]}," on Windows and as ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["root"]}," on macOS. Environment variables and per-user paths are therefore not the signed-in user's, and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["HKEY_CURRENT_USER"]}," is unreachable."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"the-python-wrapper","__idx":4},"children":["The Python wrapper"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Paste the product's PowerShell or bash script from the sections below in place of the placeholder. Both wrappers print the wrapped script's output so it appears under ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Standard output"]}," in the results table, run the child process with empty stdin so it never hangs waiting for input, print the exit code, and raise on a non-zero exit so Cortex marks the endpoint ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Failed"]},". A script that expects input reads nothing and ends early, and it can still exit 0, so a green result alone does not prove anything was installed."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Windows"]}," (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["capsule-deploy-windows.py"]},"):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"import os\nimport subprocess\n\nSCRIPT = r\"\"\"\n<PASTE THE PRODUCT'S WINDOWS POWERSHELL SCRIPT HERE>\n\"\"\"\n\nscript_path = \"C:/Windows/Temp/capsule-deploy.ps1\"\n\nwith open(script_path, \"w\", encoding=\"utf-8-sig\") as handle:\n    handle.write(SCRIPT)\n\nreturncode = 1\ntry:\n    result = subprocess.run(\n        [\"powershell.exe\", \"-NoProfile\", \"-NonInteractive\", \"-ExecutionPolicy\", \"Bypass\", \"-File\", script_path],\n        stdin=subprocess.DEVNULL,\n        stdout=subprocess.PIPE,\n        stderr=subprocess.STDOUT,\n        timeout=540,\n    )\n    print(result.stdout.decode(\"utf-8\", \"replace\"))\n    returncode = result.returncode\nexcept subprocess.TimeoutExpired as error:\n    if error.output:\n        print(error.output.decode(\"utf-8\", \"replace\"))\n    print(\"Capsule: script did not finish within 540 seconds\")\nfinally:\n    os.remove(script_path)\n\nprint(\"Capsule: exit code %d\" % returncode)\nif returncode != 0:\n    raise SystemExit(\"Capsule deployment failed with exit code %d\" % returncode)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["macOS"]}," (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["capsule-deploy-macos.py"]},"):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"import os\nimport subprocess\n\nSCRIPT = r\"\"\"\n<PASTE THE PRODUCT'S MACOS BASH SCRIPT HERE>\n\"\"\"\n\nscript_dir = \"/var/tmp/capsule\"\nscript_path = script_dir + \"/capsule-deploy.sh\"\n\nos.makedirs(script_dir, exist_ok=True)\nos.chmod(script_dir, 0o700)\n\nwith open(script_path, \"w\", encoding=\"utf-8\") as handle:\n    handle.write(SCRIPT)\nos.chmod(script_path, 0o700)\n\nreturncode = 1\ntry:\n    result = subprocess.run(\n        [\"/bin/bash\", script_path],\n        stdin=subprocess.DEVNULL,\n        stdout=subprocess.PIPE,\n        stderr=subprocess.STDOUT,\n        timeout=540,\n    )\n    print(result.stdout.decode(\"utf-8\", \"replace\"))\n    returncode = result.returncode\nexcept subprocess.TimeoutExpired as error:\n    if error.output:\n        print(error.output.decode(\"utf-8\", \"replace\"))\n    print(\"Capsule: script did not finish within 540 seconds\")\nfinally:\n    os.remove(script_path)\n\nprint(\"Capsule: exit code %d\" % returncode)\nif returncode != 0:\n    raise SystemExit(\"Capsule deployment failed with exit code %d\" % returncode)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The wrapped script is held in a Python raw triple-quoted string, so it must not itself contain the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"\"\""]}," sequence. Capsule's configuration files and companion scripts do not. Every payload in this guide is embedded in the script you upload, so the wrapper downloads nothing and needs no network access from the endpoint."]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Both wrappers import only ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["os"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["subprocess"]},". Cortex rejects a script that imports a module outside its supported list, and that list is shown only in the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["New Script"]}," dialog - follow its ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["supported modules"]}," link and confirm ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["subprocess"]}," is listed before you upload."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"uploading-the-script","__idx":5},"children":["Uploading the script"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Navigate to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Investigation & Response > Response > Action Center > Agent Script Library"]}," (the grid is called ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Scripts Library"]}," in Cortex XSIAM)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Click ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["New Script"]}," and drag in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".py"]}," wrapper file. Cortex parses it for unsupported modules and indentation problems, and offers an in-product editor if it finds either"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Complete the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["General"]}," step with the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Name"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Description"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Platform"]},", and ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Timeout"]}," values given in each product section. Set ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Outcome"]}," to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["High Risk"]},": these scripts write files and change system configuration, which is Palo Alto's own definition of a high-risk script, so the running role needs the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Run High Risk Scripts"]}," permission"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["On the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Input"]}," step choose ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Just run"]},", which executes the script line by line. No entry point or parameters are needed"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Leave the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Output"]}," step empty. Progress is reported through ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["stdout"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can also upload the script and its definitions together as a single-line JSON manifest. The manifest must contain no newline or tab characters or validation fails:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\"name\":\"Capsule Security - Cursor Hooks (Windows)\",\"description\":\"Deploys the Capsule Security hooks configuration for Cursor\",\"outcome\":\"High Risk\",\"platform\":\"Windows\",\"timeout\":600,\"entry_point\":\"\",\"entry_point_definition\":{}}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["platform"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Windows"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["macOS"]},". A script with both targets takes ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"Windows,macOS\""]},", but the payloads here are OS-specific, so upload one script per OS."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"running-the-action","__idx":6},"children":["Running the action"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Navigate to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Investigation & Response > Response > Action Center"]}," and click ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["New Action"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Select ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Run Endpoint Script"]}," and pick the script you uploaded. You can also right-click the script in the Scripts Library and choose ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Run"]},", which opens the Action Center with the script already populated"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Select the target endpoints. Cortex displays only the endpoints eligible for the action, based on the script's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["platform"]}," value, and tells you which agents in your scope will be skipped. Narrow the endpoint list first using ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Group Names"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Operating System"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["OS Version"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Agent Version"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Tags"]},", or ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Active Directory"]}," groups and organizational units, then select the rows"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Review the summary and click ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Done"]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"live-terminal-single-endpoint","__idx":7},"children":["Live Terminal (single endpoint)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Before running a fleet action, test the same PowerShell or bash on one machine. Live Terminal runs it directly, with no Python wrapper and no upload."]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Navigate to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Inventory > Endpoints > All Endpoints"]},", right-click the endpoint, and select ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Security Operations > Initiate Live Terminal"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Select ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Command Line"]},". This runs PowerShell 5.0 or later on Windows and the shell on macOS"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Paste the product's script, or upload it as a file, and press ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Shift + Enter"]}," to run it. Chain multiple commands with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["&&"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A payload that works in Live Terminal can still fail under the Agent Script Library, which runs as SYSTEM or root with no user session, so always run the wrapped script against one endpoint through Run Endpoint Script before you start a fleet wave. Live Terminal is one endpoint per session with no multi-select and no API, so it is a test and troubleshooting tool, not a deployment channel. On Windows it needs Traps 6.1 or later, Windows 7 SP1 or later, and the WinCRT patch KB 2999226. On macOS it needs Cortex XDR agent 7.0 or later and macOS 10.12 or later. On either, the endpoint must have reported activity within the last 90 minutes."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"cursor","__idx":8},"children":["Cursor"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Deploy the Cursor hooks configuration with a Run Endpoint Script action."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-1-download-the-configuration","__idx":9},"children":["Step 1: Download the Configuration"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Log in to the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Capsule Security"]}," portal"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Navigate to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Settings > Integrations"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Locate the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Cursor"]}," integration"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Download the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hooks.json"]}," file"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"cortex-xdr-deployment","__idx":10},"children":["Cortex XDR Deployment"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upload one script per OS, following ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#uploading-the-script"},"children":["Uploading the script"]},", then run it as described in ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#running-the-action"},"children":["Running the action"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Windows"]}," - Name ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule Security - Cursor Hooks (Windows)"]},", platform ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Windows"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\"name\":\"Capsule Security - Cursor Hooks (Windows)\",\"description\":\"Deploys the Capsule Security hooks configuration for Cursor\",\"outcome\":\"High Risk\",\"platform\":\"Windows\",\"timeout\":600,\"entry_point\":\"\",\"entry_point_definition\":{}}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Wrap this PowerShell in the Windows wrapper, replacing the placeholder with the contents of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hooks.json"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"powershell","header":{"controls":{"copy":{}}},"source":"$hooksDir = \"C:\\ProgramData\\Cursor\"\n$hooksFile = \"$hooksDir\\hooks.json\"\n\n$payload = @'\n<PASTE YOUR HOOKS.JSON CONTENT HERE>\n'@\n\nif (-not (Test-Path $hooksDir)) {\n    New-Item -ItemType Directory -Path $hooksDir -Force | Out-Null\n}\n\n[System.IO.File]::WriteAllText($hooksFile, $payload, [System.Text.UTF8Encoding]::new($false))\n\nWrite-Output \"Capsule: wrote Cursor hooks configuration to $hooksFile\"\nexit 0\n","lang":"powershell"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["macOS"]}," - Name ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule Security - Cursor Hooks (macOS)"]},", platform ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["macOS"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\"name\":\"Capsule Security - Cursor Hooks (macOS)\",\"description\":\"Deploys the Capsule Security hooks configuration for Cursor on macOS\",\"outcome\":\"High Risk\",\"platform\":\"macOS\",\"timeout\":600,\"entry_point\":\"\",\"entry_point_definition\":{}}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Wrap this bash in the macOS wrapper, replacing the placeholder with the contents of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hooks.json"]}," and keeping the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CAPSULE_EOF"]}," marker lines unchanged and unindented:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"#!/bin/bash\nset -e\nHOOKS_DIR=\"/Library/Application Support/Cursor\"\nmkdir -p \"$HOOKS_DIR\"\ncat > \"$HOOKS_DIR/hooks.json\" << 'CAPSULE_EOF'\n<PASTE YOUR HOOKS.JSON CONTENT HERE>\nCAPSULE_EOF\nchmod 644 \"$HOOKS_DIR/hooks.json\"\necho \"Capsule: wrote Cursor hooks configuration to $HOOKS_DIR/hooks.json\"\nexit 0\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"verification","__idx":11},"children":["Verification"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After deployment, restart Cursor on target devices, then:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Open Cursor Settings"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Navigate to the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Hooks"]}," tab"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Confirm the hooks are listed and enabled"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"uninstall","__idx":12},"children":["Uninstall"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Cortex cannot take a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".ps1"]}," or a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".sh"]}," file, so wrap the removal script below in the same ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#the-python-wrapper"},"children":["Python wrapper"]}," and upload it as a second library script, for example ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule Security - Cursor hooks removal"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upload and run a second script that deletes the file this deployment wrote. Each delete is conditional on the file still carrying Capsule's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/cursor/hooks/events"]}," marker, so a device where someone replaced the file with their own hooks keeps it. That marker check is the only thing standing between the delete and a file you own, because nothing is copied aside first."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"powershell","header":{"controls":{"copy":{}}},"source":"$path = 'C:\\ProgramData\\Cursor\\hooks.json'\nif ((Test-Path -LiteralPath $path) -and ((Get-Content -LiteralPath $path -Raw) -like '*/cursor/hooks/events*')) {\n    Remove-Item -LiteralPath $path -Force\n    Write-Output \"Capsule: removed $path\"\n}\nexit 0\n","lang":"powershell"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"#!/bin/bash\nFILE=\"/Library/Application Support/Cursor/hooks.json\"\nif grep -qF '/cursor/hooks/events' \"$FILE\" 2>/dev/null; then\n    rm -f \"$FILE\"\n    echo \"Capsule: removed $FILE\"\nfi\nexit 0\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"devin-windsurf","__idx":13},"children":["Devin (Windsurf)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Deploy the Devin (Windsurf) hooks configuration with a Run Endpoint Script action. Cascade merges hook configurations from the system, user, and workspace levels (",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://docs.devin.ai/desktop/cascade/hooks"},"children":["Cascade hooks documentation"]},"), so deploying to the system-level path applies the Capsule hooks to every user on the device, and they cannot be disabled by end users."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-1-download-the-configuration-1","__idx":14},"children":["Step 1: Download the Configuration"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Log in to the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Capsule Security"]}," portal"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Navigate to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Settings > Integrations"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Locate the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Devin (Windsurf)"]}," integration"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["For Windows endpoints, select ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Windows"]}," and extract the downloaded ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["capsule-windsurf-managed.zip"]}," (contains ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hooks.json"]}," and the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CapsuleWindsurfHook.ps1"]}," companion script)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["For macOS endpoints, select ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Mac"]}," and download the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hooks.json"]}," file"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"cortex-xdr-deployment-1","__idx":15},"children":["Cortex XDR Deployment"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upload one script per OS, following ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#uploading-the-script"},"children":["Uploading the script"]},", then run it as described in ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#running-the-action"},"children":["Running the action"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Windows"]}," - Name ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule Security - Devin (Windsurf) Hooks (Windows)"]},", platform ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Windows"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\"name\":\"Capsule Security - Devin (Windsurf) Hooks (Windows)\",\"description\":\"Deploys the Capsule Security hooks configuration for Devin (Windsurf)\",\"outcome\":\"High Risk\",\"platform\":\"Windows\",\"timeout\":600,\"entry_point\":\"\",\"entry_point_definition\":{}}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hooks.json"]}," invokes the companion script by path, so both files must be written. Replace each placeholder in the installer below with the contents of the matching file from the archive, then copy the whole installer, start to finish, and paste it into the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#the-python-wrapper"},"children":["Windows wrapper"]},"'s own placeholder - upload the resulting wrapper script, not the installer by itself:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"powershell","header":{"controls":{"copy":{}}},"source":"$ErrorActionPreference = \"Stop\"\n\nfunction Write-CapsuleFile($path, $content) {\n    $parentDir = Split-Path -Path $path -Parent\n    if (-not (Test-Path -Path $parentDir)) {\n        New-Item -ItemType Directory -Path $parentDir -Force | Out-Null\n    }\n    [System.IO.File]::WriteAllText($path, $content, [System.Text.UTF8Encoding]::new($false))\n    Write-Output \"Capsule: wrote $path\"\n}\n\n$hookScript = @'\n<PASTE YOUR CapsuleWindsurfHook.ps1 CONTENT HERE>\n'@\nWrite-CapsuleFile 'C:\\ProgramData\\Capsule\\WindsurfHooks\\CapsuleWindsurfHook.ps1' $hookScript\n\n$hooksJson = @'\n<PASTE YOUR HOOKS.JSON CONTENT HERE>\n'@\nWrite-CapsuleFile 'C:\\ProgramData\\Windsurf\\hooks.json' $hooksJson\n\nexit 0\n","lang":"powershell"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["macOS"]}," - Name ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule Security - Devin (Windsurf) Hooks (macOS)"]},", platform ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["macOS"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\"name\":\"Capsule Security - Devin (Windsurf) Hooks (macOS)\",\"description\":\"Deploys the Capsule Security hooks configuration for Devin (Windsurf) on macOS\",\"outcome\":\"High Risk\",\"platform\":\"macOS\",\"timeout\":600,\"entry_point\":\"\",\"entry_point_definition\":{}}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Wrap this bash in the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#the-python-wrapper"},"children":["macOS wrapper"]},", replacing the placeholder with the contents of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hooks.json"]}," and keeping the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CAPSULE_EOF"]}," marker lines unchanged and unindented:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"#!/bin/bash\nset -e\nHOOKS_DIR=\"/Library/Application Support/Windsurf\"\nmkdir -p \"$HOOKS_DIR\"\ncat > \"$HOOKS_DIR/hooks.json\" << 'CAPSULE_EOF'\n<PASTE YOUR HOOKS.JSON CONTENT HERE>\nCAPSULE_EOF\nchmod 644 \"$HOOKS_DIR/hooks.json\"\necho \"Capsule: wrote Devin (Windsurf) hooks configuration to $HOOKS_DIR/hooks.json\"\nexit 0\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"verification-1","__idx":16},"children":["Verification"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Hooks are loaded at application start, so after deployment, close Devin Desktop completely on target devices and reopen it, then:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Start a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Cascade"]}," session and run a simple task to generate activity"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["In the Capsule portal, navigate to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Inventory > Agents"]}," and confirm the agent appears"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"uninstall-1","__idx":17},"children":["Uninstall"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Cortex cannot take a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".ps1"]}," or a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".sh"]}," file, so wrap the removal script below in the same ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#the-python-wrapper"},"children":["Python wrapper"]}," and upload it as a second library script, for example ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule Security - Windsurf hooks removal"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upload and run a second script that deletes the files this deployment wrote. Each delete is conditional on the file still carrying Capsule's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/windsurf/hooks/events"]}," marker. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CapsuleWindsurfHook.ps1"]}," and the directories holding it are Capsule's own, and those directories are removed once empty, innermost first. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["C:\\ProgramData\\Windsurf"]}," is the product's own directory and stays."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"powershell","header":{"controls":{"copy":{}}},"source":"$config = 'C:\\ProgramData\\Windsurf\\hooks.json'\n$hookScript = 'C:\\ProgramData\\Capsule\\WindsurfHooks\\CapsuleWindsurfHook.ps1'\n\nforeach ($path in @($config, $hookScript)) {\n    if ((Test-Path -LiteralPath $path) -and ((Get-Content -LiteralPath $path -Raw) -like '*/windsurf/hooks/events*')) {\n        Remove-Item -LiteralPath $path -Force\n        Write-Output \"Capsule: removed $path\"\n    }\n}\n\nforeach ($dir in @('C:\\ProgramData\\Capsule\\WindsurfHooks', 'C:\\ProgramData\\Capsule')) {\n    if ((Test-Path -LiteralPath $dir) -and -not (Get-ChildItem -LiteralPath $dir -Force)) {\n        Remove-Item -LiteralPath $dir -Force\n    }\n}\nexit 0\n","lang":"powershell"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"#!/bin/bash\nFILE=\"/Library/Application Support/Windsurf/hooks.json\"\nif grep -qF '/windsurf/hooks/events' \"$FILE\" 2>/dev/null; then\n    rm -f \"$FILE\"\n    echo \"Capsule: removed $FILE\"\nfi\nexit 0\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"github-copilot","__idx":18},"children":["GitHub Copilot"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Deploy the GitHub Copilot hooks configuration with a Run Endpoint Script action. GitHub Copilot reads its hooks from a per-user directory, and Cortex runs every script as SYSTEM or root, so the scripts below iterate over the user profiles present on the device."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-1-download-the-configuration-2","__idx":19},"children":["Step 1: Download the Configuration"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Log in to the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Capsule Security"]}," portal"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Navigate to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Settings > Integrations"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Locate the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["GitHub Copilot"]}," integration"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Download the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["capsule-hooks.json"]}," file"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"cortex-xdr-deployment-2","__idx":20},"children":["Cortex XDR Deployment"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upload one script per OS, following ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#uploading-the-script"},"children":["Uploading the script"]},", then run it as described in ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#running-the-action"},"children":["Running the action"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Windows"]}," - Name ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule Security - GitHub Copilot Hooks (Windows)"]},", platform ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Windows"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\"name\":\"Capsule Security - GitHub Copilot Hooks (Windows)\",\"description\":\"Deploys the Capsule Security hooks configuration for GitHub Copilot in VS Code\",\"outcome\":\"High Risk\",\"platform\":\"Windows\",\"timeout\":600,\"entry_point\":\"\",\"entry_point_definition\":{}}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Wrap this PowerShell in the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#the-python-wrapper"},"children":["Windows wrapper"]},", replacing the placeholder with the contents of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["capsule-hooks.json"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"powershell","header":{"controls":{"copy":{}}},"source":"$payload = @'\n<PASTE YOUR CAPSULE-HOOKS.JSON CONTENT HERE>\n'@\n\n$utf8NoBom = [System.Text.UTF8Encoding]::new($false)\n$userProfiles = Get-ChildItem \"C:\\Users\" -Directory | Where-Object { $_.Name -notin @('Public', 'Default', 'Default User') }\n\nforeach ($userProfile in $userProfiles) {\n    $hooksDir = Join-Path $userProfile.FullName \"AppData\\Roaming\\Code\\User\\hooks\"\n    if (-not (Test-Path $hooksDir)) {\n        New-Item -ItemType Directory -Path $hooksDir -Force | Out-Null\n    }\n    [System.IO.File]::WriteAllText((Join-Path $hooksDir 'capsule-hooks.json'), $payload, $utf8NoBom)\n}\n\nWrite-Output \"Capsule: wrote GitHub Copilot hooks configuration for $($userProfiles.Count) user profile(s)\"\nexit 0\n","lang":"powershell"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["macOS"]}," - Name ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule Security - GitHub Copilot Hooks (macOS)"]},", platform ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["macOS"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\"name\":\"Capsule Security - GitHub Copilot Hooks (macOS)\",\"description\":\"Deploys the Capsule Security hooks configuration for GitHub Copilot on macOS\",\"outcome\":\"High Risk\",\"platform\":\"macOS\",\"timeout\":600,\"entry_point\":\"\",\"entry_point_definition\":{}}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Wrap this bash in the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#the-python-wrapper"},"children":["macOS wrapper"]},", replacing the placeholder with the contents of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["capsule-hooks.json"]}," and keeping the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CAPSULE_EOF"]}," marker lines unchanged and unindented:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"#!/bin/bash\nPAYLOAD=$(cat << 'CAPSULE_EOF'\n<PASTE YOUR CAPSULE-HOOKS.JSON CONTENT HERE>\nCAPSULE_EOF\n)\n\nfor USER_HOME in /Users/*/; do\n    USERNAME=$(basename \"$USER_HOME\")\n    if [ \"$USERNAME\" = \"Shared\" ] || [ \"$USERNAME\" = \".localized\" ]; then\n        continue\n    fi\n    HOOKS_DIR=\"$USER_HOME/Library/Application Support/Code/User/hooks\"\n    mkdir -p \"$HOOKS_DIR\"\n    printf '%s\\n' \"$PAYLOAD\" > \"$HOOKS_DIR/capsule-hooks.json\"\n    chmod 644 \"$HOOKS_DIR/capsule-hooks.json\"\n    chown \"$USERNAME\" \"$HOOKS_DIR/capsule-hooks.json\"\n    echo \"Capsule: wrote $HOOKS_DIR/capsule-hooks.json\"\ndone\nexit 0\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"verification-2","__idx":21},"children":["Verification"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After deployment, restart VS Code on target devices, then:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Right-click in the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Chat"]}," view and select ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Diagnostics"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Confirm the hooks are loaded and enabled"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"uninstall-2","__idx":22},"children":["Uninstall"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Cortex cannot take a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".ps1"]}," or a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".sh"]}," file, so wrap the removal script below in the same ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#the-python-wrapper"},"children":["Python wrapper"]}," and upload it as a second library script, for example ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule Security - GitHub Copilot hooks removal"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upload and run a second script that deletes the files this deployment wrote, across the same user profiles. Each delete is conditional on the file still carrying Capsule's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/github-copilot/hooks/events"]}," marker. Leave the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hooks"]}," directory in place: it is Copilot's, not one Capsule created."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"powershell","header":{"controls":{"copy":{}}},"source":"$userProfiles = Get-ChildItem \"C:\\Users\" -Directory | Where-Object { $_.Name -notin @('Public', 'Default', 'Default User') }\n\nforeach ($userProfile in $userProfiles) {\n    $path = Join-Path $userProfile.FullName \"AppData\\Roaming\\Code\\User\\hooks\\capsule-hooks.json\"\n    if ((Test-Path -LiteralPath $path) -and ((Get-Content -LiteralPath $path -Raw) -like '*/github-copilot/hooks/events*')) {\n        Remove-Item -LiteralPath $path -Force\n        Write-Output \"Capsule: removed $path\"\n    }\n}\nexit 0\n","lang":"powershell"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"#!/bin/bash\nfor USER_HOME in /Users/*/; do\n    FILE=\"$USER_HOME/Library/Application Support/Code/User/hooks/capsule-hooks.json\"\n    if grep -qF '/github-copilot/hooks/events' \"$FILE\" 2>/dev/null; then\n        rm -f \"$FILE\"\n        echo \"Capsule: removed $FILE\"\n    fi\ndone\nexit 0\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"claude-code","__idx":23},"children":["Claude Code"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Deploy the Claude Code managed settings configuration with a Run Endpoint Script action. On Windows every Capsule hook command in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["managed-settings.json"]}," invokes an external dispatcher by path, so deployment writes ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["two"]}," files - ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["managed-settings.json"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["C:\\Program Files\\ClaudeCode\\"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["capsule-hook.ps1"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["C:\\Program Files\\ClaudeCode\\hooks\\"]},". macOS writes the one settings file. Both platforms write each file wholesale, replacing whatever is at that path."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-1-download-the-configuration-3","__idx":24},"children":["Step 1: Download the Configuration"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Log in to the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Capsule Security"]}," portal"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Navigate to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Settings > Integrations"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Locate the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Claude Code"]}," integration"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Click ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Install"]}," and select your target platform"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["For Windows endpoints, download the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["capsule-claude-code-windows.zip"]}," archive Capsule generates: it contains ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["managed-settings.json"]}," and the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hooks\\capsule-hook.ps1"]}," dispatcher it invokes"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["For macOS endpoints, download the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["managed-settings.json"]}," file"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"cortex-xdr-deployment-3","__idx":25},"children":["Cortex XDR Deployment"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upload one script per OS, following ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#uploading-the-script"},"children":["Uploading the script"]},", then run it as described in ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#running-the-action"},"children":["Running the action"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Windows"]}," - Name ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule Security - Claude Code Hooks (Windows)"]},", platform ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Windows"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\"name\":\"Capsule Security - Claude Code Hooks (Windows)\",\"description\":\"Deploys the Capsule Security managed settings for Claude Code\",\"outcome\":\"High Risk\",\"platform\":\"Windows\",\"timeout\":600,\"entry_point\":\"\",\"entry_point_definition\":{}}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Every Capsule hook command in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["managed-settings.json"]}," runs ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["powershell -NoP -Exec Bypass -File \"C:\\Program Files\\ClaudeCode\\hooks\\capsule-hook.ps1\""]},", so both files must be written - deploying ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["managed-settings.json"]}," alone would leave every hook pointing at a script that was never installed."]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Never paste ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["capsule-hook.ps1"]}," into the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#the-python-wrapper"},"children":["Windows wrapper"]}," on its own, and never upload or run it by itself."]}," It is Claude Code's hook dispatcher, not an installer: it expects a hook call on stdin, so run any other way it either waits for input until Cortex's timeout or, given no input, exits 0 without writing anything, and the endpoint reports success with neither file installed. It belongs only inside the installer below, which writes it to disk and never runs it."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Build the script in this order:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Extract the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["capsule-claude-code-windows.zip"]}," archive from Step 1. It holds ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["managed-settings.json"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hooks\\capsule-hook.ps1"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["In the installer below, replace ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<PASTE YOUR managed-settings.json CONTENT HERE>"]}," with the full contents of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["managed-settings.json"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<PASTE YOUR hooks\\capsule-hook.ps1 CONTENT HERE>"]}," with the full contents of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hooks\\capsule-hook.ps1"]},". Replace only the placeholder lines, and keep the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["$content0 = @'"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["$content1 = @'"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["'@"]}," lines around them unchanged. PowerShell requires each closing ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["'@"]}," to start at column 0, with nothing before it on its line"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Copy the whole installer, start to finish, and paste it into the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#the-python-wrapper"},"children":["Windows wrapper"]},"'s ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<PASTE THE PRODUCT'S WINDOWS POWERSHELL SCRIPT HERE>"]}," placeholder"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Upload the resulting wrapper script, not the installer by itself, and run it"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This is the installer Capsule's own Windows distribution generates, with the two file contents left as placeholders:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"powershell","header":{"controls":{"copy":{}}},"source":"$ErrorActionPreference = \"Stop\"\nfunction Write-CapsuleFile($path, $content, $label) {\n  $content = $content.Replace(\"`r`n\", \"`n\")\n  $parentDir = Split-Path -LiteralPath $path\n  if (-not (Test-Path -LiteralPath $parentDir)) {\n    New-Item -ItemType Directory -Path $parentDir -Force | Out-Null\n  }\n  $utf8NoBom = New-Object System.Text.UTF8Encoding($false)\n  [System.IO.File]::WriteAllText($path, $content, $utf8NoBom)\n  Write-Output \"Capsule: wrote $label to $path\"\n}\ntry {\n  $content0 = @'\n<PASTE YOUR managed-settings.json CONTENT HERE>\n'@\n  Write-CapsuleFile 'C:\\Program Files\\ClaudeCode\\managed-settings.json' $content0 'Claude Code managed settings'\n  $content1 = @'\n<PASTE YOUR hooks\\capsule-hook.ps1 CONTENT HERE>\n'@\n  Write-CapsuleFile 'C:\\Program Files\\ClaudeCode\\hooks\\capsule-hook.ps1' $content1 'Claude Code hooks/capsule-hook.ps1'\n  exit 0\n} catch {\n  Write-Error \"Capsule: failed to write managed hook files. $_\"\n  exit 1\n}\n","lang":"powershell"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["macOS"]}," - Name ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule Security - Claude Code Hooks (macOS)"]},", platform ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["macOS"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\"name\":\"Capsule Security - Claude Code Hooks (macOS)\",\"description\":\"Deploys the Capsule Security managed settings for Claude Code on macOS\",\"outcome\":\"High Risk\",\"platform\":\"macOS\",\"timeout\":600,\"entry_point\":\"\",\"entry_point_definition\":{}}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Wrap this bash in the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#the-python-wrapper"},"children":["macOS wrapper"]},", replacing the placeholder with the contents of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["managed-settings.json"]}," and keeping the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CAPSULE_EOF"]}," marker lines unchanged and unindented:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"#!/bin/bash\nset -e\nSETTINGS_DIR=\"/Library/Application Support/ClaudeCode\"\nmkdir -p \"$SETTINGS_DIR\"\ncat > \"$SETTINGS_DIR/managed-settings.json\" << 'CAPSULE_EOF'\n<PASTE YOUR MANAGED-SETTINGS.JSON CONTENT HERE>\nCAPSULE_EOF\nchmod 644 \"$SETTINGS_DIR/managed-settings.json\"\necho \"Capsule: wrote Claude Code managed settings to $SETTINGS_DIR/managed-settings.json\"\nexit 0\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"verification-3","__idx":26},"children":["Verification"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["On Windows, a successful run's ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Standard output"]}," shows two ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule: wrote ..."]}," lines, one per file:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"text","header":{"controls":{"copy":{}}},"source":"Capsule: wrote Claude Code managed settings to C:\\Program Files\\ClaudeCode\\managed-settings.json\nCapsule: wrote Claude Code hooks/capsule-hook.ps1 to C:\\Program Files\\ClaudeCode\\hooks\\capsule-hook.ps1\n","lang":"text"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A green run without both lines means the wrong script was pasted into the wrapper: upload the installer above, wrapped, and run it again."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After deployment, restart Claude Code on target devices, then:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Run ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/hooks"]}," in Claude Code to confirm all hooks are listed"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Start a session and verify events appear in the Capsule Security portal"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"uninstall-3","__idx":27},"children":["Uninstall"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Cortex cannot take a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".ps1"]}," or a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".sh"]}," file, so wrap the removal script below in the same ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#the-python-wrapper"},"children":["Python wrapper"]}," and upload it as a second library script, for example ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule Security - Claude Code hooks removal"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["managed-settings.json"]}," is Claude Code's enterprise policy file. This deployment wrote the whole file, so the reversal deletes the whole file - but only while it still carries a Capsule marker, so a file an admin has since rewritten with their own policy is left alone. The Windows removal takes both files and matches on ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["capsule-hook.ps1"]}," as well as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["capsulesecurity"]},", because every Capsule entry in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["managed-settings.json"]}," runs the dispatcher and the Capsule endpoint lives inside that script rather than in the settings file."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"powershell","header":{"controls":{"copy":{}}},"source":"$paths = @(\n    'C:\\Program Files\\ClaudeCode\\managed-settings.json',\n    'C:\\Program Files\\ClaudeCode\\hooks\\capsule-hook.ps1'\n)\nforeach ($path in $paths) {\n    if ((Test-Path -LiteralPath $path) -and ((Get-Content -LiteralPath $path -Raw) -match 'capsulesecurity|capsule-hook\\.ps1')) {\n        Remove-Item -LiteralPath $path -Force\n        Write-Output \"Capsule: removed $path\"\n    }\n}\nexit 0\n","lang":"powershell"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"#!/bin/bash\nFILE=\"/Library/Application Support/ClaudeCode/managed-settings.json\"\nif grep -qF 'capsulesecurity' \"$FILE\" 2>/dev/null; then\n    rm -f \"$FILE\"\n    echo \"Capsule: removed $FILE\"\nfi\nexit 0\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you merged Capsule's hooks into a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["managed-settings.json"]}," your organization already owned, do not run this. Edit the file to drop only the Capsule hook entries instead."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"codex","__idx":28},"children":["Codex"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Deploy the Codex ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://developers.openai.com/codex/enterprise/managed-configuration"},"children":["managed configuration"]}," with a Run Endpoint Script action. Codex reads a managed ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["requirements.toml"]}," from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/etc/codex/requirements.toml"]}," (macOS) or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["%ProgramData%\\OpenAI\\Codex\\requirements.toml"]}," (Windows); because the configuration is managed, the Capsule hooks are trusted by policy, apply to every user on the device (including users created later), and cannot be overridden or removed by users. No per-user trust approval is required."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-1-download-the-configuration-4","__idx":29},"children":["Step 1: Download the Configuration"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Log in to the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Capsule Security"]}," portal"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Navigate to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Settings > Integrations"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Locate the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Codex"]}," integration"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["For Windows endpoints, select ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Windows"]}," and extract the downloaded ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["capsule-codex-managed.zip"]}," (contains ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["requirements.toml"]}," and the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CapsuleCodexHook.ps1"]}," companion script)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["For macOS endpoints, select ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Mac"]}," and download the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["requirements.toml"]}," file"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"cortex-xdr-deployment-4","__idx":30},"children":["Cortex XDR Deployment"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upload one script per OS, following ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#uploading-the-script"},"children":["Uploading the script"]},", then run it as described in ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#running-the-action"},"children":["Running the action"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Windows"]}," - Name ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule Security - Codex Managed Configuration (Windows)"]},", platform ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Windows"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\"name\":\"Capsule Security - Codex Managed Configuration (Windows)\",\"description\":\"Deploys the Capsule Security managed configuration for Codex\",\"outcome\":\"High Risk\",\"platform\":\"Windows\",\"timeout\":600,\"entry_point\":\"\",\"entry_point_definition\":{}}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The managed configuration invokes ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CapsuleCodexHook.ps1"]}," by path, so both files must be written - deploying ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["requirements.toml"]}," alone would leave every hook pointing at a script that was never installed. Replace each placeholder in the installer below with the contents of the matching file from the archive, then copy the whole installer, start to finish, and paste it into the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#the-python-wrapper"},"children":["Windows wrapper"]},"'s own placeholder - upload the resulting wrapper script, not the installer by itself:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"powershell","header":{"controls":{"copy":{}}},"source":"$ErrorActionPreference = \"Stop\"\n\nfunction Write-CapsuleFile($path, $content) {\n    $parentDir = Split-Path -Path $path -Parent\n    if (-not (Test-Path -Path $parentDir)) {\n        New-Item -ItemType Directory -Path $parentDir -Force | Out-Null\n    }\n    [System.IO.File]::WriteAllText($path, $content, [System.Text.UTF8Encoding]::new($false))\n    Write-Output \"Capsule: wrote $path\"\n}\n\n$hookScript = @'\n<PASTE YOUR CapsuleCodexHook.ps1 CONTENT HERE>\n'@\nWrite-CapsuleFile 'C:\\ProgramData\\Capsule\\CodexHooks\\CapsuleCodexHook.ps1' $hookScript\n\n$requirementsToml = @'\n<PASTE YOUR REQUIREMENTS.TOML CONTENT HERE>\n'@\nWrite-CapsuleFile 'C:\\ProgramData\\OpenAI\\Codex\\requirements.toml' $requirementsToml\n\nexit 0\n","lang":"powershell"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["macOS"]}," - Name ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule Security - Codex Managed Configuration (macOS)"]},", platform ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["macOS"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\"name\":\"Capsule Security - Codex Managed Configuration (macOS)\",\"description\":\"Deploys the Capsule Security managed configuration for Codex on macOS\",\"outcome\":\"High Risk\",\"platform\":\"macOS\",\"timeout\":600,\"entry_point\":\"\",\"entry_point_definition\":{}}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Wrap this bash in the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#the-python-wrapper"},"children":["macOS wrapper"]},", replacing the placeholder with the contents of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["requirements.toml"]}," and keeping the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CAPSULE_EOF"]}," marker lines unchanged and unindented:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"#!/bin/bash\nset -e\nCODEX_DIR=\"/etc/codex\"\nmkdir -p \"$CODEX_DIR\"\ncat > \"$CODEX_DIR/requirements.toml\" << 'CAPSULE_EOF'\n<PASTE YOUR REQUIREMENTS.TOML CONTENT HERE>\nCAPSULE_EOF\nchmod 644 \"$CODEX_DIR/requirements.toml\"\necho \"Capsule: wrote Codex managed configuration to $CODEX_DIR/requirements.toml\"\nexit 0\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"verification-4","__idx":31},"children":["Verification"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After deployment, close any running Codex CLI sessions on target devices, then:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Start a new Codex CLI session so the managed configuration is loaded"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Run ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/hooks"]}," and confirm the Capsule hooks are listed as managed"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["In the Capsule portal, navigate to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Inventory > Agents"]}," and confirm the Codex agent appears"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"uninstall-4","__idx":32},"children":["Uninstall"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Cortex cannot take a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".ps1"]}," or a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".sh"]}," file, so wrap the removal script below in the same ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#the-python-wrapper"},"children":["Python wrapper"]}," and upload it as a second library script, for example ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule Security - Codex hooks removal"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upload and run a second script that deletes the files this deployment wrote. Each delete is conditional on the file still carrying Capsule's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/codex/hooks/events"]}," marker. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CapsuleCodexHook.ps1"]}," and the directories holding it are Capsule's own, and those directories are removed once empty, innermost first. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["C:\\ProgramData\\OpenAI\\Codex"]}," is Codex's own directory and stays."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"powershell","header":{"controls":{"copy":{}}},"source":"$config = 'C:\\ProgramData\\OpenAI\\Codex\\requirements.toml'\n$hookScript = 'C:\\ProgramData\\Capsule\\CodexHooks\\CapsuleCodexHook.ps1'\n\nforeach ($path in @($config, $hookScript)) {\n    if ((Test-Path -LiteralPath $path) -and ((Get-Content -LiteralPath $path -Raw) -like '*/codex/hooks/events*')) {\n        Remove-Item -LiteralPath $path -Force\n        Write-Output \"Capsule: removed $path\"\n    }\n}\n\nforeach ($dir in @('C:\\ProgramData\\Capsule\\CodexHooks', 'C:\\ProgramData\\Capsule')) {\n    if ((Test-Path -LiteralPath $dir) -and -not (Get-ChildItem -LiteralPath $dir -Force)) {\n        Remove-Item -LiteralPath $dir -Force\n    }\n}\nexit 0\n","lang":"powershell"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"#!/bin/bash\nFILE=\"/etc/codex/requirements.toml\"\nif grep -qF '/codex/hooks/events' \"$FILE\" 2>/dev/null; then\n    rm -f \"$FILE\"\n    echo \"Capsule: removed $FILE\"\nfi\nexit 0\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"key-considerations","__idx":33},"children":["Key Considerations"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["There is no continuous enforcement."]}," Run Endpoint Script is a one-shot action, not a policy. An endpoint that enrolls, is rebuilt, or has the file removed after the action ran is not covered until you run the action again. Cortex offers ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Rerun"]}," and ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Run on additional agents"]}," for that, but nothing schedules them. If you need a configuration that reapplies itself, deploy these hooks through an MDM and use Cortex only where an MDM does not reach"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Actions expire after four days."]}," An endpoint that is offline longer than that moves from ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Pending"]}," to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Expired"]}," and never receives the action. Plan a second wave for stragglers"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Scripts run as ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["SYSTEM"]}," on Windows and ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["root"]}," on macOS, so environment variables and per-user paths are not the signed-in user's"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Cursor"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Devin (Windsurf)"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Claude Code"]},", and ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Codex"]}," write to system-level paths, which suits the SYSTEM and root context directly"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["GitHub Copilot"]}," uses per-user paths, so its scripts iterate over the user profiles on the device. Users created after the action runs are not covered until you run it again"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["WSL is out of scope for this channel."]}," Capsule's Windows WSL companion has to run in each user's context to enumerate that user's WSL distributions, and Cortex only runs scripts as SYSTEM. Deploy the WSL companion through an MDM that supports user-context scripts, such as ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/mdm-intune"},"children":["Microsoft Intune"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Scope a rollout by filtering the endpoint table on ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Group Names"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Operating System"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["OS Version"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Agent Version"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Tags"]},", or ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Active Directory"]}," groups, then selecting the resulting rows. Endpoint groups are a filter here, not a policy target"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Automating with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /public_api/v1/scripts/run_script"]}," caps each call at 1000 endpoints and accepts only an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endpoint_id_list"]}," filter, so large fleets need batching and the endpoint IDs resolved first"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Codex"]}," uses a managed configuration enforced by policy - it applies to all users on the device (including users created later) and cannot be overridden by user-level configuration"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Devin (Windsurf)"]}," merges system, user, and workspace hook configurations, so the system-level deployment coexists with any per-user hooks and cannot be disabled by end users"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Restart each application on target devices after deployment for hooks to take effect"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["All five integrations can be uploaded as separate scripts and run independently"]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"monitoring-deployments","__idx":34},"children":["Monitoring Deployments"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Results are pull-based. Cortex sends no notification when an action finishes, so watch the Action Center."]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Navigate to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Investigation & Response > Response > Action Center"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Right-click the action and select ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Additional data"]}," to open ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Detailed Results"]},". The upper bar shows the script name, status, and target scope; the per-endpoint table shows ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Status"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Execution timestamp"]},", and ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Standard output"]}," - which is where the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Capsule: wrote ..."]}," lines from the scripts above appear"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Read the per-endpoint status:",{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Completed Successfully"]},": the script ran and exited cleanly"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Pending"]},": the endpoint has not checked in yet. It has four days"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["In Progress"]},": the agent is running the script now"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Failed"]},": the agent could not execute the script, or the script raised an exception"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Timeout"]},": the script exceeded the timeout you configured and the agent stopped it"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Expired"]},": the four-day window elapsed before the endpoint checked in"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Canceled"]}," / ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Aborted"]},": stopped before the agent pulled the request, or after it started"]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Right-click an endpoint row to download its ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["stdout"]}," or view exceptions, and use ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Export to file"]}," for the whole table. To watch results arrive live, right-click a running action and select ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Open in interactive mode"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To stop a rollout, right-click the action and choose ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Cancel for pending endpoints"]},", or ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Abort and cancel execution"]}," for endpoints already running it."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"references","__idx":35},"children":["References"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://cortex-docs.paloaltonetworks.com/cortex-xsiam/detect-investigate-and-respond-to-threats/investigation-and-response/response-actions/run-agent-scripts-on-an-endpoint"},"children":["Run agent scripts on an endpoint (Cortex XSIAM)"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://cortex-docs.paloaltonetworks.com/cortex-xdr-3.x/cortex-xdr-3.x-documentation/investigate-and-respond-to-incidents/response-actions/run-scripts-on-an-endpoint"},"children":["Run scripts on an endpoint (Cortex XDR 3.x)"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://cortex-docs.paloaltonetworks.com/cortex-xsiam/detect-investigate-and-respond-to-threats/investigation-and-response/response-actions"},"children":["Response actions, platform and agent version matrix"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://cortex-docs.paloaltonetworks.com/cortex-xdr-5.x/reference-and-developer-docs/role-based-access-control/investigation-and-response-permissions/response-permissions/agent-scripts-library-permissions"},"children":["Agent Scripts Library permissions (Cortex XDR 5.x)"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://cortex-docs.paloaltonetworks.com/cortex-xsiam/detect-investigate-and-respond-to-threats/investigation-and-response/investigate-endpoints/overview-of-the-action-center/initiate-and-monitor-endpoint-actions"},"children":["Initiate and monitor endpoint actions"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://cortex-docs.paloaltonetworks.com/cortex-xsiam/detect-investigate-and-respond-to-threats/investigation-and-response/response-actions/initiate-a-live-terminal-session"},"children":["Initiate a Live Terminal session"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://cortex-docs.paloaltonetworks.com/cortex-xsiam/detect-investigate-and-respond-to-threats/investigation-and-response/investigate-endpoints/manage-endpoints"},"children":["Manage endpoints"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://cortex-docs.paloaltonetworks.com/cortex-xdr-agent/9.3/cortex-xdr-agent-for-windows/install-the-cortex-xdr-agent-for-windows"},"children":["Install the Cortex XDR agent for Windows, including the restriction flags"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://cortex-docs.paloaltonetworks.com/xdr-5-api/cortex-platform/script-execution"},"children":["Script Execution API"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://developers.openai.com/codex/hooks"},"children":["Codex Hooks"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://developers.openai.com/codex/enterprise/managed-configuration"},"children":["Codex Managed Configuration"]}]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"support","__idx":36},"children":["Support"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For help with deployment:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Email"]},": support@capsule.security"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Include"]},": Your organization ID, Cortex XDR or XSIAM tenant details, the action ID from the Action Center, and any error messages"]}]}]},"headings":[{"value":"Palo Alto Cortex XDR Distribution","id":"palo-alto-cortex-xdr-distribution","depth":1},{"value":"Prerequisites","id":"prerequisites","depth":2},{"value":"How Cortex Runs These Scripts","id":"how-cortex-runs-these-scripts","depth":2},{"value":"Three different things in Cortex are called \"scripts\"","id":"three-different-things-in-cortex-are-called-scripts","depth":3},{"value":"The Python wrapper","id":"the-python-wrapper","depth":3},{"value":"Uploading the script","id":"uploading-the-script","depth":3},{"value":"Running the action","id":"running-the-action","depth":3},{"value":"Live Terminal (single endpoint)","id":"live-terminal-single-endpoint","depth":3},{"value":"Cursor","id":"cursor","depth":2},{"value":"Step 1: Download the Configuration","id":"step-1-download-the-configuration","depth":3},{"value":"Cortex XDR Deployment","id":"cortex-xdr-deployment","depth":3},{"value":"Verification","id":"verification","depth":3},{"value":"Uninstall","id":"uninstall","depth":3},{"value":"Devin (Windsurf)","id":"devin-windsurf","depth":2},{"value":"Step 1: Download the Configuration","id":"step-1-download-the-configuration-1","depth":3},{"value":"Cortex XDR Deployment","id":"cortex-xdr-deployment-1","depth":3},{"value":"Verification","id":"verification-1","depth":3},{"value":"Uninstall","id":"uninstall-1","depth":3},{"value":"GitHub Copilot","id":"github-copilot","depth":2},{"value":"Step 1: Download the Configuration","id":"step-1-download-the-configuration-2","depth":3},{"value":"Cortex XDR Deployment","id":"cortex-xdr-deployment-2","depth":3},{"value":"Verification","id":"verification-2","depth":3},{"value":"Uninstall","id":"uninstall-2","depth":3},{"value":"Claude Code","id":"claude-code","depth":2},{"value":"Step 1: Download the Configuration","id":"step-1-download-the-configuration-3","depth":3},{"value":"Cortex XDR Deployment","id":"cortex-xdr-deployment-3","depth":3},{"value":"Verification","id":"verification-3","depth":3},{"value":"Uninstall","id":"uninstall-3","depth":3},{"value":"Codex","id":"codex","depth":2},{"value":"Step 1: Download the Configuration","id":"step-1-download-the-configuration-4","depth":3},{"value":"Cortex XDR Deployment","id":"cortex-xdr-deployment-4","depth":3},{"value":"Verification","id":"verification-4","depth":3},{"value":"Uninstall","id":"uninstall-4","depth":3},{"value":"Key Considerations","id":"key-considerations","depth":2},{"value":"Monitoring Deployments","id":"monitoring-deployments","depth":2},{"value":"References","id":"references","depth":2},{"value":"Support","id":"support","depth":2}],"frontmatter":{"seo":{"title":"Palo Alto Cortex XDR Distribution"}},"lastModified":"2026-10-18T11:05:04.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/mdm-cortex-xdr","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}