/ utils / settings / mdm / constants.ts
constants.ts
 1  /**
 2   * Shared constants and path builders for MDM settings modules.
 3   *
 4   * This module has ZERO heavy imports (only `os`) — safe to use from mdmRawRead.ts.
 5   * Both mdmRawRead.ts and mdmSettings.ts import from here to avoid duplication.
 6   */
 7  
 8  import { homedir, userInfo } from 'os'
 9  import { join } from 'path'
10  
11  /** macOS preference domain for Claude Code MDM profiles. */
12  export const MACOS_PREFERENCE_DOMAIN = 'com.anthropic.claudecode'
13  
14  /**
15   * Windows registry key paths for Claude Code MDM policies.
16   *
17   * These keys live under SOFTWARE\Policies which is on the WOW64 shared key
18   * list — both 32-bit and 64-bit processes see the same values without
19   * redirection. Do not move these to SOFTWARE\ClaudeCode, as SOFTWARE is
20   * redirected and 32-bit processes would silently read from WOW6432Node.
21   * See: https://learn.microsoft.com/en-us/windows/win32/winprog64/shared-registry-keys
22   */
23  export const WINDOWS_REGISTRY_KEY_PATH_HKLM =
24    'HKLM\\SOFTWARE\\Policies\\ClaudeCode'
25  export const WINDOWS_REGISTRY_KEY_PATH_HKCU =
26    'HKCU\\SOFTWARE\\Policies\\ClaudeCode'
27  
28  /** Windows registry value name containing the JSON settings blob. */
29  export const WINDOWS_REGISTRY_VALUE_NAME = 'Settings'
30  
31  /** Path to macOS plutil binary. */
32  export const PLUTIL_PATH = '/usr/bin/plutil'
33  
34  /** Arguments for plutil to convert plist to JSON on stdout (append plist path). */
35  export const PLUTIL_ARGS_PREFIX = ['-convert', 'json', '-o', '-', '--'] as const
36  
37  /** Subprocess timeout in milliseconds. */
38  export const MDM_SUBPROCESS_TIMEOUT_MS = 5000
39  
40  /**
41   * Build the list of macOS plist paths in priority order (highest first).
42   * Evaluates `process.env.USER_TYPE` at call time so ant-only paths are
43   * included only when appropriate.
44   */
45  export function getMacOSPlistPaths(): Array<{ path: string; label: string }> {
46    let username = ''
47    try {
48      username = userInfo().username
49    } catch {
50      // ignore
51    }
52  
53    const paths: Array<{ path: string; label: string }> = []
54  
55    if (username) {
56      paths.push({
57        path: `/Library/Managed Preferences/${username}/${MACOS_PREFERENCE_DOMAIN}.plist`,
58        label: 'per-user managed preferences',
59      })
60    }
61  
62    paths.push({
63      path: `/Library/Managed Preferences/${MACOS_PREFERENCE_DOMAIN}.plist`,
64      label: 'device-level managed preferences',
65    })
66  
67    // Allow user-writable preferences for local MDM testing in ant builds only.
68    if (process.env.USER_TYPE === 'ant') {
69      paths.push({
70        path: join(
71          homedir(),
72          'Library',
73          'Preferences',
74          `${MACOS_PREFERENCE_DOMAIN}.plist`,
75        ),
76        label: 'user preferences (ant-only)',
77      })
78    }
79  
80    return paths
81  }