Passwortverwaltung
Passwort-Hashing mit PBKDF2-SHA256, Zurücksetzen über Admin-CLI und -API, Rücksetzlinks per Token zur Selbstbedienung sowie Speicherung der Zugangsdaten in SQLite oder PostgreSQL in Potato konfigurieren.
Neu in v2.4.0
Potatos Authentifizierung arbeitet mit PBKDF2-SHA256 und 100.000 Iterationen sowie einem Salt pro Nutzer, also dem Verfahren, das NIST für die sichere Speicherung von Passwörtern empfiehlt. Diese Seite beschreibt, wie Passwörter gespeichert werden, wie sie sich zurücksetzen lassen und wie Zugangsdaten Serverneustarts überdauern.
Sie gilt für die Methoden in_memory und database. Unter OAuth verwaltet der Identitätsanbieter das Passwort, daher trifft nichts davon zu, außer für die lokalen Konten im gemischten Modus.
Umsetzung der Sicherheit
Passwörter werden im Format salt$hash gespeichert:
- 32 Zeichen langer Hex-Salt, pro Nutzer eindeutig
- 64 Zeichen langer Hex-Digest, abgeleitet per PBKDF2-HMAC-SHA256 aus dem Passwort mit diesem Salt und 100.000 Iterationen
- Vergleich in konstanter Zeit über
hmac.compare_digest, um Timing-Angriffe zu verhindern
Ein einzelner SHA-256-Durchlauf über ein gesalzenes Passwort ist schnell genug, um es in großem Maßstab per Brute Force zu knacken. Erst die 100.000 Iterationen machen jeden Rateversuch teuer.
Vorhandene Klartextpasswörter in user_config.json-Dateien werden beim Laden durch Potato automatisch mit eindeutigen Salts neu gehasht, eine manuelle Migration entfällt.
Standardkonfiguration
Standardmäßig authentifiziert Potato im Arbeitsspeicher. require_password ist ein Schlüssel der obersten Ebene und gehört nicht zum Block authentication:
require_password: true
authentication:
method: in_memory
user_config:
users:
- username: "annotator1"
password: "initial-password" # will be hashed on first load
- username: "annotator2"
password: "initial-password"Dauerhafte Zugangsdaten
Konten, die über das Registrierungsformular angelegt werden, schreibt Potato in eine JSONL-Datei und liest sie beim nächsten Start wieder ein. Unter in_memory ist das die Datei user_config.json neben dem Ausgabeverzeichnis, sofern Sie keine andere angeben.
Speicherung in einer Datei
authentication:
method: in_memory
user_config_path: /shared/path/to/user_config.jsonlGeben Sie einen Pfad an, wenn sich mehrere Serverinstanzen eine Nutzerliste teilen oder die Nutzerliste an einem anderen Ort als neben den Annotationen liegen soll. Neue Registrierungen und Passwortänderungen werden sofort geschrieben.
Bewahren Sie die Nutzerliste zusammen mit der Annotationsausgabe auf. Das Verzeichnis eines Annotators trägt seinen Benutzernamen. Fehlt die Nutzerliste, während das Ausgabeverzeichnis noch existiert, würde die nächste Person, die diesen Benutzernamen eingibt, die Arbeit eines anderen übernehmen. Potato lehnt die Registrierung deshalb ab, und der Annotator kommt erst wieder hinein, wenn Sie die Datei wiederhergestellt haben.
Vor v2.8.3 schrieb in_memory nichts, solange user_config_path nicht ausdrücklich gesetzt war, sodass Konten einen Neustart nicht überstanden. Wenn Sie eine Studie mit einer älteren Version durchgeführt haben, sind diese Konten verloren, die Annotationen aber nicht.
Datenbank als Backend
SQLite (ohne zusätzliche Abhängigkeiten):
authentication:
method: database
database_url: "sqlite:///auth/users.db"PostgreSQL (setzt psycopg2-binary voraus):
authentication:
method: database
database_url: "postgresql://user:password@localhost:5432/potato_auth"Potato legt die Tabelle users beim ersten Start an und betreibt SQLite im WAL-Modus, damit gleichzeitige Lesezugriffe besser laufen. database_url muss mit sqlite:/// oder postgresql:// beginnen. Sie können auch POTATO_DB_CONNECTION in der Umgebung setzen; sind beide vorhanden, hat database_url Vorrang.
Hinweis: method: database und user_config_path schließen sich gegenseitig aus, wählen Sie eine der beiden Speicherstrategien. Potato meldet einen Fehler, wenn beide konfiguriert sind.
Passwörter zurücksetzen
Admin-CLI
Ein Passwort auf der Kommandozeile zurücksetzen:
# Prompts for username and password
potato reset-password config.yaml
# Prompts for the password only
potato reset-password config.yaml --username annotator1Admin-API
Programmatisch mit dem Admin-API-Key zurücksetzen:
curl -X POST http://localhost:8000/admin/reset_password \
-H "X-API-Key: $ADMIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"username": "annotator1", "new_password": "new-secure-password"}'Der Key stammt, in dieser Reihenfolge, aus der Einstellung admin_api_key auf oberster Ebene, aus der Umgebungsvariablen POTATO_ADMIN_API_KEY oder aus einer generierten Datei admin_api_key.txt im Aufgabenverzeichnis.
Selbstbedienung per Token
Annotatoren, die ihr Passwort vergessen haben, können es selbst zurücksetzen. Sie rufen /forgot-password auf und geben ihren Benutzernamen ein, und Potato erzeugt ein einmalig verwendbares Token, das 24 Stunden gültig ist. Der Rücksetzlink wird auf dem Bildschirm angezeigt, damit ein Administrator ihn weitergeben kann; Potato verschickt keine E-Mails. Der Annotator öffnet /reset/<token> und setzt ein neues Passwort, womit das Token verbraucht ist.
Dieser Ablauf braucht keine Konfiguration. Ist require_password: true gesetzt, erscheint auf der Anmeldeseite ein Link "Forgot Password?".
Administratoren können ein Token auch direkt erzeugen:
curl -X POST http://localhost:8000/admin/create_reset_token \
-H "X-API-Key: $ADMIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"username": "annotator1"}'
# {"reset_link": "http://localhost:8000/reset/abc123...",
# "token": "abc123...", "expires_in_hours": 24}Übergeben Sie "ttl_hours": 48 im Request-Body, um eine andere Gültigkeitsdauer festzulegen.
Betrieb ohne Passwörter
Für Vorführungen im Unterricht, kurze Studien oder Aufgaben mit externer Authentifizierung (MTurk, Prolific) lassen sich Passwörter ganz abschalten:
require_password: false
authentication:
method: in_memoryAnnotatoren melden sich mit einem beliebigen Benutzernamen an, eine Passwortabfrage erscheint nicht. Für sensible Daten oder Aufgaben mit geprüfter Identität ist das nicht zu empfehlen.
Einzelheiten stehen unter Passwortloser Login.
Vollständige Referenz
# Top-level: require a password at login (default: true)
require_password: true
# Top-level: key for the admin endpoints
admin_api_key: ${POTATO_ADMIN_API_KEY}
authentication:
# in_memory (default) | database | clerk | oauth
method: in_memory
# in_memory only, mutually exclusive with method: database
user_config_path: users.jsonl
# database only; sqlite:/// or postgresql://
# database_url: "sqlite:///auth.db"
user_config:
users:
- username: "researcher"
password: "secure-passphrase"
- username: "annotator1"
password: "initial-pass"| Endpunkt | Methode | Auth | Beschreibung |
|---|---|---|---|
/forgot-password | GET, POST | keine | Ein Rücksetz-Token anfordern |
/reset/<token> | GET, POST | keine | Ein neues Passwort setzen |
/admin/reset_password | POST | API-Key | Passwort durch den Administrator zurücksetzen |
/admin/create_reset_token | POST | API-Key | Ein Rücksetz-Token erzeugen |
Weiterführende Informationen
- SSO & OAuth-Authentifizierung: Anmeldung über Google, GitHub oder institutionelles SSO
- Passwortloser Login: Zugang nur über den Benutzernamen für offene Aufgaben
- Produktionseinrichtung: HTTPS und Konfiguration des Reverse Proxy
- Admin-Dashboard: Annotatorenkonten verwalten
Implementierungsdetails stehen in der Quelldokumentation.