Skip to content

Commit 72606e3

Browse files
committed
feat: status documentation
1 parent 1924957 commit 72606e3

6 files changed

Lines changed: 316 additions & 18 deletions

File tree

content/docs/platform/compliance/controls/index.mdx

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,24 @@ title: Controls
33
description: "Controls als Kernbaustein: Von Framework-Anforderungen über Implementierungen bis hin zu Evidences"
44
---
55

6+
import { getPageTreePeers } from 'fumadocs-core/server';
7+
import { source } from '@/lib/source';
8+
9+
<Cards>
10+
<Card title="Status" href="/platform/compliance/controls/status">
11+
Lerne mehr über den Control Status
12+
</Card>
13+
<Card title="Control Implementations" href="/platform/compliance/controls/control-implementations">
14+
Erfahre, wie Controls praktisch umgesetzt werden
15+
</Card>
16+
</Cards>
17+
618
## Controls: Der strukturierte Ansatz für nachweisbare Compliance
719

820
Controls bilden das strategische Fundament jeder effektiven Compliance-Strategie. Anders als bei traditionellen GRC-Tools, die sich auf das reine Hochladen von Policy-Dokumenten beschränken, implementiert Kopexa einen systematischen Control-basierten Ansatz, der messbare Sicherheitsziele mit konkreten Umsetzungsmaßnahmen verknüpft.
921

22+
23+
1024
## Was sind Controls?
1125

1226
Ein **Control** definiert ein spezifisches Sicherheits- oder Compliance-Ziel, das erreicht werden soll. Controls beschreiben nicht das "Wie", sondern das "Was" - sie geben vor, welcher Sicherheitsstandard erfüllt werden muss, ohne die konkrete Implementierung zu diktieren.
@@ -33,13 +47,13 @@ Ein **Control** definiert ein spezifisches Sicherheits- oder Compliance-Ziel, da
3347

3448
## Framework-Integration: Ein Control, mehrere Standards
3549

36-
Ein Control in Kopexa kann mehrere Compliance-Frameworks gleichzeitig abdecken.
50+
Ein Control in Kopexa kann mehrere Compliance-Frameworks gleichzeitig abdecken.
3751

38-
**Beispiel-Control:** *„Regelmäßige Überprüfung von Zugangsrechten“*
39-
- ISO 27001: A.9.2.5
40-
- SOC 2: CC6.2
41-
- NIST CSF: PR.AC-4
42-
- TISAX: 3.1.1
52+
**Beispiel-Control:** *„Regelmäßige Überprüfung von Zugangsrechten“*
53+
- ISO 27001: A.9.2.5
54+
- SOC 2: CC6.2
55+
- NIST CSF: PR.AC-4
56+
- TISAX: 3.1.1
4357

4458
<Callout>
4559
So wird Doppelarbeit reduziert und ein einheitlicher Nachweis über mehrere Frameworks hinweg möglich.
@@ -59,7 +73,7 @@ graph TD
5973
- **Definition**: Was soll erreicht werden?
6074
- **Beispiel**: "Alle Benutzerkonten müssen eindeutig identifizierbar sein"
6175

62-
### 2. Implementation (Umsetzungsmaßnahme)
76+
### 2. Implementation (Umsetzungsmaßnahme)
6377
- **Definition**: Wie wird das Control umgesetzt?
6478
- **Beispiel**: "Active Directory-basierte Benutzerauthentifizierung mit eindeutigen Benutzernamen"
6579

@@ -92,7 +106,7 @@ graph LR
92106
### 2. Implementation-Flexibilität gewährleisten
93107
Controls sollten verschiedene Implementierungsansätze zulassen:
94108

95-
**Control: "Sensible Daten werden gegen unbefugten Zugriff geschützt"**.
109+
**Control: "Sensible Daten werden gegen unbefugten Zugriff geschützt"**.
96110
Mögliche Implementations:
97111

98112
- Encryption-at-Rest via BitLocker
@@ -138,7 +152,7 @@ console.log(`Control ${controlStatus.name}: ${controlStatus.status}`);
138152

