311 lines
15 KiB
Markdown
311 lines
15 KiB
Markdown
# AI Disclosure Standard 1.8.0
|
|
|
|
Ein zustandsloser Go-Dienst für sichtbare und maschinenlesbare Erklärungen zur KI-Nutzung in Artikeln, Webseiten und einzelnen Inhaltsbestandteilen.
|
|
|
|
## Funktionen
|
|
|
|
- einzelne Deklarationen und zusammengefasste Artikel-/Webseiten-Deklarationen;
|
|
- SVG-Badges, HTML-Erklärung und JSON-LD unter einem gemeinsamen Link;
|
|
- Text, Titelbild, weitere Bilder, Recherche, Übersetzung, Audio, Video und Code getrennt erfassbar;
|
|
- automatisch erzeugte, professionell formulierte Zusammenfassung als Fließtext und strukturierte Tabelle;
|
|
- frei wählbare Nachweisgrundlage: Selbsterklärung, technisch protokolliert, signiert oder verifiziert;
|
|
- Deutsch, Englisch, Französisch, Spanisch, Italienisch, Niederländisch, Portugiesisch und Polnisch;
|
|
- Sprachumschalter direkt auf der Ergebnisseite;
|
|
- mehrsprachige Hintergrundseite zu Artikel 50 des EU AI Act, Kennzeichnungspflichten und freiwilliger Transparenz;
|
|
- optionale lizenzierte Funktionen für eigene Texte und Badge-Darstellung;
|
|
- Offline-, Hybrid- und Online-Prüfung über die eigenständige Universal License Platform;
|
|
- konfigurierbare Seiten für Impressum, Datenschutz und Barrierefreiheit;
|
|
- CSP mit Request-Nonce, minimierte Logs, vertrauensgebundene Proxy-Header und gehärtete Container-Defaults;
|
|
- Health-, Readiness- und optional geschützter Prometheus-Endpunkt;
|
|
- Docker-, Kubernetes- und Docker-Swarm-Deployment;
|
|
- optionaler zweiter Bulk-Container für wiederverwendbare Vorlagen und bis zu 500 Inhalts-URLs pro Lauf, ohne Benutzerkonten oder Datenbank.
|
|
|
|
## Start unter Windows
|
|
|
|
```powershell
|
|
go run .\cmd\server
|
|
```
|
|
|
|
Danach:
|
|
|
|
```text
|
|
Generator: http://localhost:8080/
|
|
Produktseite: http://localhost:8080/product
|
|
Hintergrund: http://localhost:8080/background
|
|
Impressum: http://localhost:8080/impressum
|
|
Datenschutz: http://localhost:8080/datenschutz
|
|
Barrierefrei: http://localhost:8080/barrierefreiheit
|
|
Healthcheck: http://localhost:8080/healthz
|
|
Funktionen: http://localhost:8080/v1/capabilities
|
|
Bulk: http://localhost:8081/
|
|
```
|
|
|
|
Go lädt `.env` nicht selbst. Unter PowerShell kann die Datei vor dem Start in die Prozessumgebung übernommen werden oder Docker Compose mit `--env-file .env` verwendet werden.
|
|
|
|
## Docker Compose
|
|
|
|
```powershell
|
|
Copy-Item .env.example .env
|
|
docker compose --env-file .env up -d --build
|
|
```
|
|
|
|
|
|
## Bulk-Generator
|
|
|
|
Der optionale Container `ai-disclosure-bulk` ist bewusst klein und zustandslos. Er enthält **keine eigene rechtliche Entscheidungslogik**. Stattdessen ruft er für jede Inhalts-URL den Core-Endpunkt `/v1/render` auf und setzt ausschließlich `subject` neu. Dadurch bleiben normaler Generator, API und Bulk-Ausgabe auf demselben Regel- und Renderingstand.
|
|
|
|
Typischer Ablauf:
|
|
|
|
1. Kennzeichnung im normalen Generator konfigurieren.
|
|
2. **Als Bulk-Vorlage öffnen** auswählen.
|
|
3. Optional ein Website-Profil mit wiederkehrenden Angaben wie Autor, Impressums-/Verantwortlichkeits-URL und Beschwerdestelle im Browser speichern.
|
|
4. Absolute URLs oder relative Pfade einfügen. Für relative Pfade kann einmalig eine Basis-URL gesetzt werden.
|
|
5. HTML, Markdown, JSON-LD, JSONL oder CSV erzeugen und kopieren bzw. herunterladen.
|
|
|
|
Der Bulk-Container ruft die eingegebenen Inhalts-URLs **nicht** ab. Website-Profile und gespeicherte Kennzeichnungsvorlagen werden ausschließlich im `localStorage` des Browsers gespeichert. URL-Listen und erzeugte Ergebnisse werden weder im Browser dauerhaft gespeichert noch serverseitig persistiert. Profile und Vorlagen können als JSON exportiert, importiert oder vollständig gelöscht werden.
|
|
|
|
Relevante Variablen:
|
|
|
|
| Variable | Standard | Bedeutung |
|
|
|---|---|---|
|
|
| `BULK_URL` | leer / in der Beispielkonfiguration `http://localhost:8081` | öffentliche URL des Bulk-Generators; aktiviert den Übergabe-Button im normalen Generator |
|
|
| `CORE_INTERNAL_URL` | `http://app:8080` | feste interne Origin des Disclosure-Core; der Bulk-Dienst folgt keinen frei eingegebenen Ziel-URLs |
|
|
| `DISCLOSURE_BASE_URL` | `http://localhost:8080` | öffentliche Core-Origin für Links in der Bulk-Oberfläche |
|
|
| `GENERATOR_URL` | wie `DISCLOSURE_BASE_URL` | öffentlicher Link zurück zum normalen Generator |
|
|
| `BULK_MAX_URLS` | `500` | maximale Zahl an Inhalts-URLs je Lauf, maximal 5000 |
|
|
| `BULK_WORKERS` | `4` | parallele Core-Render-Aufrufe, maximal 32 |
|
|
| `BULK_REQUEST_TIMEOUT` | `8s` | Timeout je Core-Aufruf |
|
|
|
|
Die Vorlagenübergabe vom normalen Generator zum Bulk-Generator erfolgt im URL-Fragment (`#template=...`). Dieses Fragment wird vom Browser nicht als Teil der HTTP-Anfrage an den Server gesendet und nach dem Import aus der Adresszeile entfernt.
|
|
|
|
## Lizenzprüfung
|
|
|
|
Dieses Projekt stellt **keine Lizenzen aus** und enthält keine Schlüsselgenerierung, privaten Schlüssel, Lizenzverwaltung, Admin-Oberfläche oder eigenen Lizenzserver. Diese Aufgaben gehören ausschließlich in die separat betriebene **Universal License Platform**.
|
|
|
|
Der Produktserver enthält nur den Laufzeit-Client und akzeptiert:
|
|
|
|
```env
|
|
LICENSE_TOKEN=...
|
|
LICENSE_MODE=offline
|
|
LICENSE_SERVER_URL=
|
|
LICENSE_INSTANCE_ID=
|
|
```
|
|
|
|
Der Produktname ist fest verdrahtet:
|
|
|
|
```text
|
|
ai-disclosure-standard
|
|
```
|
|
|
|
Für die vorhandenen Funktionen verwendet die Plattform diese Feature-IDs:
|
|
|
|
```text
|
|
custom_text
|
|
custom_badge
|
|
white_label
|
|
```
|
|
|
|
### Vertrauensschlüssel einbetten
|
|
|
|
Die öffentlichen Issuer- und Lease-Schlüssel werden von der Universal License Platform bereitgestellt. Lade dort den Trust Store herunter und ersetze vor dem Build:
|
|
|
|
```text
|
|
internal/app/trusted_keys.json
|
|
```
|
|
|
|
PowerShell-Beispiel:
|
|
|
|
```powershell
|
|
Invoke-WebRequest `
|
|
"https://licenses.example.org/api/v1/trust-store" `
|
|
-OutFile ".\internal\app\trusted_keys.json"
|
|
|
|
go build .\cmd\server
|
|
```
|
|
|
|
Der Trust Store wird mit `go:embed` fest in das Binary eingebaut. Es gibt absichtlich kein `LICENSE_PUBLIC_KEY` und keinen zur Laufzeit austauschbaren Trust Store.
|
|
|
|
### Prüfmodi
|
|
|
|
**Offline** prüft den signierten Lizenz-Token ausschließlich lokal.
|
|
|
|
```env
|
|
LICENSE_MODE=offline
|
|
LICENSE_TOKEN=...
|
|
```
|
|
|
|
**Hybrid** fragt die Universal License Platform ab und speichert ein kurzlebiges, signiertes Lease. Bei temporärer Nichterreichbarkeit kann das letzte gültige Lease innerhalb der in der Lizenz festgelegten Grace-Periode verwendet werden.
|
|
|
|
```env
|
|
LICENSE_MODE=hybrid
|
|
LICENSE_TOKEN=...
|
|
LICENSE_CACHE_FILE=/data/license-lease.json
|
|
```
|
|
|
|
**Online** benötigt eine erfolgreiche aktuelle Prüfung durch die Plattform.
|
|
|
|
```env
|
|
LICENSE_MODE=online
|
|
LICENSE_TOKEN=...
|
|
```
|
|
|
|
Bei Hybrid- und Online-Lizenzen übernimmt der Client bevorzugt die von der Plattform signiert in der Lizenz gespeicherte Server-URL. `LICENSE_SERVER_URL` ist nur ein expliziter Override beziehungsweise Fallback.
|
|
|
|
Der Client verwendet die Plattform-API:
|
|
|
|
```text
|
|
POST /api/v1/licenses/validate
|
|
```
|
|
|
|
und unterstützt für bestehende Installationen weiterhin:
|
|
|
|
```text
|
|
POST /v1/introspect
|
|
```
|
|
|
|
Weitere Einzelheiten stehen in [`docs/LICENSE-INTEGRATION.md`](docs/LICENSE-INTEGRATION.md). Für bestehende 1.5-Installationen siehe [`docs/MIGRATION-1.5-TO-1.6.md`](docs/MIGRATION-1.5-TO-1.6.md).
|
|
|
|
## Konfiguration
|
|
|
|
### Betrieb und Sicherheit
|
|
|
|
| Variable | Standard | Bedeutung |
|
|
|---|---|---|
|
|
| `LISTEN_ADDRESS` | `:8080` | HTTP-Adresse |
|
|
| `BASE_URL` | `http://localhost:8080` | öffentliche Origin ohne Pfad, Query oder Fragment |
|
|
| `PUBLIC_NAME` | `AI Usage Disclosure` | sichtbarer Produktname |
|
|
| `CONTACT_URL` | Projektseite | Kontakt-/Informationsseite |
|
|
| `DEFAULT_LANGUAGE` | `de` | Standardsprache |
|
|
| `TRUST_PROXY` | `false` | Proxy-Header nur berücksichtigen, wenn zusätzlich vertrauenswürdige Netze gesetzt sind |
|
|
| `TRUSTED_PROXY_CIDRS` | leer | kommagetrennte CIDRs der tatsächlich kontrollierten Reverse Proxies |
|
|
| `LOG_CLIENT_IP` | `false` | Client-IP in Anwendungslogs aufnehmen; aus Datenschutzgründen standardmäßig deaktiviert |
|
|
| `ENABLE_HSTS` | `true` | HSTS bei einer `https://`-Basis-URL senden |
|
|
| `METRICS_ENABLED` | `false` | `/metrics` aktivieren |
|
|
| `METRICS_TOKEN` | leer | bei aktiviertem `/metrics` verpflichtender Bearer-Token; auch als `METRICS_TOKEN_FILE` |
|
|
|
|
### Betreiber- und Datenschutzangaben
|
|
|
|
Die Seiten `/impressum`, `/datenschutz` und `/barrierefreiheit` werden aus Umgebungsvariablen erzeugt. Mindestens `LEGAL_NAME`, `LEGAL_ADDRESS`, `LEGAL_EMAIL`, `HOSTING_PROVIDER`, `LOG_RETENTION` und `CONSUMER_DISPUTE_STATUS` müssen vor öffentlichem Betrieb geprüft werden. Mit `LEGAL_STRICT=true` startet der Server nicht, solange Pflichtwerte fehlen oder Platzhalter wie `REPLACE_ME` enthalten.
|
|
|
|
Weitere Variablen stehen vollständig in [`.env.example`](.env.example). Dazu gehören Vertretungsberechtigte, Register- und Umsatzsteuerangaben, redaktionell Verantwortliche, Datenschutzkontakt, Empfänger, Drittlandübermittlungen, Aufsichtsbehörde, Verbraucherstreitbeilegung und Barrierefreiheitskontakt.
|
|
|
|
## Lizenzprüfung
|
|
|
|
| Variable | Standard | Bedeutung |
|
|
|---|---|---|
|
|
| `LICENSE_TOKEN` | leer | von der Universal License Platform ausgestellter Token |
|
|
| `LICENSE_MODE` | `offline` | Mindestmodus `offline`, `hybrid` oder `online` |
|
|
| `LICENSE_SERVER_URL` | leer | optionaler Prüfserver-Override |
|
|
| `LICENSE_INSTANCE_ID` | leer | optionale Instanzbindung |
|
|
| `LICENSE_CACHE_FILE` | `./data/license-lease.json` | signierter Hybrid-Lease-Cache |
|
|
| `LICENSE_REFRESH_INTERVAL` | `15m` | Hintergrundaktualisierung |
|
|
| `LICENSE_REQUEST_TIMEOUT` | `5s` | Timeout der Onlineprüfung |
|
|
|
|
Die mitgelieferten Rechtstexte sind eine technisch abgestimmte Vorlage, keine individuelle Rechtsberatung. Die konkrete Einordnung hängt unter anderem von Betreiber, Hosting, Vertragsmodell, Zielgruppe, Zusatzdiensten und redaktionellen Inhalten ab. Siehe [`docs/LEGAL-AND-SECURITY.md`](docs/LEGAL-AND-SECURITY.md) und den [`Reviewbericht vom 20. Juli 2026`](docs/REVIEW-2026-07-20.md).
|
|
|
|
Für die Abgrenzung zum EU AI Act und insbesondere zu Artikel 4 und Artikel 50 siehe außerdem [`docs/EU-AI-ACT-COMPLIANCE.md`](docs/EU-AI-ACT-COMPLIANCE.md). Das JSON-LD dieses Projekts ist ergänzende Dokumentation und kein automatischer Ersatz für eine Provider-Markierung nach Artikel 50 Absatz 2.
|
|
|
|
## API
|
|
|
|
```text
|
|
GET /badge/{preset}.svg
|
|
GET /v1/badge.svg
|
|
GET /background
|
|
GET /impressum
|
|
GET /datenschutz
|
|
GET /barrierefreiheit
|
|
GET /declaration
|
|
GET /v1/declaration.json
|
|
GET /v1/render HTML, Markdown und JSON-LD aus denselben Parametern
|
|
POST /v1/validate
|
|
GET /v1/capabilities
|
|
GET /healthz
|
|
GET /readyz
|
|
GET /metrics optional, standardmäßig deaktiviert
|
|
```
|
|
|
|
Beispiel für eine Artikelerklärung:
|
|
|
|
```text
|
|
/declaration?mode=article&textExtent=none&textReview=none&imageExtent=full&imageReview=editorial&researchExtent=assisted&researchReview=expert&assurance=technicallyRecorded&lang=de
|
|
```
|
|
|
|
### SVG-Darstellungen
|
|
|
|
Der Query-Parameter `theme` unterstützt drei Darstellungen:
|
|
|
|
| Wert | Ausgabe |
|
|
|---|---|
|
|
| `color` | klassisches zweifarbiges Text-Badge |
|
|
| `mono` | monochromes Text-Badge |
|
|
| `emoji` | quadratisches, rein grafisches SVG-Symbol mit zugänglichem Titel |
|
|
|
|
Die Emoji-Variante verwendet je nach Preset ein Mensch-, Recherche-, Zusammenfassungs- oder Blitzsymbol. Beispiel:
|
|
|
|
```text
|
|
/badge/research.svg?theme=emoji&lang=de&link=auto
|
|
```
|
|
|
|
Bei `theme=emoji` werden `style=flat` und `style=flat-square` ignoriert, da die Ausgabe immer quadratisch ist. Mit der Pro-Funktion `custom_badge` steuert `leftColor` die Symbolfarbe und `rightColor` die Hintergrundfarbe.
|
|
|
|
|
|
### Nachweisgrundlage
|
|
|
|
Der Generator bietet vier interoperable Werte. Sie werden über den Query-Parameter `assurance` an HTML- und JSON-LD-Ausgaben übertragen:
|
|
|
|
| Wert | Bedeutung |
|
|
|---|---|
|
|
| `selfDeclared` | Die veröffentlichende Person oder Organisation stellt die Angaben selbst bereit. |
|
|
| `technicallyRecorded` | Die Angaben wurden im Erstellungs- oder Veröffentlichungsprozess technisch protokolliert. |
|
|
| `signed` | Die Erklärung wurde digital signiert; Herkunft und Unverändertheit können geprüft werden. |
|
|
| `verified` | Die Angaben wurden nach einem dokumentierten Verfahren zusätzlich verifiziert. |
|
|
|
|
Eine digitale Signatur bestätigt die Herkunft und Integrität der Erklärung, nicht automatisch die inhaltliche Richtigkeit ihrer Angaben. Nicht zutreffende Nachweisstufen sollten nicht ausgewählt werden.
|
|
|
|
## Entwicklung und Prüfung
|
|
|
|
```powershell
|
|
go test .\...
|
|
go vet .\...
|
|
```
|
|
|
|
Der eingebundene, reine Laufzeit-Client wird separat geprüft:
|
|
|
|
```powershell
|
|
Set-Location .\third_party\license-platform-client
|
|
go test .\...
|
|
```
|
|
|
|
Gesamtprüfung über Make:
|
|
|
|
```bash
|
|
make check
|
|
```
|
|
|
|
## Projektgrenze
|
|
|
|
Im Hauptprojekt verbleiben ausschließlich:
|
|
|
|
- ein eingebetteter öffentlicher Trust Store;
|
|
- ein verifikationsfähiger Client;
|
|
- Feature- und Limit-Abfragen;
|
|
- optionaler signierter Lease-Cache.
|
|
|
|
Nicht enthalten sind:
|
|
|
|
- private Schlüssel;
|
|
- Keygen oder Lizenzsignierung;
|
|
- Lizenzportal oder Admin-API;
|
|
- Lizenzdatenbank;
|
|
- Widerrufsverwaltung oder Lease-Signierung.
|
|
|
|
Diese Funktionen werden nur in der eigenständigen Universal License Platform betrieben.
|
|
|
|
### Art.-50-Kontext (Schema 1.3)
|
|
|
|
Der Generator trennt seit Schema 1.3 bewusst zwischen **Inhalt/KI-Nutzung**, **Art.-50-Selbsteinordnung**, **Veröffentlichungs-/Verantwortlichkeitsangaben** und **Ausgabe**. Abhängige Eingabefelder werden nur eingeblendet, wenn sie zu den zuvor angegebenen Tatsachen passen. Rolle und Nutzungskontext bilden dabei den ersten Filter; deployerspezifische Deepfake-/Public-Interest-Fragen erscheinen nicht bei rein persönlicher nicht-beruflicher Nutzung oder einer ausschließlich providerseitigen Rolle. So erscheint die Deepfake-Prüfung nur bei KI-beteiligten Bild-, Audio- oder Videoinhalten, die Public-Interest-Prüfung nur bei KI-beteiligtem Text und die redaktionelle Verantwortung nur dann, wenn sie für die mögliche Ausnahme bei Public-Interest-Texten tatsächlich relevant werden kann.
|
|
|
|
`legalContext` kann `categories` (`deepfake`, `publicInterestText`, `artisticCreativeSatiricalFictional`, `otherVoluntary`) sowie `actorRole`, `useContext`, `outputDate`, `deepfakeAssessment`, `publicInterestAssessment`, `creativeWorkAssessment` und `lawEnforcementAuthorization` dokumentieren. Die inhaltlichen Prüfungen verwenden bewusst `yes` / `no` / `unsure`, damit „nicht angeklickt“ nicht mit „nein“ verwechselt wird. Die Angaben sind eine vorsichtige Selbsteinordnung und keine automatische Rechtsentscheidung. Der Generator berücksichtigt insbesondere Provider-/Deployer-Rolle, rein persönliche nicht-berufliche Nutzung, den Anwendungsbeginn am 2. August 2026, die besondere Strafverfolgungs-Ausnahme in Art. 50 Abs. 4 sowie bei Public-Interest-Texten die Kombination aus substantieller menschlicher Prüfung/redaktioneller Kontrolle und ausdrücklich benannter redaktioneller Verantwortung.
|
|
|
|
Autor/Byline (`author`) und redaktionelle Verantwortung (`editorialResponsibility`) sind getrennte Metadaten. Eine freiwillige Beschwerde-/Rückmeldestelle (`complaintsContact`) kann als Best Practice angegeben werden, wird aber ausdrücklich nicht als allgemeine Pflicht aus Art. 50 dargestellt. Der Generator zeigt außerdem Plausibilitäts- und Rechtshinweise sowie die möglichen Folgen einer Kennzeichnungspflicht; Details stehen in [`docs/EU-AI-ACT-COMPLIANCE.md`](docs/EU-AI-ACT-COMPLIANCE.md).
|