feat(canonical-controls): Canonical Control Library — rechtssichere Security Controls
All checks were successful
CI/CD / go-lint (push) Has been skipped
CI/CD / python-lint (push) Has been skipped
CI/CD / nodejs-lint (push) Has been skipped
CI/CD / test-go-ai-compliance (push) Successful in 40s
CI/CD / test-python-backend-compliance (push) Successful in 41s
CI/CD / test-python-document-crawler (push) Successful in 26s
CI/CD / test-python-dsms-gateway (push) Successful in 23s
CI/CD / validate-canonical-controls (push) Successful in 18s
CI/CD / deploy-hetzner (push) Successful in 2m26s

Eigenstaendig formulierte Security Controls mit unabhaengiger Taxonomie
und Open-Source-Verankerung (OWASP, NIST, ENISA). Keine BSI-Nomenklatur.

- Migration 044: 5 DB-Tabellen (frameworks, controls, sources, licenses, mappings)
- 10 Seed Controls mit 39 Open-Source-Referenzen
- License Gate: Quellen-Berechtigungspruefung (analysis/excerpt/embeddings/product)
- Too-Close-Detektor: 5 Metriken (exact-phrase, token-overlap, ngram, embedding, LCS)
- REST API: 8 Endpoints unter /v1/canonical/
- Go Loader mit Multi-Index (ID, domain, severity, framework)
- Frontend: Control Library Browser + Provenance Wiki
- CI/CD: validate-controls.py Job (schema, no-leak, open-anchors)
- 67 Tests (8 Go + 59 Python), alle PASS
- MkDocs Dokumentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-03-12 19:55:06 +01:00
parent 8442115e7c
commit 050f353192
20 changed files with 3935 additions and 0 deletions

View File

