Zum Inhalt springen

Klokk Anchor

Klokk Anchor ist ein Begleitdienst, der täglich einen Nachweis Ihrer Zeiterfassungsdaten in die **IOTA-Rebased-(Starfish-)**Blockchain schreibt; nachträgliche Änderungen an den Daten werden damit erkennbar. Jedes Ereignis wird auf ein einseitiges SHA-256-Commitment reduziert und in einem Merkle-Baum zusammengefasst; nur die tägliche Merkle-Wurzel wird verankert, sodass keine personenbezogenen Daten in Richtung Chain gelangen. Optional wird ein vertrauenswürdiger Zeitstempel nach RFC 3161 ergänzt.

Voraussetzungen: ein laufendes Klokk mit EXTENSIONS_ENABLED=true; ein Klokk-API-Schlüssel mit den Scopes read:time_entries und read:companies; sowie zwei 32-Byte-Hex-Geheimnisse (eines für die Verschlüsselung im Ruhezustand, eines für das Hashing der Firmen-Token). Für das Mainnet eine finanzierte IOTA-Wallet (in der Anchor-Oberfläche erstellt); der Anchor-Smart-Contract von Klokk ist als Standard eingebaut.

Image: klokkme/anchor / ghcr.io/klokk-me/anchor (Tags stable, latest). PostgreSQL wird über DATABASE_URL unterstützt.

docker-compose.yml
services:
klokk-anchor:
image: klokkme/anchor:stable
restart: unless-stopped
ports:
- "127.0.0.1:9090:9090"
volumes:
- anchor-data:/app/data
environment:
ACCEPT_TERMS: "true" # Zustimmung zu den Nutzungsbedingungen: https://klokk.me/de/terms
KLOKK_BASE_URL: "https://klokk.example.com"
KLOKK_API_KEY: "klokk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
DATABASE_URL: "sqlite:/app/data/klokk-anchor.db"
ENCRYPTION_KEY: "change-me-openssl-rand-hex-32"
COMPANY_TOKEN_PEPPER: "change-me-openssl-rand-hex-32"
IOTA_NETWORK: "mainnet"
TZ: "Europe/Berlin"
TIMEZONE: "Europe/Berlin"
volumes:
anchor-data:
docker-compose.yml
services:
klokk-anchor:
image: klokkme/anchor:stable
restart: unless-stopped
read_only: true
tmpfs:
- /tmp
cap_drop: [ALL]
security_opt:
- no-new-privileges:true
pids_limit: 200
ports:
- "127.0.0.1:9090:9090"
volumes:
- anchor-data:/app/data
environment:
ACCEPT_TERMS: "true" # Zustimmung zu den Nutzungsbedingungen: https://klokk.me/de/terms
KLOKK_BASE_URL: "https://klokk.example.com"
KLOKK_API_KEY: "klokk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
DATABASE_URL: "sqlite:/app/data/klokk-anchor.db"
ENCRYPTION_KEY: "change-me-openssl-rand-hex-32"
COMPANY_TOKEN_PEPPER: "change-me-openssl-rand-hex-32"
IOTA_NETWORK: "mainnet"
TZ: "Europe/Berlin"
TIMEZONE: "Europe/Berlin"
volumes:
anchor-data:

Zuerst die Geheimnisse erzeugen: openssl rand -hex 32 zweimal ausführen – für ENCRYPTION_KEY und für COMPANY_TOKEN_PEPPER. Wird ENCRYPTION_KEY nach dem Anlegen von Wallets geändert, sind diese dauerhaft unlesbar. Jede Variable kann auch aus einer Datei kommen (Docker-Secrets): <NAME>_FILE, z. B. ENCRYPTION_KEY_FILE.

