# 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 ``` oder: ```http X-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' '' > secrets/license_token.txt printf '%s' '' > 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='' ``` Lizenzierter interner Bulk-Dienst: ```bash kubectl create secret generic ai-disclosure-commercial \ --from-literal=license-token='' \ --from-literal=bulk-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.