139153
### Traditionelle Policy-Uploads: Die Limitierungen
140154
- **Statischer Content**: Keine Verknüpfung zu aktuellen Implementierungen
141-
- **Audit-Ineffizienz**: Manuelle Prüfung jedes Dokuments erforderlich
155+
- **Audit-Ineffizienz**: Manuelle Prüfung jedes Dokuments erforderlich
142156
- **Redundanzen**: Gleiche Inhalte in verschiedenen Framework-Dokumenten
143157
- **Versionsprobleme**: Inkonsistente Policy-Versionen across Frameworks
144158

@@ -147,10 +161,10 @@ console.log(`Control ${controlStatus.name}: ${controlStatus.status}`);
147161

148162
- **Dynamic Mapping**: Ein Control bedient multiple Frameworks
149163
- **Implementation-Tracking**: Direkte Verknüpfung zu Umsetzungsmaßnahmen
150-
- **Automated Evidence**: Continuous Compliance-Monitoring
164+
- **Automated Evidence**: Continuous Compliance-Monitoring
151165
- **Audit-Readiness**: Jederzeit prüfbare Compliance-Status
152166

153167

154168
<Callout>
155169
Kopexa transformiert Compliance von einem dokumentenlastigen, reaktiven Prozess zu einem strukturierten, kontinuierlich überwachten System.
156-
</Callout>
170+
</Callout>
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
---
2+
title: Status Models
3+
description: Einheitliche Status-Logik für Controls, Control Implementations und Evidences
4+
---
5+
6+
## Warum Status-Modelle?
7+
8+
In klassischen GRC-Tools muss der Status oft **manuell gepflegt** werden: Excel-Spalten, Notizen oder Kommentare.
9+
Das führt zu **Inkonsistenzen**, widersprüchlichen Bewertungen und viel Nacharbeit in Audits.
10+
11+
Kopexa geht einen anderen Weg:
12+
Der Status wird **automatisch** berechnet – immer auf Basis der Verknüpfungen zwischen Controls, Implementations und Evidences.
13+
So entsteht eine **lebendige Compliance-Landkarte**, die ohne manuelles Pflegen konsistent bleibt und für Auditor:innen jederzeit nachvollziehbar ist.
14+
15+
<Callout>
16+
**Dein Vorteil:** Weniger Verwaltungsarbeit, weniger Diskussionen im Audit, mehr Zeit für die tatsächliche Verbesserung deiner Sicherheitsmaßnahmen.
17+
</Callout>
18+
19+
## Control Status
20+
21+
Controls sind die „oberste Ebene“ – sie definieren, **was** erreicht werden soll.
22+
Ihr Status ergibt sich automatisch aus den zugeordneten Implementations.
23+
24+
| Status | Bedeutung | Typische Ursache |
25+
|--------|-----------|------------------|
26+
| **PREPARING** | Control ist angelegt, aber noch nicht weiter bearbeitet | Neu erstellt |
27+
| **OUT_OF_SCOPE** | Control ist für den Scope nicht relevant | z. B. Technologie nicht im Einsatz |
28+
| **IN_PROGRESS** | Erste Arbeiten laufen, Implementations werden zugeordnet | Work in progress |
29+
| **NEEDS_APPROVAL** | Mindestens eine Implementation ist nicht genehmigt oder unvollständig | Review offen |
30+
| **FULFILLED** | Alle Implementations sind *PUBLISHED* | Erfolgreiche Umsetzung |
31+
32+
<Mermaid chart={`
33+
graph LR
34+
A[PREPARING] --> B[IN_PROGRESS]
35+
B --> C[NEEDS_APPROVAL]
36+
C -->|approved| D[FULFILLED]
37+
A --> E[OUT_OF_SCOPE]
38+
`} />
39+
40+
**Warum hilfreich?**
41+
- Du erkennst sofort, welche Controls noch offen oder blockiert sind.
42+
- Auditor:innen sehen eine klare Story: von Planung (PREPARING) bis Nachweis (FULFILLED).
43+
- OUT_OF_SCOPE verhindert, dass irrelevante Anforderungen dein Reporting aufblähen.
44+
45+
## Control Implementation Status
46+
47+
Implementations sind die konkreten **Maßnahmen (TOMs)**, die ein Control umsetzen.
48+
Ihr Status hängt ausschließlich von den hinterlegten Evidences ab.
49+
50+
| Status | Bedeutung | Typische Ursache |
51+
|--------|-----------|------------------|
52+
| **MISSING_EVIDENCE** | Keine oder zu wenige Evidences vorhanden | Maßnahme dokumentiert, aber nicht belegt |
53+
| **NEEDS_APPROVAL** | Mindestens eine Evidence ist noch nicht bestätigt oder unvollständig | Review offen |
54+
| **PUBLISHED** | Alle Evidences sind vorhanden und gültig | Vollständig umgesetzt |
55+
| **ARCHIVED** | Implementation ist nicht mehr aktiv gültig | Maßnahme ersetzt oder außer Betrieb |
56+
57+
<Mermaid chart={`
58+
graph LR
59+
A[MISSING_EVIDENCE] --> B[NEEDS_APPROVAL]
60+
B -->|approved| C[PUBLISHED]
61+
C --> D[ARCHIVED]
62+
`} />
63+
64+
**Warum hilfreich?**
65+
- Du siehst nicht nur, ob eine Maßnahme existiert, sondern ob sie **wirksam nachgewiesen** ist.
66+
- Das schützt vor „Papier-Controls“, die zwar dokumentiert, aber nicht überprüfbar sind.
67+
- ARCHIVED sorgt dafür, dass alte Maßnahmen nicht fälschlich als aktiv gewertet werden.
68+
69+
## Evidence Lifecycle
70+
71+
Evidences sind der **Beweis**, dass eine Implementation tatsächlich umgesetzt ist.
72+
Sie verknüpfen Maßnahmen mit Nachweisen – wie Policies, Audit-Logs, Screenshots oder Prozessdokumente.
73+
74+
In Kopexa hängen Evidences oft an **Dokumenten**, die selbst einen Lifecycle haben (Status, Review, Versionierung).
75+
Dieser Dokument-Lifecycle beeinflusst den Status der Evidence **automatisch**.
76+
77+
### Evidence Status
78+
79+
| Status | Bedeutung | Typische Ursache |
80+
|--------|-----------|------------------|
81+
| **PENDING** | Evidence ist angelegt, aber noch nicht geprüft | Neu erstellt |
82+
| **ACTION REQUIRED** | Unterliegendes Dokument oder Nachweis ist abgelaufen oder im Review | Dokument expired / Review fällig |
83+
| **PASSED** | Evidence ist gültig und überprüft | Dokument freigegeben |
84+
| **FAILED** | Evidence ist ungültig (z. B. Dokument gelöscht oder zurückgezogen) | Policy widerrufen / Fehlerhafte Evidence |
85+
86+
<Mermaid chart={`
87+
graph LR
88+
A[Document Lifecycle] --> B[Evidence Status]
89+
B --> C[Implementation Status]
90+
C --> D[Control Status]
91+
`} />
92+
93+
### Beispiel
94+
95+
- Eine Richtlinie (*Document*) läuft in den jährlichen Review-Zyklus.
96+
- Das Dokument springt auf den Status **"Review required"**.
97+
- Alle Evidences, die auf dieser Richtlinie basieren, wechseln automatisch auf **"ACTION REQUIRED"**.
98+
- Die betroffenen Implementations und Controls werden dadurch ebenfalls abgewertet.
99+
100+
So entsteht eine **durchgehende Kette**: Dokument → Evidence → Implementation → Control.
101+
102+
### Warum wichtig?
103+
104+
- **Realistische Nachweise:** Evidences spiegeln nicht nur einen Upload wider, sondern den echten Gültigkeitsstatus.
105+
- **Früherkennung:** Sobald ein Dokument im Review ist, erkennt Kopexa automatisch, dass Handlungsbedarf besteht.
106+
- **Audit-Sicherheit:** Auditor:innen sehen, dass Nachweise nicht nur einmalig hochgeladen, sondern kontinuierlich überwacht werden.
107+
108+
<Callout>
109+
**Benefit für dich:** Keine Excel-Reminder mehr nötig. Kopexa erkennt automatisch, wann Evidences „stale“ werden und markiert deine Controls entsprechend.
110+
</Callout>
111+
112+
## Best Practices
113+
114+
- **Automatisiert statt manuell:** Kein Status-Klicken mehr – Kopexa übernimmt das.
115+
- **Transparente Logik:** Jeder Status ist klar dokumentiert und nachvollziehbar.
116+
- **Audit-Ready:** Ein Prüfer kann jederzeit vom Control bis zur einzelnen Evidence zurückverfolgen, wie ein Status zustande kam.
117+
- **Fokus auf Wirksamkeit:** Dein Team investiert Zeit in echte Verbesserungen statt in Status-Pflege.
118+
119+
<Callout>
120+
Mit Kopexa siehst du nicht nur, **was geplant** ist, sondern auch **was nachweislich funktioniert**.
121+
</Callout>
122+
123+
## FAQ
124+
125+
<Accordions type="single">
126+
<Accordion title="Warum setzt Kopexa auf automatische Status?">
127+
Damit Compliance **konsistent und auditierbar** bleibt – unabhängig davon, wer im Team pflegt oder reviewt.
128+
</Accordion>
129+
<Accordion title="Kann ich den Status manuell überschreiben?">
130+
Nein. Status sind **immer systemisch berechnet**, um Manipulation und Fehler auszuschließen.
131+
Du steuerst einen Status indirekt, indem du **Implementations** pflegst und **Evidences** bereitstellst.
132+
</Accordion>
133+
<Accordion title="Was unterscheidet Evidence von einem Dokument?">
134+
Ein Dokument ist eine **Quelle** (z. B. Policy-PDF, Screenshot).
135+
Eine Evidence ist der **Nachweis**, dass dieses Dokument zur Umsetzung einer Implementation genutzt wird.
136+
</Accordion>
137+
<Accordion title='Warum gibt es "Out of Scope"?'>
138+
Damit du klar zeigen kannst, dass ein Control im **Audit-Scope irrelevant** ist – ohne es zu löschen.
139+
Das reduziert Rückfragen und zeigt Professionalität im Compliance-Management.
140+
</Accordion>
141+
</Accordions>

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"postinstall": "fumadocs-mdx"
1212
},
1313
"dependencies": {
14+
"@radix-ui/react-accordion": "^1.2.12",
1415
"@radix-ui/react-collapsible": "^1.1.12",
1516
"@radix-ui/react-popover": "^1.1.15",
1617
"@radix-ui/react-presence": "^1.1.5",

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/accordion.tsx

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
'use client';
2+
3+
import type {
4+
AccordionMultipleProps,
5+
AccordionSingleProps,
6+
} from '@radix-ui/react-accordion';
7+
import * as AccordionPrimitive from '@radix-ui/react-accordion';
8+
import { Check, ChevronRight, Link as LinkIcon } from 'lucide-react';
9+
import {
10+
type ComponentPropsWithoutRef,
11+
forwardRef,
12+
type ReactNode,
13+
useEffect,
14+
useRef,
15+
useState,
16+
} from 'react';
17+
import { cn } from '../lib/cn';
18+
import { useCopyButton } from 'fumadocs-ui/utils/use-copy-button';
19+
import { buttonVariants } from './ui/button';
20+
import { mergeRefs } from '../lib/merge-refs';
21+
22+
export const Accordions = forwardRef<
23+
HTMLDivElement,
24+
| Omit<AccordionSingleProps, 'value' | 'onValueChange'>
25+
| Omit<AccordionMultipleProps, 'value' | 'onValueChange'>
26+
>(({ type = 'single', className, defaultValue, ...props }, ref) => {
27+
const rootRef = useRef<HTMLDivElement>(null);
28+
const composedRef = mergeRefs(ref, rootRef);
29+
const [value, setValue] = useState<string | string[]>(() =>
30+
type === 'single' ? (defaultValue ?? '') : (defaultValue ?? []),
31+
);
32+
33+
useEffect(() => {
34+
const id = window.location.hash.substring(1);
35+
const element = rootRef.current;
36+
if (!element || id.length === 0) return;
37+
38+
const selected = document.getElementById(id);
39+
if (!selected || !element.contains(selected)) return;
40+
const value = selected.getAttribute('data-accordion-value');
41+
42+
if (value)
43+
setValue((prev) => (typeof prev === 'string' ? value : [value, ...prev]));
44+
}, []);
45+
46+
return (
47+
// @ts-expect-error -- Multiple types
48+
<AccordionPrimitive.Root
49+
type={type}
50+
ref={composedRef}
51+
value={value}
52+
onValueChange={setValue}
53+
collapsible={type === 'single' ? true : undefined}
54+
className={cn(
55+
'divide-y divide-fd-border overflow-hidden rounded-lg border bg-fd-card',
56+
className,
57+
)}
58+
{...props}
59+
/>
60+
);
61+
});
62+
63+
Accordions.displayName = 'Accordions';
64+
65+
export const Accordion = forwardRef<
66+
HTMLDivElement,
67+
Omit<
68+
ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>,
69+
'value' | 'title'
70+
> & {
71+
title: string | ReactNode;
72+
value?: string;
73+
}
74+
>(
75+
(
76+
{ title, className, id, value = String(title), children, ...props },
77+
ref,
78+
) => {
79+
return (
80+
<AccordionPrimitive.Item
81+
ref={ref}
82+
value={value}
83+
className={cn('scroll-m-24', className)}
84+
{...props}
85+
>
86+
<AccordionPrimitive.Header
87+
id={id}
88+
data-accordion-value={value}
89+
className="not-prose flex flex-row items-center text-fd-card-foreground font-medium has-focus-visible:bg-fd-accent"
90+
>
91+
<AccordionPrimitive.Trigger className="group flex flex-1 items-center gap-2 px-3 py-2.5 text-start focus-visible:outline-none">
92+
<ChevronRight className="size-4 shrink-0 text-fd-muted-foreground transition-transform duration-200 group-data-[state=open]:rotate-90" />
93+
{title}
94+
</AccordionPrimitive.Trigger>
95+
{id ? <CopyButton id={id} /> : null}
96+
</AccordionPrimitive.Header>
97+
<AccordionPrimitive.Content className="overflow-hidden data-[state=closed]:animate-fd-accordion-up data-[state=open]:animate-fd-accordion-down">
98+
<div className="px-4 pb-2 text-[15px] prose-no-margin">
99+
{children}
100+
</div>
101+
</AccordionPrimitive.Content>
102+
</AccordionPrimitive.Item>
103+
);
104+
},
105+
);
106+
107+
function CopyButton({ id }: { id: string }) {
108+
const [checked, onClick] = useCopyButton(() => {
109+
const url = new URL(window.location.href);
110+
url.hash = id;
111+
112+
return navigator.clipboard.writeText(url.toString());
113+
});
114+
115+
return (
116+
<button
117+
type="button"
118+
aria-label="Copy Link"
119+
className={cn(
120+
buttonVariants({
121+
color: 'ghost',
122+
className: 'text-fd-muted-foreground me-2',
123+
}),
124+
)}
125+
onClick={onClick}
126+
>
127+
{checked ? (
128+
<Check className="size-3.5" />
129+
) : (
130+
<LinkIcon className="size-3.5" />
131+
)}
132+
</button>
133+
);
134+
}
135+
136+
Accordion.displayName = 'Accordion';

0 commit comments

Comments
 (0)