400 lines
14 KiB
Markdown
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.
|