check_filevault_status
check_filevault_status
Reports full-disk encryption status — FileVault on macOS, BitLocker on Windows. Use during security compliance verification or when diagnosing boot/authentication issues.
Metadata
Name
check_filevault_status
Updated
2 months ago
Source
Risk
Low
Requires consent
false
Affected scope
user
Code
/**
* mcp/skills/checkFileVaultStatus.ts — check_filevault_status skill
*
* Reports full-disk encryption status — FileVault on macOS, BitLocker on
* Windows. Use during security compliance verification or when diagnosing
* boot/authentication issues.
*
* Platform strategy
* -----------------
* darwin `fdesetup status` and `fdesetup list`
* win32 PowerShell Get-BitLockerVolume
*
* Smoke test
* npx tsx -r dotenv/config mcp/skills/checkFileVaultStatus.ts
*/
import * as os from "os";
import { exec } from "child_process";
import { promisify } from "util";
import { z } from "zod";
const execAsync = promisify(exec);
// -- Meta ---------------------------------------------------------------------
export const meta = {
name: "check_filevault_status",
description:
"Reports full-disk encryption status — FileVault on macOS, BitLocker on Windows. " +
"Use during security compliance verification or when diagnosing boot/authentication issues.",
riskLevel: "low",
destructive: false,
requiresConsent: false,
supportsDryRun: false,
affectedScope: ["user"],
auditRequired: false,
schema: {},
} as const;
// -- Types --------------------------------------------------------------------
interface FileVaultResult {
platform: string;
enabled: boolean;
status: string;
encryptionMethod: string | null;
encryptionPercent: number | null;
enabledUsers: string[];
message: string;
}
// -- PowerShell helper --------------------------------------------------------
async function runPS(script: string): Promise<string> {
const encoded = Buffer.from(script, "utf16le").toString("base64");
const { stdout } = await execAsync(
`powershell.exe -NoProfile -NonInteractive -EncodedCommand ${encoded}`,
{ maxBuffer: 20 * 1024 * 1024 },
);
return stdout.trim();
}
// -- darwin implementation ----------------------------------------------------
async function checkFileVaultDarwin(): Promise<FileVaultResult> {
// fdesetup status
let statusOutput = "";
try {
({ stdout: statusOutput } = await execAsync("fdesetup status 2>/dev/null", {
maxBuffer: 1024 * 1024,
}));
} catch (err) {
statusOutput = (err as { stdout?: string }).stdout ?? "";
}
const enabled = /FileVault is On/i.test(statusOutput);
const status = statusOutput.trim() || "Unknown";
// fdesetup list — may require sudo; best-effort
let enabledUsers: string[] = [];
try {
const { stdout: listOutput } = await execAsync("fdesetup list 2>/dev/null", {
maxBuffer: 1024 * 1024,
});
enabledUsers = listOutput
.trim()
.split("\n")
.filter(Boolean)
.map((line) => line.split(",")[0].trim())
.filter(Boolean);
} catch {
// May require sudo — silently ignore
}
return {
platform: "darwin",
enabled,
status,
encryptionMethod: enabled ? "XTS-AES-128" : null,
encryptionPercent: enabled ? 100 : 0,
enabledUsers,
message: enabled
? `FileVault is enabled. ${enabledUsers.length} user(s) can unlock the disk.`
: "FileVault is disabled. Disk is not encrypted.",
};
}
// -- win32 implementation -----------------------------------------------------
async function checkFileVaultWin32(): Promise<FileVaultResult> {
const ps = `
$ErrorActionPreference = 'SilentlyContinue'
$vols = Get-BitLockerVolume | Select-Object MountPoint,EncryptionMethod,VolumeStatus,ProtectionStatus,EncryptionPercentage
if ($vols) { @($vols) | ConvertTo-Json -Depth 2 -Compress } else { '[]' }`.trim();
let enabled = false;
let status = "Unknown";
let encryptionMethod: string | null = null;
let encryptionPercent: number | null = null;
let message = "";
try {
const raw = await runPS(ps);
const parsed = JSON.parse(raw ?? "[]") as Array<{
MountPoint: string;
EncryptionMethod: string;
VolumeStatus: string;
ProtectionStatus: string;
EncryptionPercentage: number;
}>;
if (parsed.length > 0) {
const systemVol = parsed.find((v) => v.MountPoint === "C:") ?? parsed[0];
enabled = systemVol.ProtectionStatus === "On";
status = systemVol.VolumeStatus;
encryptionMethod = systemVol.EncryptionMethod || null;
encryptionPercent = systemVol.EncryptionPercentage ?? null;
message = `BitLocker on C: is ${enabled ? "ON" : "OFF"}. ` +
`Volume status: ${status}. ` +
`${encryptionPercent}% encrypted.`;
} else {
message = "No BitLocker volumes found or BitLocker is not available.";
}
} catch (err) {
message = `Error reading BitLocker status: ${(err as Error).message}`;
}
return {
platform: "win32",
enabled,
status,
encryptionMethod,
encryptionPercent,
enabledUsers: [],
message,
};
}
// -- Exported run function ----------------------------------------------------
export async function run(_args: Record<string, never> = {}) {
const platform = os.platform();
return platform === "win32"
? checkFileVaultWin32()
: checkFileVaultDarwin();
}
// -- CLI smoke test -----------------------------------------------------------
if (false) {
run({})
.then(r => console.log(JSON.stringify(r, null, 2)))
.catch((err: Error) => { console.error(err.message); process.exit(1); });
}