Variable Standard Beschreibung
ACCEPT_TERMS Erforderlich — Mit true den Nutzungsbedingungen zustimmen. Ohne die Variable protokolliert Klokk Anchor den Link und beendet sich.
KLOKK_BASE_URL Erforderlich — Basis-URL Ihrer Klokk-Instanz.
KLOKK_API_KEY Erforderlich — Erweiterungs-API-Schlüssel mit read:time_entries + read:companies. Ein firmengebundener Schlüssel beschränkt den Anchor auf diese Firma. Geheim halten.
DATABASE_URL sqlite:data/klokk-anchor.db SQLite-Pfad (sqlite:…) oder PostgreSQL-DSN (postgresql://…).
ENCRYPTION_KEY Erforderlich — 64-stelliger Hex-Wert (32 Byte). AES-256-GCM-Schlüssel für gespeicherte privaten Wallet-Schlüssel. openssl rand -hex 32.
COMPANY_TOKEN_PEPPER Erforderlich — Geheimnis, das vor dem SHA-256-Hashing in die Firmen-Token eingemischt wird, sodass Firmen-IDs nicht aus On-Chain-Werten rückrechenbar sind.
IOTA_NETWORK mainnet mainnet, testnet oder localnet. IOTA_ANCHOR_PACKAGE verwendet standardmäßig das von Klokk bereitgestellte Package des gewählten Netzes.
TIMEZONE / DAILY_BOOKING_TIME UTC / 00:00 IANA-Zeitzone und feste tägliche Buchungszeit (HH:MM) zum Verankern des Vortags.
ANCHOR_EMPTY_DAYS true Auch an Tagen ohne Einträge einen Nachweis verankern (positiver Beleg „niemand hat gearbeitet”). Eine Transaktion pro Firma und leerem Tag.
TSA_URL https://freetsa.org/tsr RFC-3161-Zeitstempelstelle; an sie geht nur die tägliche Merkle-Wurzel. Das voreingestellte FreeTSA ist kein qualifizierter eIDAS-Dienst – dafür einen qualifizierten QTSP eintragen. Leer (TSA_URL=) schaltet die Zeitstempel ab. Best-Effort; blockiert das Verankern nie.
LEDGER_URLS — Kommagetrennte Klokk Ledger-URLs, um Nachweise bei der Verifizierung gegenzuprüfen — eine betreiberunabhängige vierte Prüfung.
ERROR_REPORTS — Legt fest, ob diese Installation anonymisierte Fehlerberichte an das Klokk-Team sendet. Nicht gesetzt: Superadmins entscheiden unter Fehlerprotokoll (aus, bis sie es einschalten). true: immer an. false: aus, und auch Fehler melden und Wunsch äußern sind abgeschaltet. Was gesendet wird: siehe Datenschutzerklärung.
ERROR_REPORTS_URL https://radar.klokk.me Klokk Radar: Ziel der Fehlerberichte, Fehlermeldungen und Wünsche und Quelle der neuesten Version für den Update-Hinweis.
UPDATE_CHECK true Liest zweimal täglich die neueste Klokk-Anchor-Version aus der öffentlichen Release-Liste von Klokk Radar und zeigt einen Update-Hinweis. false schaltet das ab.
ADMIN_PORT 9090 Port für die Web-Oberfläche und die REST-API (für Remote-Zugriff hinter einen Reverse-Proxy legen).

Klokk Anchor benachrichtigt per ntfy, Webhook oder E-Mail, wenn eine Verankerung fehlschlägt, ein übermittelter Nachweis nicht bestätigt wird (oder seine Wurzel auf der Kette nicht übereinstimmt), Klokk bei einer Buchung nicht gelesen werden kann oder ein Wallet-Guthaben unter WALLET_LOW_BALANCE_MIST fällt. Gleichartige Probleme werden zu einer Nachricht zusammengefasst (höchstens eine alle 15 Minuten), damit ein Nachholen über viele Tage nicht zur Nachrichtenflut wird. Superadmins können im Dashboard eine Testnachricht senden oder im Container klokk-anchor --test-notification ausführen.

Variable Standard Beschreibung
NOTIFY_NTFY_URL — ntfy-Topic-URL, z. B. https://ntfy.sh/mein-anchor oder ein eigener Server.
NOTIFY_NTFY_TOKEN — ntfy-Zugriffstoken für geschützte Topics.
NOTIFY_NTFY_USER / _PASSWORD — Alternativ: ntfy-Benutzer und -Passwort.
NOTIFY_WEBHOOK_URL — Erhält dieselben Benachrichtigungen als JSON-POST (event, title, message, priority, count, url).
NOTIFY_WEBHOOK_SECRET — Signiert den Webhook-Inhalt: Header X-Klokk-Anchor-Signature: sha256=<hex HMAC-SHA256>.
NOTIFY_SMTP_HOST — Mailserver; schaltet Benachrichtigungen per E-Mail ein.
NOTIFY_SMTP_FROM — Absender, z. B. klokk-anchor <[email protected]> (für E-Mail erforderlich).
NOTIFY_SMTP_TO — Empfänger, durch Kommas getrennt (für E-Mail erforderlich).
NOTIFY_SMTP_USER / _PASSWORD — Anmeldung am Mailserver; nur über eine verschlüsselte Verbindung.
NOTIFY_SMTP_SECURITY starttls starttls (Port 587), tls (465) oder none (25, nur für ein Relay im lokalen Netz, ohne Anmeldung).
NOTIFY_SMTP_PORT — Überschreibt den Port, der sich aus NOTIFY_SMTP_SECURITY ergibt.
NOTIFY_EVENTS alle Kommagetrennte Auswahl aus anchor_failed, proof_failed, klokk_unreachable, wallet_low_balance.
NOTIFY_LANGUAGE en Sprache der Nachrichten: en oder de.
NOTIFY_NAME klokk-anchor Präfix jedes Titels, um mehrere Instanzen zu unterscheiden.
WALLET_LOW_BALANCE_MIST 100000000 Schwelle für niedriges Guthaben in MIST (1 IOTA = 10⁹ MIST); eine Nachricht je Unterschreitung.
PUBLIC_BASE_URL — Adresse der Oberfläche, wie der Browser sie aufruft, z. B. https://anchor.example.com. Passkeys gelten für diese Adresse (Relying-Party-ID und Origin, abweichend setzbar mit WEBAUTHN_RPID und WEBAUTHN_ORIGIN); ohne sie lassen sich Passkeys nur unter localhost anlegen. Benachrichtigungen verlinken auf diese Adresse.