nox-openclaw-hunter 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +140 -0
- package/bin/nox.js +2 -0
- package/dist/branding.d.ts +39 -0
- package/dist/branding.d.ts.map +1 -0
- package/dist/branding.js +66 -0
- package/dist/branding.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +94 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/export.d.ts +21 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +616 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/index.d.ts +8 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +8 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/isolate.d.ts +30 -0
- package/dist/commands/isolate.d.ts.map +1 -0
- package/dist/commands/isolate.js +547 -0
- package/dist/commands/isolate.js.map +1 -0
- package/dist/commands/purge.d.ts +22 -0
- package/dist/commands/purge.d.ts.map +1 -0
- package/dist/commands/purge.js +295 -0
- package/dist/commands/purge.js.map +1 -0
- package/dist/commands/scan.d.ts +23 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +155 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/detector/app-bundle.d.ts +13 -0
- package/dist/detector/app-bundle.d.ts.map +1 -0
- package/dist/detector/app-bundle.js +27 -0
- package/dist/detector/app-bundle.js.map +1 -0
- package/dist/detector/cli-binary.d.ts +12 -0
- package/dist/detector/cli-binary.d.ts.map +1 -0
- package/dist/detector/cli-binary.js +66 -0
- package/dist/detector/cli-binary.js.map +1 -0
- package/dist/detector/config.d.ts +21 -0
- package/dist/detector/config.d.ts.map +1 -0
- package/dist/detector/config.js +337 -0
- package/dist/detector/config.js.map +1 -0
- package/dist/detector/detection-config.d.ts +24 -0
- package/dist/detector/detection-config.d.ts.map +1 -0
- package/dist/detector/detection-config.js +242 -0
- package/dist/detector/detection-config.js.map +1 -0
- package/dist/detector/docker.d.ts +10 -0
- package/dist/detector/docker.d.ts.map +1 -0
- package/dist/detector/docker.js +94 -0
- package/dist/detector/docker.js.map +1 -0
- package/dist/detector/index.d.ts +50 -0
- package/dist/detector/index.d.ts.map +1 -0
- package/dist/detector/index.js +155 -0
- package/dist/detector/index.js.map +1 -0
- package/dist/detector/network.d.ts +34 -0
- package/dist/detector/network.d.ts.map +1 -0
- package/dist/detector/network.js +205 -0
- package/dist/detector/network.js.map +1 -0
- package/dist/detector/process.d.ts +16 -0
- package/dist/detector/process.d.ts.map +1 -0
- package/dist/detector/process.js +47 -0
- package/dist/detector/process.js.map +1 -0
- package/dist/detector/service.d.ts +17 -0
- package/dist/detector/service.d.ts.map +1 -0
- package/dist/detector/service.js +51 -0
- package/dist/detector/service.js.map +1 -0
- package/dist/enforcer/docker-cleaner.d.ts +30 -0
- package/dist/enforcer/docker-cleaner.d.ts.map +1 -0
- package/dist/enforcer/docker-cleaner.js +163 -0
- package/dist/enforcer/docker-cleaner.js.map +1 -0
- package/dist/enforcer/file-remover.d.ts +34 -0
- package/dist/enforcer/file-remover.d.ts.map +1 -0
- package/dist/enforcer/file-remover.js +137 -0
- package/dist/enforcer/file-remover.js.map +1 -0
- package/dist/enforcer/index.d.ts +33 -0
- package/dist/enforcer/index.d.ts.map +1 -0
- package/dist/enforcer/index.js +142 -0
- package/dist/enforcer/index.js.map +1 -0
- package/dist/enforcer/process-killer.d.ts +18 -0
- package/dist/enforcer/process-killer.d.ts.map +1 -0
- package/dist/enforcer/process-killer.js +80 -0
- package/dist/enforcer/process-killer.js.map +1 -0
- package/dist/enforcer/service-stopper.d.ts +23 -0
- package/dist/enforcer/service-stopper.d.ts.map +1 -0
- package/dist/enforcer/service-stopper.js +95 -0
- package/dist/enforcer/service-stopper.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/isolator/firewall.d.ts +25 -0
- package/dist/isolator/firewall.d.ts.map +1 -0
- package/dist/isolator/firewall.js +114 -0
- package/dist/isolator/firewall.js.map +1 -0
- package/dist/isolator/index.d.ts +63 -0
- package/dist/isolator/index.d.ts.map +1 -0
- package/dist/isolator/index.js +201 -0
- package/dist/isolator/index.js.map +1 -0
- package/dist/isolator/lockdown.d.ts +22 -0
- package/dist/isolator/lockdown.d.ts.map +1 -0
- package/dist/isolator/lockdown.js +401 -0
- package/dist/isolator/lockdown.js.map +1 -0
- package/dist/isolator/quarantine.d.ts +39 -0
- package/dist/isolator/quarantine.d.ts.map +1 -0
- package/dist/isolator/quarantine.js +364 -0
- package/dist/isolator/quarantine.js.map +1 -0
- package/dist/mdm/index.d.ts +93 -0
- package/dist/mdm/index.d.ts.map +1 -0
- package/dist/mdm/index.js +414 -0
- package/dist/mdm/index.js.map +1 -0
- package/dist/mdm/intune.d.ts +69 -0
- package/dist/mdm/intune.d.ts.map +1 -0
- package/dist/mdm/intune.js +409 -0
- package/dist/mdm/intune.js.map +1 -0
- package/dist/mdm/jamf.d.ts +58 -0
- package/dist/mdm/jamf.d.ts.map +1 -0
- package/dist/mdm/jamf.js +441 -0
- package/dist/mdm/jamf.js.map +1 -0
- package/dist/mdm/jumpcloud.d.ts +73 -0
- package/dist/mdm/jumpcloud.d.ts.map +1 -0
- package/dist/mdm/jumpcloud.js +470 -0
- package/dist/mdm/jumpcloud.js.map +1 -0
- package/dist/mdm/templates/detect.ps1.d.ts +30 -0
- package/dist/mdm/templates/detect.ps1.d.ts.map +1 -0
- package/dist/mdm/templates/detect.ps1.js +463 -0
- package/dist/mdm/templates/detect.ps1.js.map +1 -0
- package/dist/mdm/templates/detect.sh.d.ts +30 -0
- package/dist/mdm/templates/detect.sh.d.ts.map +1 -0
- package/dist/mdm/templates/detect.sh.js +474 -0
- package/dist/mdm/templates/detect.sh.js.map +1 -0
- package/dist/mdm/templates/enforce.ps1.d.ts +33 -0
- package/dist/mdm/templates/enforce.ps1.d.ts.map +1 -0
- package/dist/mdm/templates/enforce.ps1.js +681 -0
- package/dist/mdm/templates/enforce.ps1.js.map +1 -0
- package/dist/mdm/templates/enforce.sh.d.ts +33 -0
- package/dist/mdm/templates/enforce.sh.d.ts.map +1 -0
- package/dist/mdm/templates/enforce.sh.js +591 -0
- package/dist/mdm/templates/enforce.sh.js.map +1 -0
- package/dist/platform/darwin.d.ts +6 -0
- package/dist/platform/darwin.d.ts.map +1 -0
- package/dist/platform/darwin.js +192 -0
- package/dist/platform/darwin.js.map +1 -0
- package/dist/platform/index.d.ts +43 -0
- package/dist/platform/index.d.ts.map +1 -0
- package/dist/platform/index.js +27 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/linux.d.ts +6 -0
- package/dist/platform/linux.d.ts.map +1 -0
- package/dist/platform/linux.js +134 -0
- package/dist/platform/linux.js.map +1 -0
- package/dist/platform/windows.d.ts +6 -0
- package/dist/platform/windows.d.ts.map +1 -0
- package/dist/platform/windows.js +134 -0
- package/dist/platform/windows.js.map +1 -0
- package/dist/reporter/console.d.ts +27 -0
- package/dist/reporter/console.d.ts.map +1 -0
- package/dist/reporter/console.js +431 -0
- package/dist/reporter/console.js.map +1 -0
- package/dist/reporter/index.d.ts +11 -0
- package/dist/reporter/index.d.ts.map +1 -0
- package/dist/reporter/index.js +13 -0
- package/dist/reporter/index.js.map +1 -0
- package/dist/reporter/json.d.ts +61 -0
- package/dist/reporter/json.d.ts.map +1 -0
- package/dist/reporter/json.js +75 -0
- package/dist/reporter/json.js.map +1 -0
- package/dist/reporter/webhook.d.ts +57 -0
- package/dist/reporter/webhook.d.ts.map +1 -0
- package/dist/reporter/webhook.js +230 -0
- package/dist/reporter/webhook.js.map +1 -0
- package/dist/types/config.d.ts +116 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +6 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/detection.d.ts +85 -0
- package/dist/types/detection.d.ts.map +1 -0
- package/dist/types/detection.js +5 -0
- package/dist/types/detection.js.map +1 -0
- package/dist/types/enforcement.d.ts +33 -0
- package/dist/types/enforcement.d.ts.map +1 -0
- package/dist/types/enforcement.js +5 -0
- package/dist/types/enforcement.js.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/isolation.d.ts +55 -0
- package/dist/types/isolation.d.ts.map +1 -0
- package/dist/types/isolation.js +5 -0
- package/dist/types/isolation.js.map +1 -0
- package/dist/utils/exec.d.ts +48 -0
- package/dist/utils/exec.d.ts.map +1 -0
- package/dist/utils/exec.js +103 -0
- package/dist/utils/exec.js.map +1 -0
- package/dist/utils/fs.d.ts +34 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +111 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +48 -0
- package/dist/utils/logger.js.map +1 -0
- package/docs/intune.md +390 -0
- package/docs/jamf.md +400 -0
- package/docs/jumpcloud.md +510 -0
- package/package.json +65 -0
package/dist/mdm/jamf.js
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jamf Pro MDM integration module.
|
|
3
|
+
* Generates Jamf-specific deployment scripts and documentation.
|
|
4
|
+
*/
|
|
5
|
+
import { VERSION, COMPANY } from '../branding.js';
|
|
6
|
+
import { generateDetectShellScript, } from './templates/detect.sh.js';
|
|
7
|
+
import { generateEnforceShellScript, } from './templates/enforce.sh.js';
|
|
8
|
+
/**
|
|
9
|
+
* Generate Jamf-formatted detection script.
|
|
10
|
+
*/
|
|
11
|
+
export function generateJamfDetectScript(options = {}) {
|
|
12
|
+
const scriptOptions = {
|
|
13
|
+
webhookUrl: options.webhookUrl,
|
|
14
|
+
webhookToken: options.webhookToken,
|
|
15
|
+
gatewayPort: options.gatewayPort,
|
|
16
|
+
verbose: options.verbose,
|
|
17
|
+
};
|
|
18
|
+
// Add Jamf-specific wrapper with parameter handling
|
|
19
|
+
const baseScript = generateDetectShellScript(scriptOptions);
|
|
20
|
+
const jamfScript = wrapWithJamfParameters(baseScript, 'detect');
|
|
21
|
+
return {
|
|
22
|
+
filename: 'nox-detect-openclaw.sh',
|
|
23
|
+
content: jamfScript,
|
|
24
|
+
description: 'Jamf Pro detection script for OpenClaw AI agent',
|
|
25
|
+
jamfCategory: 'Security',
|
|
26
|
+
priority: 'Before',
|
|
27
|
+
parameters: getJamfDetectParameters(),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Generate Jamf-formatted enforcement script.
|
|
32
|
+
*/
|
|
33
|
+
export function generateJamfEnforceScript(options = {}) {
|
|
34
|
+
const scriptOptions = {
|
|
35
|
+
webhookUrl: options.webhookUrl,
|
|
36
|
+
webhookToken: options.webhookToken,
|
|
37
|
+
gatewayPort: options.gatewayPort,
|
|
38
|
+
verbose: options.verbose,
|
|
39
|
+
quarantine: options.quarantine,
|
|
40
|
+
};
|
|
41
|
+
const baseScript = generateEnforceShellScript(scriptOptions);
|
|
42
|
+
const jamfScript = wrapWithJamfParameters(baseScript, 'enforce');
|
|
43
|
+
return {
|
|
44
|
+
filename: 'nox-enforce-openclaw.sh',
|
|
45
|
+
content: jamfScript,
|
|
46
|
+
description: 'Jamf Pro enforcement script for OpenClaw AI agent removal',
|
|
47
|
+
jamfCategory: 'Security',
|
|
48
|
+
priority: 'Before',
|
|
49
|
+
parameters: getJamfEnforceParameters(),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Wrap script with Jamf parameter handling.
|
|
54
|
+
*/
|
|
55
|
+
function wrapWithJamfParameters(script, mode) {
|
|
56
|
+
const parameterHandling = `
|
|
57
|
+
# ==============================================================================
|
|
58
|
+
# Jamf Pro Parameter Handling
|
|
59
|
+
# ==============================================================================
|
|
60
|
+
# Parameters passed from Jamf Pro policy:
|
|
61
|
+
# $1 - Mount Point (usually /)
|
|
62
|
+
# $2 - Computer Name
|
|
63
|
+
# $3 - Username of currently logged-in user
|
|
64
|
+
# $4 - Parameter 4 (custom)
|
|
65
|
+
# $5 - Parameter 5 (custom)
|
|
66
|
+
# ...
|
|
67
|
+
# ==============================================================================
|
|
68
|
+
|
|
69
|
+
# Jamf parameters
|
|
70
|
+
JAMF_MOUNT_POINT="\${1:-/}"
|
|
71
|
+
JAMF_COMPUTER_NAME="\${2:-$(hostname)}"
|
|
72
|
+
JAMF_USERNAME="\${3:-}"
|
|
73
|
+
|
|
74
|
+
# Custom parameters
|
|
75
|
+
${mode === 'detect' ? `
|
|
76
|
+
PARAM_WEBHOOK_URL="\${4:-}"
|
|
77
|
+
PARAM_WEBHOOK_TOKEN="\${5:-}"
|
|
78
|
+
PARAM_VERBOSE="\${6:-false}"
|
|
79
|
+
` : `
|
|
80
|
+
PARAM_WEBHOOK_URL="\${4:-}"
|
|
81
|
+
PARAM_WEBHOOK_TOKEN="\${5:-}"
|
|
82
|
+
PARAM_QUARANTINE="\${6:-false}"
|
|
83
|
+
PARAM_VERBOSE="\${7:-false}"
|
|
84
|
+
`}
|
|
85
|
+
|
|
86
|
+
# Override webhook settings if provided via Jamf parameters
|
|
87
|
+
if [[ -n "$PARAM_WEBHOOK_URL" ]]; then
|
|
88
|
+
WEBHOOK_URL="$PARAM_WEBHOOK_URL"
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
if [[ -n "$PARAM_WEBHOOK_TOKEN" ]]; then
|
|
92
|
+
WEBHOOK_TOKEN="$PARAM_WEBHOOK_TOKEN"
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# Log Jamf context
|
|
96
|
+
echo "Jamf Pro Context:"
|
|
97
|
+
echo " Mount Point: $JAMF_MOUNT_POINT"
|
|
98
|
+
echo " Computer: $JAMF_COMPUTER_NAME"
|
|
99
|
+
echo " User: $JAMF_USERNAME"
|
|
100
|
+
echo ""
|
|
101
|
+
|
|
102
|
+
`;
|
|
103
|
+
// Insert parameter handling after the initial comments
|
|
104
|
+
const lines = script.split('\n');
|
|
105
|
+
const insertIndex = lines.findIndex(line => line.startsWith('set -'));
|
|
106
|
+
if (insertIndex !== -1) {
|
|
107
|
+
lines.splice(insertIndex, 0, parameterHandling);
|
|
108
|
+
}
|
|
109
|
+
return lines.join('\n');
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Get Jamf parameter definitions for detect script.
|
|
113
|
+
*/
|
|
114
|
+
function getJamfDetectParameters() {
|
|
115
|
+
return [
|
|
116
|
+
{
|
|
117
|
+
number: 4,
|
|
118
|
+
label: 'Webhook URL',
|
|
119
|
+
description: 'URL to send detection results (optional)',
|
|
120
|
+
required: false,
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
number: 5,
|
|
124
|
+
label: 'Webhook Token',
|
|
125
|
+
description: 'Bearer token for webhook authentication (optional)',
|
|
126
|
+
required: false,
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
number: 6,
|
|
130
|
+
label: 'Verbose Mode',
|
|
131
|
+
description: 'Enable verbose logging (true/false)',
|
|
132
|
+
required: false,
|
|
133
|
+
defaultValue: 'false',
|
|
134
|
+
},
|
|
135
|
+
];
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get Jamf parameter definitions for enforce script.
|
|
139
|
+
*/
|
|
140
|
+
function getJamfEnforceParameters() {
|
|
141
|
+
return [
|
|
142
|
+
{
|
|
143
|
+
number: 4,
|
|
144
|
+
label: 'Webhook URL',
|
|
145
|
+
description: 'URL to send enforcement results (optional)',
|
|
146
|
+
required: false,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
number: 5,
|
|
150
|
+
label: 'Webhook Token',
|
|
151
|
+
description: 'Bearer token for webhook authentication (optional)',
|
|
152
|
+
required: false,
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
number: 6,
|
|
156
|
+
label: 'Quarantine Mode',
|
|
157
|
+
description: 'Move files to quarantine instead of deleting (true/false)',
|
|
158
|
+
required: false,
|
|
159
|
+
defaultValue: 'false',
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
number: 7,
|
|
163
|
+
label: 'Verbose Mode',
|
|
164
|
+
description: 'Enable verbose logging (true/false)',
|
|
165
|
+
required: false,
|
|
166
|
+
defaultValue: 'false',
|
|
167
|
+
},
|
|
168
|
+
];
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Generate Jamf Pro extension attribute for inventory.
|
|
172
|
+
*/
|
|
173
|
+
export function generateJamfExtensionAttribute() {
|
|
174
|
+
return `#!/bin/bash
|
|
175
|
+
# ==============================================================================
|
|
176
|
+
# Nox OpenClaw Detection - Jamf Extension Attribute
|
|
177
|
+
# ==============================================================================
|
|
178
|
+
# Generated by nox-openclaw-detector v${VERSION}
|
|
179
|
+
# ${COMPANY} - https://nox.security
|
|
180
|
+
#
|
|
181
|
+
# This extension attribute reports OpenClaw installation status to Jamf Pro
|
|
182
|
+
# for use in Smart Groups and reporting.
|
|
183
|
+
#
|
|
184
|
+
# Data Type: String
|
|
185
|
+
# Input Type: Script
|
|
186
|
+
# ==============================================================================
|
|
187
|
+
|
|
188
|
+
OPENCLAW_STATUS="Not Installed"
|
|
189
|
+
|
|
190
|
+
# Check CLI binary
|
|
191
|
+
if command -v openclaw &>/dev/null; then
|
|
192
|
+
OPENCLAW_STATUS="Installed"
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
# Check common paths
|
|
196
|
+
for path in /usr/local/bin/openclaw /opt/homebrew/bin/openclaw; do
|
|
197
|
+
if [[ -f "$path" ]]; then
|
|
198
|
+
OPENCLAW_STATUS="Installed"
|
|
199
|
+
break
|
|
200
|
+
fi
|
|
201
|
+
done
|
|
202
|
+
|
|
203
|
+
# Check app bundle
|
|
204
|
+
if [[ -d "/Applications/OpenClaw.app" ]]; then
|
|
205
|
+
OPENCLAW_STATUS="Installed"
|
|
206
|
+
fi
|
|
207
|
+
|
|
208
|
+
# Check config directory
|
|
209
|
+
if [[ -d "$HOME/.openclaw" ]] || [[ -d "/Users/"*"/.openclaw" ]]; then
|
|
210
|
+
OPENCLAW_STATUS="Installed"
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
# Check if running
|
|
214
|
+
if pgrep -f "openclaw" > /dev/null 2>&1; then
|
|
215
|
+
OPENCLAW_STATUS="Running"
|
|
216
|
+
fi
|
|
217
|
+
|
|
218
|
+
# Check gateway port
|
|
219
|
+
if nc -z localhost 18789 2>/dev/null; then
|
|
220
|
+
OPENCLAW_STATUS="Running"
|
|
221
|
+
fi
|
|
222
|
+
|
|
223
|
+
echo "<result>$OPENCLAW_STATUS</result>"
|
|
224
|
+
`;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Generate Jamf deployment documentation.
|
|
228
|
+
*/
|
|
229
|
+
export function generateJamfDocumentation() {
|
|
230
|
+
return `# Jamf Pro Integration Guide
|
|
231
|
+
|
|
232
|
+
## Overview
|
|
233
|
+
|
|
234
|
+
This guide explains how to deploy Nox OpenClaw detection and enforcement scripts via Jamf Pro for fleet-wide management of macOS devices.
|
|
235
|
+
|
|
236
|
+
Generated by nox-openclaw-detector v${VERSION}
|
|
237
|
+
${COMPANY} - https://nox.security
|
|
238
|
+
|
|
239
|
+
## Prerequisites
|
|
240
|
+
|
|
241
|
+
- Jamf Pro 10.x or later
|
|
242
|
+
- macOS 10.15+ managed devices
|
|
243
|
+
- Admin access to Jamf Pro console
|
|
244
|
+
|
|
245
|
+
## Quick Start
|
|
246
|
+
|
|
247
|
+
1. Upload the detection script to Jamf Pro
|
|
248
|
+
2. Create a policy with recurring trigger
|
|
249
|
+
3. (Optional) Add enforcement script for remediation
|
|
250
|
+
4. (Optional) Create Smart Groups based on extension attribute
|
|
251
|
+
|
|
252
|
+
## Script Setup
|
|
253
|
+
|
|
254
|
+
### Step 1: Add Detection Script
|
|
255
|
+
|
|
256
|
+
1. Navigate to **Settings > Computer Management > Scripts**
|
|
257
|
+
2. Click **+ New**
|
|
258
|
+
3. Configure:
|
|
259
|
+
- **Display Name:** Nox OpenClaw Detection
|
|
260
|
+
- **Category:** Security
|
|
261
|
+
- **Script Contents:** Paste \`nox-detect-openclaw.sh\`
|
|
262
|
+
4. Configure Parameters (Labels tab):
|
|
263
|
+
- Parameter 4: Webhook URL
|
|
264
|
+
- Parameter 5: Webhook Token
|
|
265
|
+
- Parameter 6: Verbose Mode
|
|
266
|
+
5. Click **Save**
|
|
267
|
+
|
|
268
|
+
### Step 2: Add Enforcement Script (Optional)
|
|
269
|
+
|
|
270
|
+
1. Navigate to **Settings > Computer Management > Scripts**
|
|
271
|
+
2. Click **+ New**
|
|
272
|
+
3. Configure:
|
|
273
|
+
- **Display Name:** Nox OpenClaw Enforcement
|
|
274
|
+
- **Category:** Security
|
|
275
|
+
- **Script Contents:** Paste \`nox-enforce-openclaw.sh\`
|
|
276
|
+
4. Configure Parameters (Labels tab):
|
|
277
|
+
- Parameter 4: Webhook URL
|
|
278
|
+
- Parameter 5: Webhook Token
|
|
279
|
+
- Parameter 6: Quarantine Mode
|
|
280
|
+
- Parameter 7: Verbose Mode
|
|
281
|
+
5. Click **Save**
|
|
282
|
+
|
|
283
|
+
### Step 3: Add Extension Attribute (Optional)
|
|
284
|
+
|
|
285
|
+
1. Navigate to **Settings > Computer Management > Extension Attributes**
|
|
286
|
+
2. Click **+ New**
|
|
287
|
+
3. Configure:
|
|
288
|
+
- **Display Name:** OpenClaw Status
|
|
289
|
+
- **Data Type:** String
|
|
290
|
+
- **Input Type:** Script
|
|
291
|
+
- **Script:** Paste extension attribute script
|
|
292
|
+
4. Click **Save**
|
|
293
|
+
|
|
294
|
+
## Policy Configuration
|
|
295
|
+
|
|
296
|
+
### Detection Policy
|
|
297
|
+
|
|
298
|
+
1. Navigate to **Computers > Policies**
|
|
299
|
+
2. Click **+ New**
|
|
300
|
+
3. Configure General:
|
|
301
|
+
- **Display Name:** Nox OpenClaw Detection
|
|
302
|
+
- **Enabled:** Yes
|
|
303
|
+
- **Trigger:** Recurring Check-in
|
|
304
|
+
- **Execution Frequency:** Once per day
|
|
305
|
+
4. Configure Scripts:
|
|
306
|
+
- Add "Nox OpenClaw Detection" script
|
|
307
|
+
- Set parameter values as needed
|
|
308
|
+
5. Configure Scope:
|
|
309
|
+
- Add target computers or groups
|
|
310
|
+
6. Click **Save**
|
|
311
|
+
|
|
312
|
+
### Enforcement Policy (Optional)
|
|
313
|
+
|
|
314
|
+
1. Navigate to **Computers > Policies**
|
|
315
|
+
2. Click **+ New**
|
|
316
|
+
3. Configure General:
|
|
317
|
+
- **Display Name:** Nox OpenClaw Enforcement
|
|
318
|
+
- **Enabled:** Yes (or No for manual trigger)
|
|
319
|
+
- **Trigger:** Custom (Self Service) or Recurring Check-in
|
|
320
|
+
- **Execution Frequency:** Ongoing
|
|
321
|
+
4. Configure Scripts:
|
|
322
|
+
- Add "Nox OpenClaw Enforcement" script
|
|
323
|
+
- Set parameter values as needed
|
|
324
|
+
5. Configure Scope:
|
|
325
|
+
- Scope to Smart Group "OpenClaw Detected" (see below)
|
|
326
|
+
6. Click **Save**
|
|
327
|
+
|
|
328
|
+
## Smart Groups
|
|
329
|
+
|
|
330
|
+
### OpenClaw Detected
|
|
331
|
+
|
|
332
|
+
Create a Smart Group to identify devices with OpenClaw installed:
|
|
333
|
+
|
|
334
|
+
1. Navigate to **Computers > Smart Computer Groups**
|
|
335
|
+
2. Click **+ New**
|
|
336
|
+
3. Configure:
|
|
337
|
+
- **Display Name:** OpenClaw Detected
|
|
338
|
+
- **Criteria:**
|
|
339
|
+
- Extension Attribute: OpenClaw Status
|
|
340
|
+
- Operator: is
|
|
341
|
+
- Value: Installed
|
|
342
|
+
|
|
343
|
+
**OR**
|
|
344
|
+
|
|
345
|
+
- Extension Attribute: OpenClaw Status
|
|
346
|
+
- Operator: is
|
|
347
|
+
- Value: Running
|
|
348
|
+
|
|
349
|
+
### OpenClaw Running
|
|
350
|
+
|
|
351
|
+
For devices actively running OpenClaw:
|
|
352
|
+
|
|
353
|
+
- **Criteria:**
|
|
354
|
+
- Extension Attribute: OpenClaw Status
|
|
355
|
+
- Operator: is
|
|
356
|
+
- Value: Running
|
|
357
|
+
|
|
358
|
+
## Exit Codes
|
|
359
|
+
|
|
360
|
+
| Code | Meaning | Jamf Behavior |
|
|
361
|
+
|------|---------|---------------|
|
|
362
|
+
| 0 | Not detected / Success | Policy marked successful |
|
|
363
|
+
| 1 | Detected / Partial failure | Policy marked failed (triggers alerts) |
|
|
364
|
+
| 2 | Script error | Policy marked failed |
|
|
365
|
+
| 3 | Nothing to enforce | Policy marked successful |
|
|
366
|
+
|
|
367
|
+
## Webhook Integration
|
|
368
|
+
|
|
369
|
+
To send results to your SIEM or alerting platform:
|
|
370
|
+
|
|
371
|
+
1. Set Parameter 4 (Webhook URL) in policy
|
|
372
|
+
2. Optionally set Parameter 5 (Webhook Token) for authentication
|
|
373
|
+
|
|
374
|
+
Webhook payload format:
|
|
375
|
+
\`\`\`json
|
|
376
|
+
{
|
|
377
|
+
"event": "openclaw.detection",
|
|
378
|
+
"version": "1.0",
|
|
379
|
+
"timestamp": "2026-02-03T10:30:00Z",
|
|
380
|
+
"status": "detected",
|
|
381
|
+
"severity": "high",
|
|
382
|
+
"host": {
|
|
383
|
+
"hostname": "MacBook-Pro.local",
|
|
384
|
+
"os": "Darwin",
|
|
385
|
+
"arch": "arm64",
|
|
386
|
+
"user": "jsmith"
|
|
387
|
+
},
|
|
388
|
+
"details": "CLI found at /usr/local/bin/openclaw; Config directory found",
|
|
389
|
+
"source": {
|
|
390
|
+
"tool": "nox-openclaw-detector",
|
|
391
|
+
"version": "${VERSION}",
|
|
392
|
+
"vendor": "${COMPANY}"
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
\`\`\`
|
|
396
|
+
|
|
397
|
+
## Troubleshooting
|
|
398
|
+
|
|
399
|
+
### Script Not Running
|
|
400
|
+
|
|
401
|
+
1. Verify policy scope includes target computers
|
|
402
|
+
2. Check policy trigger and frequency
|
|
403
|
+
3. Review Jamf Pro logs for errors
|
|
404
|
+
|
|
405
|
+
### Permission Errors
|
|
406
|
+
|
|
407
|
+
1. Ensure script runs with root privileges
|
|
408
|
+
2. Check for SIP restrictions on certain paths
|
|
409
|
+
3. Verify MDM profile allows script execution
|
|
410
|
+
|
|
411
|
+
### Webhook Failures
|
|
412
|
+
|
|
413
|
+
1. Verify URL is accessible from managed devices
|
|
414
|
+
2. Check firewall rules allow outbound HTTPS
|
|
415
|
+
3. Validate bearer token if using authentication
|
|
416
|
+
|
|
417
|
+
## Support
|
|
418
|
+
|
|
419
|
+
For issues or questions:
|
|
420
|
+
- Email: support@nox.security
|
|
421
|
+
- Documentation: https://docs.nox.security/jamf
|
|
422
|
+
`;
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Get all Jamf exports.
|
|
426
|
+
*/
|
|
427
|
+
export function getJamfExports(options = {}) {
|
|
428
|
+
return {
|
|
429
|
+
detectScript: generateJamfDetectScript(options),
|
|
430
|
+
enforceScript: generateJamfEnforceScript(options),
|
|
431
|
+
extensionAttribute: generateJamfExtensionAttribute(),
|
|
432
|
+
documentation: generateJamfDocumentation(),
|
|
433
|
+
metadata: {
|
|
434
|
+
platform: 'jamf',
|
|
435
|
+
displayName: 'Jamf Pro',
|
|
436
|
+
supportedOS: ['macOS'],
|
|
437
|
+
version: VERSION,
|
|
438
|
+
},
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
//# sourceMappingURL=jamf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jamf.js","sourceRoot":"","sources":["../../src/mdm/jamf.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JumpCloud MDM integration module.
|
|
3
|
+
* Generates JumpCloud-specific deployment scripts and documentation.
|
|
4
|
+
*/
|
|
5
|
+
export interface JumpCloudScriptOptions {
|
|
6
|
+
webhookUrl?: string;
|
|
7
|
+
webhookToken?: string;
|
|
8
|
+
gatewayPort?: number;
|
|
9
|
+
verbose?: boolean;
|
|
10
|
+
quarantine?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface JumpCloudCommand {
|
|
13
|
+
name: string;
|
|
14
|
+
command: string;
|
|
15
|
+
commandType: 'linux' | 'mac' | 'windows';
|
|
16
|
+
shell: string;
|
|
17
|
+
user: string;
|
|
18
|
+
sudo: boolean;
|
|
19
|
+
timeout: number;
|
|
20
|
+
files?: string[];
|
|
21
|
+
launchType: 'manual' | 'trigger';
|
|
22
|
+
trigger?: string;
|
|
23
|
+
scheduleRepeatType?: 'day' | 'week' | 'month';
|
|
24
|
+
schedule?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Generate JumpCloud-formatted macOS/Linux detection command.
|
|
28
|
+
*/
|
|
29
|
+
export declare function generateJumpCloudUnixDetectCommand(options?: JumpCloudScriptOptions, platform?: 'mac' | 'linux'): JumpCloudCommand;
|
|
30
|
+
/**
|
|
31
|
+
* Generate JumpCloud-formatted macOS/Linux enforcement command.
|
|
32
|
+
*/
|
|
33
|
+
export declare function generateJumpCloudUnixEnforceCommand(options?: JumpCloudScriptOptions, platform?: 'mac' | 'linux'): JumpCloudCommand;
|
|
34
|
+
/**
|
|
35
|
+
* Generate JumpCloud-formatted Windows detection command.
|
|
36
|
+
*/
|
|
37
|
+
export declare function generateJumpCloudWindowsDetectCommand(options?: JumpCloudScriptOptions): JumpCloudCommand;
|
|
38
|
+
/**
|
|
39
|
+
* Generate JumpCloud-formatted Windows enforcement command.
|
|
40
|
+
*/
|
|
41
|
+
export declare function generateJumpCloudWindowsEnforceCommand(options?: JumpCloudScriptOptions): JumpCloudCommand;
|
|
42
|
+
/**
|
|
43
|
+
* Generate JumpCloud API payload for command creation.
|
|
44
|
+
*/
|
|
45
|
+
export declare function generateJumpCloudApiPayload(command: JumpCloudCommand): object;
|
|
46
|
+
/**
|
|
47
|
+
* Generate JumpCloud System Insights custom fact script.
|
|
48
|
+
*/
|
|
49
|
+
export declare function generateJumpCloudSystemInsightsFact(): string;
|
|
50
|
+
/**
|
|
51
|
+
* Generate JumpCloud deployment documentation.
|
|
52
|
+
*/
|
|
53
|
+
export declare function generateJumpCloudDocumentation(): string;
|
|
54
|
+
/**
|
|
55
|
+
* Get all JumpCloud exports.
|
|
56
|
+
*/
|
|
57
|
+
export declare function getJumpCloudExports(options?: JumpCloudScriptOptions): {
|
|
58
|
+
macDetectCommand: JumpCloudCommand;
|
|
59
|
+
macEnforceCommand: JumpCloudCommand;
|
|
60
|
+
linuxDetectCommand: JumpCloudCommand;
|
|
61
|
+
linuxEnforceCommand: JumpCloudCommand;
|
|
62
|
+
windowsDetectCommand: JumpCloudCommand;
|
|
63
|
+
windowsEnforceCommand: JumpCloudCommand;
|
|
64
|
+
systemInsightsFact: string;
|
|
65
|
+
documentation: string;
|
|
66
|
+
metadata: {
|
|
67
|
+
platform: string;
|
|
68
|
+
displayName: string;
|
|
69
|
+
supportedOS: string[];
|
|
70
|
+
version: string;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=jumpcloud.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jumpcloud.d.ts","sourceRoot":"","sources":["../../src/mdm/jumpcloud.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAwBH,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,GAAG,KAAK,GAAG,SAAS,CAAC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,QAAQ,GAAG,SAAS,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,kCAAkC,CAChD,OAAO,GAAE,sBAA2B,EACpC,QAAQ,GAAE,KAAK,GAAG,OAAe,GAChC,gBAAgB,CAsBlB;AAED;;GAEG;AACH,wBAAgB,mCAAmC,CACjD,OAAO,GAAE,sBAA2B,EACpC,QAAQ,GAAE,KAAK,GAAG,OAAe,GAChC,gBAAgB,CAqBlB;AAED;;GAEG;AACH,wBAAgB,qCAAqC,CACnD,OAAO,GAAE,sBAA2B,GACnC,gBAAgB,CAsBlB;AAED;;GAEG;AACH,wBAAgB,sCAAsC,CACpD,OAAO,GAAE,sBAA2B,GACnC,gBAAgB,CAqBlB;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAkB7E;AAED;;GAEG;AACH,wBAAgB,mCAAmC,IAAI,MAAM,CAsD5D;AAED;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,MAAM,CAqQvD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,sBAA2B;;;;;;;;;;;;;;;EAiBvE"}
|