Files
jbergner 6e152a5121
Some checks failed
release-tag / release-image (push) Failing after 1m38s
2.0.2 Update und Anpassungen
2026-07-24 10:08:19 +02:00

400 lines
14 KiB
Markdown

# AI Disclosure Standard 2.0.2
Ein mehrsprachiger, selbst hostbarer Go-Dienst für sichtbare und maschinenlesbare Erklärungen zur KI-Nutzung in Artikeln, Webseiten und einzelnen Inhaltsbestandteilen.
Die Community-Basis bleibt offen und ohne Plattformzwang nutzbar. Für professionelle Betreiber stehen zusätzlich lizenzierbare Laufzeitfunktionen wie eigene Darstellung, Bulk-Verarbeitung, Export-Bundles und White-Label-Betrieb zur Verfügung. Lizenzen werden ausschließlich durch die separat betriebene **Universal License Platform** ausgestellt.
## Funktionsumfang
### Offener Kern
- Einzeldeklarationen und zusammengefasste Artikel-/Webseiten-Deklarationen;
- Text, Titelbild, weitere Bilder, Recherche, Übersetzung, Audio, Video und Code getrennt erfassbar;
- SVG-Badges, HTML-Erklärung und JSON-LD aus derselben Deklaration;
- automatisch erzeugte Fließtext-Zusammenfassung und sauber gerasterte Tabellenansicht;
- Nachweisgrundlagen `selfDeclared`, `technicallyRecorded`, `signed` und `verified`;
- Deutsch, Englisch, Französisch, Spanisch, Italienisch, Niederländisch, Portugiesisch und Polnisch;
- Sprachumschalter direkt auf der Ergebnis-Seite;
- mehrsprachige Hintergrundseite zu Artikel 50 des EU AI Act;
- technisches, **nicht bindendes** Article-50-Decision-Support-Modell;
- strukturierte Erfassung von Deepfake-Kontext, Texten zu Angelegenheiten von öffentlichem Interesse, substanzieller menschlicher Prüfung, redaktioneller Verantwortung, Erstexposition und Barrierefreiheit;
- Validator, JSON-Schema und OpenAPI 3.1;
- Health-, Readiness- und Prometheus-Endpunkte;
- Docker, Docker Compose, Docker Swarm und Kubernetes;
- SBOM, Build-Provenance und keyless signierte offizielle Container-Images in der mitgelieferten CI-Pipeline.
### Lizenzierbare Betriebsfunktionen
Die offizielle Distribution kennt folgende Capability-IDs:
```text
custom_text
custom_badge
white_label
bulk_api
export_bundle
```
Zusätzlich kann die Lizenzplattform numerische Limits liefern, beispielsweise:
```text
bulk_items=500
```
Die offene Standardfunktionalität hängt nicht von einer Lizenz ab. Ein Betreiber kann für offizielle kommerzielle Deployments mit `REQUIRE_LICENSE=true` festlegen, dass die Instanz ohne gültige Runtime-Lizenz nicht betriebsbereit ist und keine fachlichen Endpunkte bedient.
## Artikel-50-Unterstützung
Der Generator kann ergänzend zur eigentlichen KI-Nutzung Tatsachen erfassen, die für Artikel 50 relevant sein können:
- Deepfake bzw. realitätsähnlich erzeugter/manipulierter Inhalt;
- Text zur Information der Öffentlichkeit über eine Angelegenheit von öffentlichem Interesse;
- offensichtlich künstlerischer, kreativer, satirischer oder fiktionaler Kontext;
- substanzielle menschliche Prüfung bzw. redaktionelle Kontrolle;
- bestätigte redaktionelle Verantwortung;
- Offenlegung spätestens bei der ersten Exposition;
- Berücksichtigung anwendbarer Barrierefreiheitsanforderungen.
Daraus erzeugt die Anwendung eine konservative technische Einordnung unter:
```text
GET /v1/article50-assessment.json
```
Diese Einordnung ist ausdrücklich **keine Rechtsberatung und keine automatische Konformitätsentscheidung**. Die Rohdaten bleiben Teil der Deklaration und können unabhängig von der Bewertung weiterverarbeitet werden.
Weitere Details: [`docs/ARTICLE-50-DECISION-SUPPORT.md`](docs/ARTICLE-50-DECISION-SUPPORT.md)
## Schnellstart
Unter Windows:
```powershell
go run .\cmd\server
```
Danach:
```text
Generator: http://localhost:8080/
Produktseite: http://localhost:8080/product
Hintergrund: http://localhost:8080/background
Capabilities: http://localhost:8080/v1/capabilities
Health: http://localhost:8080/healthz
Readiness: http://localhost:8080/readyz
```
Go lädt `.env` beim direkten Start nicht automatisch. Docker Compose kann sie explizit verwenden:
```powershell
Copy-Item .env.example .env
docker compose --env-file .env up -d --build
```
## Betriebsmodi
`SERVICE_MODE` trennt öffentliche Oberfläche und Server-to-Server-Betrieb:
| Modus | Zweck |
|---|---|
| `full` | Generator, Produkt-/Hintergrundseiten, Deklarationen und APIs |
| `api` | Deklarations-, Badge- und Maschinen-APIs ohne öffentliche Generator-/Produktseite |
| `bulk` | eigenständiger Bulk Workspace plus Bulk-/Validierungs-/Betriebs-APIs |
Der dedizierte Bulk-Container setzt bereits:
```text
SERVICE_MODE=bulk
REQUIRE_LICENSE=true
BULK_REQUIRE_API_KEY=true
API_ALLOWED_ORIGIN=
```
## Professioneller Bulk-Betrieb
Der Bulk-Container enthält wieder die vollständige browserbasierte **Bulk Workspace**-Oberfläche. Sie ist unter `/` und `/bulk` erreichbar und ergänzt die API, statt sie zu ersetzen. API-Keys werden im Browser nur im `sessionStorage` des aktuellen Tabs gehalten.
Build:
```bash
docker build -f Dockerfile.bulk -t ai-disclosure-standard-bulk:2.0.2 .
```
Die Oberfläche ist nach dem Start erreichbar unter:
```text
http://localhost:8080/
http://localhost:8080/bulk
```
Der programmatische Bulk-Endpunkt lautet:
```text
POST /v1/bulk/declarations
```
Er benötigt in der offiziellen Bulk-Distribution:
1. eine gültige Lizenz mit Capability `bulk_api`;
2. optional ein Lizenzlimit `bulk_items`;
3. einen serverseitigen API-Schlüssel.
Authentifizierung:
```http
Authorization: Bearer <bulk-api-key>
```
oder:
```http
X-API-Key: <bulk-api-key>
```
Beispiel:
```json
{
"items": [
{
"id": "article-42",
"parameters": {
"mode": "article",
"lang": "de",
"textExtent": "partial",
"textReview": "expert",
"publicInterestText": "true",
"substantialHumanReview": "true",
"editorialResponsibilityConfirmed": "true"
}
}
]
}
```
Grenzen:
```env
BULK_MAX_ITEMS=500
BULK_MAX_BODY_BYTES=4194304
BULK_REQUIRE_API_KEY=true
BULK_API_KEY_FILE=/run/secrets/bulk/key
```
Ist `LICENSE_TOKEN_FILE` bzw. `BULK_API_KEY_FILE` gesetzt, ist die angegebene Datei **autoritativ** und hat Vorrang vor einem eventuell gleichzeitig vorhandenen `LICENSE_TOKEN` bzw. `BULK_API_KEY` aus `.env`. Dadurch können veraltete Environment-Werte Docker-/Kubernetes-Secrets nicht unbemerkt überschreiben.
Siehe [`docs/BULK-API.md`](docs/BULK-API.md) und [`docs/BULK-WORKSPACE.md`](docs/BULK-WORKSPACE.md).
## Supply-Chain-Sicherheit
Die CI-Pipeline erzeugt SBOM/Provenance und signiert veröffentlichte Full- und Bulk-Container keyless mit Sigstore/Cosign über GitHub OIDC. Für produktive Deployments sollte nach Digest ausgerollt und die Signatur verifiziert werden. Details: [`docs/SUPPLY-CHAIN.md`](docs/SUPPLY-CHAIN.md).
## Export-Bundle
Mit der Capability `export_bundle` steht zur Verfügung:
```text
GET /v1/declaration.bundle.json
```
Das Bundle enthält:
- Deklaration;
- Article-50-Assessment;
- kanonische URLs;
- Erzeugungszeitpunkt des Bundles;
- einen SHA-256-Digest der serialisierten Deklaration.
Der Digest ist ein Integritätsmerkmal, **keine digitale Signatur**.
## Lizenzprüfung
Dieses Repository stellt keine Lizenzen aus und enthält keine privaten Lizenzschlüssel, Keygen-Funktionen, Lizenzverwaltung oder Admin-Oberfläche. Diese Aufgaben liegen ausschließlich in der eigenständigen Universal License Platform.
Produkt-ID:
```text
ai-disclosure-standard
```
Der Produktserver enthält nur den Runtime-Client. Typische Konfiguration:
```env
LICENSE_TOKEN=...
LICENSE_MODE=hybrid
LICENSE_SERVER_URL=https://licenses.example.org
LICENSE_INSTANCE_ID=publisher-01
LICENSE_CACHE_FILE=/data/license-lease.json
```
Alternativ können Secrets über Dateien eingebunden werden:
```env
LICENSE_TOKEN_FILE=/run/secrets/license/token
```
### Vertrauensschlüssel
Die öffentlichen Issuer- und Lease-Schlüssel werden vor dem Build in
```text
internal/app/trusted_keys.json
```
eingebettet. Es gibt absichtlich keinen zur Laufzeit austauschbaren `LICENSE_PUBLIC_KEY`.
Beispiel:
```powershell
Invoke-WebRequest `
"https://licenses.example.org/api/v1/trust-store" `
-OutFile ".\internal\app\trusted_keys.json"
go build .\cmd\server
```
Die Laufzeitprüfung unterstützt Offline-, Hybrid- und Online-Modus. Hybrid nutzt einen signierten Lease-Cache und eignet sich für hochverfügbare Installationen, die kurze Ausfälle des Lizenzdienstes tolerieren sollen.
Siehe [`docs/LICENSE-INTEGRATION.md`](docs/LICENSE-INTEGRATION.md).
## Produktionsdeployment mit Docker Compose
Für den offenen Einzelserver:
```bash
docker compose up -d --build
```
Für ein Beispiel mit Runtime-Secrets und separatem Bulk-Dienst:
```bash
mkdir -p secrets
printf '%s' '<LICENSE_TOKEN>' > secrets/license_token.txt
printf '%s' '<LONG_RANDOM_API_KEY>' > secrets/bulk_api_key.txt
BASE_URL=https://ai.example.org \
LICENSE_SERVER_URL=https://licenses.example.org \
docker compose -f compose.commercial.yaml up -d --build
```
Der Bulk-Dienst nutzt `OUTPUT_BASE_URL`, damit seine Resultate auf die öffentliche Full-/API-Instanz verweisen können. Die Bulk-Instanz liefert selbst den Bulk Workspace, aber bewusst keine öffentlichen Deklarationsseiten aus. Der Bulk-Port ist in diesem Beispiel nur an `127.0.0.1:8081` gebunden. In einer echten Produktionsumgebung sollte der Bulk-Service intern bleiben oder hinter einem authentifizierenden API-Gateway betrieben werden.
## Kubernetes
Öffentliche Anwendung:
```bash
kubectl apply -f deploy/kubernetes.yaml
```
Optionales Lizenz-Secret:
```bash
kubectl create secret generic ai-disclosure-license \
--from-literal=token='<LICENSE_TOKEN>'
```
Lizenzierter interner Bulk-Dienst:
```bash
kubectl create secret generic ai-disclosure-commercial \
--from-literal=license-token='<LICENSE_TOKEN>' \
--from-literal=bulk-api-key='<LONG_RANDOM_API_KEY>'
kubectl apply -f deploy/kubernetes-bulk.yaml
```
Das Bulk-Manifest enthält absichtlich **keinen Ingress**.
Siehe [`docs/COMMERCIAL-DEPLOYMENT.md`](docs/COMMERCIAL-DEPLOYMENT.md).
## Konfiguration
Die Datei [`.env.example`](.env.example) ist ab Version 2.0.2 die **vollständige Referenz** aller vom offiziellen Server unterstützten Runtime-Variablen. Ein Regressionstest stellt sicher, dass die dokumentierten Kernvariablen nicht versehentlich aus der Beispieldatei verschwinden.
Neu bzw. explizit dokumentiert sind insbesondere:
- vertrauenswürdige Proxy-Netze über `TRUSTED_PROXY_CIDRS`;
- datensparsame Request-Logs über `LOG_CLIENT_IP=false`;
- optionales HSTS über `ENABLE_HSTS`;
- standardmäßig deaktivierte und per Bearer-Token geschützte Prometheus-Metriken;
- `_FILE`-Varianten für Lizenz-, Bulk- und Metrics-Secrets;
- vollständige Betreiber-, Datenschutz- und Barrierefreiheitsdaten für `/legal`, `/privacy` und `/accessibility`;
- `LEGAL_STRICT` als Fail-Fast-Prüfung gegen leere Produktions-Platzhalter.
`SALES_URL` und die früheren `PRICE_*`-Variablen sind bewusst **nicht** mehr unterstützt: Preisübersicht und Pro-Werbung wurden aus der öffentlichen Anwendung entfernt. Tote Konfigurationsparameter werden nicht weitergeführt.
Eine kommentierte Beschreibung aller Variablen steht zusätzlich in [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md).
## Wichtige API-Endpunkte
```text
GET /badge/{preset}.svg
GET /v1/badge.svg
GET /declaration
GET /v1/declaration.json
GET /v1/article50-assessment.json
GET /v1/declaration.bundle.json # licensed: export_bundle
POST /v1/bulk/declarations # licensed: bulk_api
POST /v1/validate
GET /v1/capabilities
GET /healthz
GET /readyz
GET /metrics # optional, Bearer-geschützt
GET /legal # UI modes
GET /privacy # UI modes
GET /accessibility # UI modes
```
## Sicherheit
- minimales Scratch-Runtime-Image;
- non-root UID/GID `65532`;
- read-only root filesystem in den mitgelieferten Deployments;
- alle Linux-Capabilities entfernt;
- `no-new-privileges`;
- Kubernetes `RuntimeDefault` seccomp;
- keine ServiceAccount-Tokens in Kubernetes-Pods;
- Lizenz- und Bulk-Secrets können als Dateien gemountet werden;
- CSP, `X-Content-Type-Options`, `X-Frame-Options`, Referrer- und Permissions-Policy;
- konfigurierbares CORS;
- Proxy-Header werden nur von explizit vertrauenswürdigen CIDR-Netzen akzeptiert;
- Client-IP-Logging ist standardmäßig deaktiviert;
- optionales HSTS für HTTPS-only Deployments;
- Prometheus ist standardmäßig deaktiviert und bei Aktivierung Bearer-geschützt;
- Request-IDs und strukturierte JSON-Logs;
- Body- und Itemlimits für die Bulk-API;
- optionale API-Key-Authentifizierung des Bulk-Endpunkts;
- Lizenzstatus wird bei `REQUIRE_LICENSE=true` nicht nur in Readiness, sondern auch im Request-Pfad durchgesetzt.
## Open Source und kommerzieller Betrieb
Der aktuelle Quellstand trägt die mitgelieferte MIT-Lizenz. Damit eignet er sich als offene Referenzimplementierung und ist frei integrierbar. Die Runtime-Capabilities sind eine technische Produktgrenze der offiziellen Distribution und der Universal License Platform.
Für ein Geschäftsmodell, das **zusätzlich** urheberrechtlich zwischen Community- und kommerzieller Distribution unterscheiden soll, sollte vor Veröffentlichung bewusst eine Dual-Licensing- bzw. Open-Core-Strategie festgelegt werden. Die vorhandene MIT-Lizenz selbst räumt weitgehende Nutzungs-, Änderungs- und Weitergaberechte ein. Siehe [`docs/LICENSING-STRATEGY.md`](docs/LICENSING-STRATEGY.md).
## Entwicklung und Qualitätssicherung
```bash
make check
```
entspricht im Wesentlichen:
```bash
gofmt
go vet ./...
go test -race ./...
cd third_party/license-platform-client
go vet ./...
go test -race ./...
```
Container:
```bash
make docker-build-all
```
Die CI baut und veröffentlicht bei Pushes auf `main` sowohl das normale als auch das dedizierte Bulk-Image für `linux/amd64` und `linux/arm64` und fordert SBOM/Provenance-Ausgabe von BuildKit an.