@@ -0,0 +1,204 @@
-- Migration 044: Canonical Control Library
-- Provides a legally defensible, independently authored security control library.
-- Controls are formulated independently (no BSI/proprietary nomenclature).
-- Every control MUST have open-source anchors (OWASP, NIST, ENISA).
-- Source provenance is tracked internally for audit, never shipped in product.
--
-- Tables:
-- 1. canonical_control_licenses — License metadata for source materials
-- 2. canonical_control_sources — Source registry (internal, not product-facing)
-- 3. canonical_control_frameworks — Registered control frameworks
-- 4. canonical_controls — The actual controls (product-facing)
-- 5. canonical_control_mappings — Provenance trail (internal audit)
BEGIN;
-- =============================================================================
-- 1. License Metadata
-- =============================================================================
CREATE TABLE IF NOT EXISTS canonical_control_licenses (
license_id VARCHAR(50) PRIMARY KEY,
name VARCHAR(255) NOT NULL,
terms_url TEXT,
commercial_use VARCHAR(20) NOT NULL
CHECK (commercial_use IN ('allowed', 'restricted', 'prohibited', 'unclear')),
ai_training_restriction VARCHAR(20),
tdm_allowed_under_44b VARCHAR(10)
CHECK (tdm_allowed_under_44b IN ('yes', 'no', 'unclear')),
deletion_required BOOLEAN DEFAULT false,
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- =============================================================================
-- 2. Source Registry (internal — never shipped in product)
-- =============================================================================
CREATE TABLE IF NOT EXISTS canonical_control_sources (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
source_id VARCHAR(50) UNIQUE NOT NULL,
title VARCHAR(500) NOT NULL,
publisher VARCHAR(100) NOT NULL,
url TEXT,
version_label VARCHAR(50),
language VARCHAR(5) DEFAULT 'de',
license_id VARCHAR(50) NOT NULL
REFERENCES canonical_control_licenses(license_id),
allowed_analysis BOOLEAN DEFAULT false,
allowed_store_excerpt BOOLEAN DEFAULT false,
allowed_ship_embeddings BOOLEAN DEFAULT false,
allowed_ship_in_product BOOLEAN DEFAULT false,
vault_retention_days INTEGER DEFAULT 30,
vault_access_tier VARCHAR(20) DEFAULT 'restricted'
CHECK (vault_access_tier IN ('restricted', 'internal', 'public')),
retrieved_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_ccs_license ON canonical_control_sources(license_id);
-- =============================================================================
-- 3. Control Frameworks
-- =============================================================================
CREATE TABLE IF NOT EXISTS canonical_control_frameworks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
framework_id VARCHAR(50) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
version VARCHAR(20) NOT NULL,
description TEXT,
owner VARCHAR(100) DEFAULT 'security-platform',
policy_version VARCHAR(20),
release_state VARCHAR(20) DEFAULT 'draft'
CHECK (release_state IN ('draft', 'review', 'approved', 'deprecated')),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- =============================================================================
-- 4. Canonical Controls (product-facing)
-- =============================================================================
CREATE TABLE IF NOT EXISTS canonical_controls (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
framework_id UUID NOT NULL
REFERENCES canonical_control_frameworks(id),
control_id VARCHAR(20) NOT NULL,
title VARCHAR(255) NOT NULL,
objective TEXT NOT NULL,
rationale TEXT NOT NULL,
scope JSONB NOT NULL DEFAULT '{}',
requirements JSONB NOT NULL DEFAULT '[]',
test_procedure JSONB NOT NULL DEFAULT '[]',
evidence JSONB NOT NULL DEFAULT '[]',
severity VARCHAR(20) NOT NULL
CHECK (severity IN ('low', 'medium', 'high', 'critical')),
risk_score NUMERIC(3,1) CHECK (risk_score >= 0 AND risk_score <= 10),
implementation_effort VARCHAR(2)
CHECK (implementation_effort IN ('s', 'm', 'l', 'xl')),
evidence_confidence NUMERIC(3,2) CHECK (evidence_confidence >= 0 AND evidence_confidence <= 1),
open_anchors JSONB NOT NULL DEFAULT '[]',
release_state VARCHAR(20) DEFAULT 'draft'
CHECK (release_state IN ('draft', 'review', 'approved', 'deprecated')),
tags JSONB DEFAULT '[]',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE (framework_id, control_id)
);
CREATE INDEX IF NOT EXISTS idx_canonical_controls_domain
ON canonical_controls ((LEFT(control_id, 4)));
CREATE INDEX IF NOT EXISTS idx_canonical_controls_severity
ON canonical_controls (severity);
CREATE INDEX IF NOT EXISTS idx_canonical_controls_release
ON canonical_controls (release_state);
CREATE INDEX IF NOT EXISTS idx_canonical_controls_framework
ON canonical_controls (framework_id);
-- =============================================================================
-- 5. Control Mappings / Provenance (internal audit trail)
-- =============================================================================
CREATE TABLE IF NOT EXISTS canonical_control_mappings (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
control_id UUID NOT NULL
REFERENCES canonical_controls(id) ON DELETE CASCADE,
source_id UUID NOT NULL
REFERENCES canonical_control_sources(id),
mapping_type VARCHAR(30) NOT NULL
CHECK (mapping_type IN ('inspired_by_internal', 'corroborated_by_open', 'derived_only_open')),
attribution_class VARCHAR(20) NOT NULL
CHECK (attribution_class IN ('internal_only', 'product_ok')),
source_locator VARCHAR(100),
paraphrase_note TEXT,
excerpt_hashes JSONB DEFAULT '[]',
similarity_report JSONB,
reviewed_by VARCHAR(100),
reviewed_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_ccm_control ON canonical_control_mappings(control_id);
CREATE INDEX IF NOT EXISTS idx_ccm_source ON canonical_control_mappings(source_id);
-- =============================================================================
-- SEED: Licenses
-- =============================================================================
INSERT INTO canonical_control_licenses (license_id, name, terms_url, commercial_use, ai_training_restriction, tdm_allowed_under_44b, deletion_required, notes)
VALUES
('BSI_TOS_2025', 'BSI Nutzungsbedingungen', 'https://www.bsi.bund.de/impressum', 'restricted', 'unclear', 'yes', true,
'Kommerziell nur mit Zustimmung. TDM unter UrhG 44b erlaubt, Kopien danach loeschen.'),
('OWASP_CC_BY_SA', 'Creative Commons BY-SA 4.0', 'https://creativecommons.org/licenses/by-sa/4.0/', 'allowed', null, 'yes', false,
'Offen, Attribution + ShareAlike. Kommerziell erlaubt.'),
('NIST_PUBLIC_DOMAIN', 'US Government Public Domain', 'https://www.nist.gov/open/copyright-fair-use-and-licensing-statements-srd-data-software-and-technical-series-publications', 'allowed', null, 'yes', false,
'US-Regierungswerke sind gemeinfrei. Keine Einschraenkungen.'),
('ENISA_CC_BY', 'Creative Commons BY 4.0', 'https://creativecommons.org/licenses/by/4.0/', 'allowed', null, 'yes', false,
'Offen, nur Attribution. Kommerziell erlaubt.'),
('ETSI_RESTRICTIVE', 'ETSI Terms of Use', 'https://www.etsi.org/intellectual-property-rights', 'prohibited', 'prohibited', 'no', true,
'Kommerzielle Nutzung und AI-Training ausdruecklich verboten.'),
('ISO_PAYWALLED', 'ISO Copyright', 'https://www.iso.org/privacy-and-copyright.html', 'prohibited', 'prohibited', 'unclear', true,
'Kostenpflichtig. Kein Recht auf Reproduktion, Paraphrase muss hinreichend abstrahiert sein.'),
('IEC_AI_PROHIBITED', 'IEC Terms of Use', 'https://www.iec.ch/terms-conditions', 'prohibited', 'prohibited', 'no', true,
'AI-Training explizit verboten.'),
('CSA_NC', 'CSA Noncommercial', 'https://cloudsecurityalliance.org/license/', 'restricted', null, 'unclear', false,
'Noncommercial license. Kommerziell nur mit separater Vereinbarung.'),
('CIS_CC_BY_NC_ND', 'Creative Commons BY-NC-ND 4.0', 'https://creativecommons.org/licenses/by-nc-nd/4.0/', 'prohibited', null, 'yes', false,
'Kein kommerzieller Gebrauch, keine Ableitungen.')
ON CONFLICT (license_id) DO NOTHING;
-- =============================================================================
-- SEED: Sources
-- =============================================================================
INSERT INTO canonical_control_sources (source_id, title, publisher, url, version_label, language, license_id, allowed_analysis, allowed_store_excerpt, allowed_ship_embeddings, allowed_ship_in_product)
VALUES
('BSI_TR03161_1', 'BSI TR-03161 Teil 1 — Mobile Anwendungen', 'BSI', 'https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Publikationen/TechnischeRichtlinien/TR03161/BSI-TR-03161-1.html', '1.0', 'de', 'BSI_TOS_2025', true, false, false, false),
('BSI_TR03161_2', 'BSI TR-03161 Teil 2 — Web-Anwendungen', 'BSI', 'https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Publikationen/TechnischeRichtlinien/TR03161/BSI-TR-03161-2.html', '1.0', 'de', 'BSI_TOS_2025', true, false, false, false),
('BSI_TR03161_3', 'BSI TR-03161 Teil 3 — Hintergrunddienste', 'BSI', 'https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Publikationen/TechnischeRichtlinien/TR03161/BSI-TR-03161-3.html', '1.0', 'de', 'BSI_TOS_2025', true, false, false, false),
('OWASP_ASVS', 'OWASP Application Security Verification Standard', 'OWASP Foundation', 'https://owasp.org/www-project-application-security-verification-standard/', '4.0.3', 'en', 'OWASP_CC_BY_SA', true, true, true, true),
('OWASP_MASVS', 'OWASP Mobile Application Security Verification Standard', 'OWASP Foundation', 'https://mas.owasp.org/', '2.1.0', 'en', 'OWASP_CC_BY_SA', true, true, true, true),
('OWASP_TOP10', 'OWASP Top 10', 'OWASP Foundation', 'https://owasp.org/www-project-top-ten/', '2021', 'en', 'OWASP_CC_BY_SA', true, true, true, true),
('NIST_SP800_53', 'NIST SP 800-53 Rev. 5 — Security and Privacy Controls', 'NIST', 'https://csrc.nist.gov/publications/detail/sp/800-53/rev-5/final', 'Rev.5', 'en', 'NIST_PUBLIC_DOMAIN', true, true, true, true),
('NIST_SP800_63B', 'NIST SP 800-63B — Digital Identity Guidelines (Authentication)', 'NIST', 'https://pages.nist.gov/800-63-3/sp800-63b.html', 'Rev.3', 'en', 'NIST_PUBLIC_DOMAIN', true, true, true, true),
('ENISA_GOOD_PRACTICES', 'ENISA Good Practices for Security of IoT/Mobile', 'ENISA', 'https://www.enisa.europa.eu/publications', null, 'en', 'ENISA_CC_BY', true, true, true, true),
('CIS_CONTROLS', 'CIS Critical Security Controls', 'Center for Internet Security', 'https://www.cisecurity.org/controls', 'v8', 'en', 'CIS_CC_BY_NC_ND', true, false, false, false)
ON CONFLICT (source_id) DO NOTHING;
-- =============================================================================
-- SEED: Default Framework
-- =============================================================================
INSERT INTO canonical_control_frameworks (framework_id, name, version, description, owner, release_state)
VALUES (
'bp_security_v1',
'BreakPilot Security Controls',
'1.0',
'Eigenstaendig formulierte Security Controls basierend auf offenem Wissen (OWASP, NIST, ENISA). Unabhaengige Taxonomie und Nomenklatur.',
'security-platform',
'draft'
)
ON CONFLICT (framework_id) DO NOTHING;
COMMIT;