feat(compliance): add ISO/IEC 27001:2022 and ISO/IEC 42001:2023 frameworks
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled

ISO 27001:2022: 37 Annex A controls across 4 themes (Organizational,
People, Physical, Technological) mapped to MITRE ATT&CK techniques.

ISO 42001:2023: 25 Annex A controls for AI Management Systems mapped to
relevant ATT&CK techniques covering AI supply chain, data pipeline
integrity, model serving security, and third-party AI risk.

Backend: import functions, _import_curated_framework() shared helper,
and POST /compliance/import/iso-27001 + iso-42001 endpoints.
Frontend: API client functions + import buttons in CompliancePage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kitos
2026-06-03 15:50:54 +02:00
parent 460faf9935
commit 0b82d96bcc
4 changed files with 640 additions and 3 deletions

View File

@@ -126,3 +126,15 @@ export async function importDoraMappings(): Promise<Record<string, unknown>> {
const { data } = await client.post("/compliance/import/dora");
return data;
}
/** Import ISO/IEC 27001:2022 Annex A compliance mappings (admin). */
export async function importIso27001Mappings(): Promise<Record<string, unknown>> {
const { data } = await client.post("/compliance/import/iso-27001");
return data;
}
/** Import ISO/IEC 42001:2023 AI Management System compliance mappings (admin). */
export async function importIso42001Mappings(): Promise<Record<string, unknown>> {
const { data } = await client.post("/compliance/import/iso-42001");
return data;
}

View File

@@ -8,6 +8,8 @@ import {
importNistMappings,
importCisMappings,
importDoraMappings,
importIso27001Mappings,
importIso42001Mappings,
type ComplianceFrameworkSummary,
} from "../api/compliance";
import { useAuth } from "../context/AuthContext";
@@ -90,7 +92,28 @@ export default function CompliancePage() {
},
});
const isImporting = importNist.isPending || importCis.isPending || importDora.isPending;
const importIso27001 = useMutation({
mutationFn: importIso27001Mappings,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["compliance-frameworks"] });
queryClient.invalidateQueries({ queryKey: ["compliance-status"] });
},
});
const importIso42001 = useMutation({
mutationFn: importIso42001Mappings,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["compliance-frameworks"] });
queryClient.invalidateQueries({ queryKey: ["compliance-status"] });
},
});
const isImporting =
importNist.isPending ||
importCis.isPending ||
importDora.isPending ||
importIso27001.isPending ||
importIso42001.isPending;
if (isLoading && !frameworkStatus) {
return (
@@ -232,10 +255,28 @@ export default function CompliancePage() {
{importDora.isPending ? <Loader2 className="h-3 w-3 animate-spin" /> : <Plus className="h-3 w-3" />}
DORA
</button>
{(importNist.isSuccess || importCis.isSuccess || importDora.isSuccess) && (
<button
onClick={() => importIso27001.mutate()}
disabled={isImporting}
className="flex items-center gap-1.5 rounded-lg border border-gray-700 bg-gray-800 px-3 py-1.5 text-xs font-medium text-gray-300 hover:border-cyan-500/50 hover:text-white transition-colors disabled:opacity-50"
>
{importIso27001.isPending ? <Loader2 className="h-3 w-3 animate-spin" /> : <Plus className="h-3 w-3" />}
ISO 27001:2022
</button>
<button
onClick={() => importIso42001.mutate()}
disabled={isImporting}
className="flex items-center gap-1.5 rounded-lg border border-gray-700 bg-gray-800 px-3 py-1.5 text-xs font-medium text-gray-300 hover:border-cyan-500/50 hover:text-white transition-colors disabled:opacity-50"
>
{importIso42001.isPending ? <Loader2 className="h-3 w-3 animate-spin" /> : <Plus className="h-3 w-3" />}
ISO 42001:2023
</button>
{(importNist.isSuccess || importCis.isSuccess || importDora.isSuccess ||
importIso27001.isSuccess || importIso42001.isSuccess) && (
<span className="text-xs text-green-400">Import complete</span>
)}
{(importNist.isError || importCis.isError || importDora.isError) && (
{(importNist.isError || importCis.isError || importDora.isError ||
importIso27001.isError || importIso42001.isError) && (
<span className="text-xs text-red-400">Import failed</span>
)}
</div>