Skip to content

パスワード管理

PotatoでのPBKDF2-SHA256によるパスワードハッシュ化、管理者向けCLI/APIによるリセット、トークンを使ったセルフサービスのリセット手順、SQLiteまたはPostgreSQLでの認証情報の保存方法を解説します。

v2.4.0の新機能

Potatoの認証はPBKDF2-SHA256を100,000回反復し、ユーザーごとに個別のソルトを使います。これはNISTがパスワードの安全な保存方法として推奨しているものと同じ方式です。このページでは、パスワードがどう保存されるか、リセットの方法、そしてサーバーを再起動しても認証情報を保持する方法を扱います。

セキュリティの実装

パスワードはsalt$hashという形式で保存されます。

  • 32文字の16進ソルト(ユーザーごとに固有)
  • salt + passwordの64文字のSHA-256ハッシュ
  • タイミング攻撃を防ぐためのhmac.compare_digestによる定数時間比較

user_config.jsonlファイルに平文のパスワードが残っている場合、Potatoが読み込む際に固有のソルトで自動的に再ハッシュされます。手動での移行作業は不要です。

デフォルトの設定

デフォルトでは、Potatoはインメモリ認証を使います。アノテーターは設定ファイルに記載しておく必要があります。

yaml
authentication:
  method: in_memory
  require_password: true
 
user_config:
  users:
    - username: "annotator1"
      password: "initial-password"   # will be hashed on first load
    - username: "annotator2"
      password: "initial-password"

認証情報の永続化

インメモリの認証情報は再起動で失われます。永続的に保存するには、ファイルまたはデータベースのバックエンドを使ってください。

ファイルによる永続化

yaml
authentication:
  method: in_memory
  user_config_path: /shared/path/to/user_config.jsonl

Potatoはハッシュ化した認証情報をこのファイルに書き出し、再起動時に読み戻します。セッション中に設定・変更したパスワードは再起動後も残ります。

データベースバックエンド

SQLite(追加の依存パッケージは不要):

yaml
authentication:
  method: database
  database_url: "sqlite:///auth/users.db"

PostgreSQLpsycopg2-binaryが必要):

yaml
authentication:
  method: database
  database_url: "postgresql://user:password@localhost:5432/potato_auth"

データベースのテーブルは初回起動時に自動で作成されます。

注意: method: databaseuser_config_pathは同時に使えません。どちらか一方の永続化方式を選んでください。

パスワードのリセット

管理者用CLI

コマンドラインからパスワードをリセットします。

bash
# Reset a specific user's password
potato reset-password config.yaml --username annotator1
 
# Prompted for new password interactively

管理者用API

APIキーを使ってプログラムからリセットします。

bash
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"}'

トークンによるセルフサービスのリセット

Potatoはユーザー自身が開始するリセット手順にも対応しています。ユーザーは/forgot-passwordにアクセスしてユーザー名を入力すると、1回だけ使えるリセットトークンを受け取ります。/reset/<token>にアクセスして新しいパスワードを設定します。

トークンの有効期間は24時間で、使えるのは1回だけです。Potatoはメールを送信しないため、リセット用リンクの配布は管理者が手動で行います。

設定で有効にする:

yaml
authentication:
  method: database
  database_url: "sqlite:///auth/users.db"
  allow_password_reset: true
  reset_token_ttl_hours: 24

管理者側の手順:

bash
# Generate a reset token for a user
curl -X POST http://localhost:8000/admin/generate_reset_token \
  -H "X-API-Key: $ADMIN_API_KEY" \
  -d '{"username": "annotator1"}'
 
# Returns: {"reset_url": "https://your-server.com/reset/abc123..."}
# Share this URL with the annotator

パスワードなしモード

授業でのデモ、短時間の調査、外部認証(MTurk、Prolific)を使うタスクでは、パスワードを完全に無効にできます。

yaml
authentication:
  method: in_memory
  require_password: false

アノテーターは任意のユーザー名を入力するだけでログインでき、パスワードの入力欄は表示されません。機微なデータを扱う場合や、本人確認が必要なタスクには向きません。

詳しくはパスワードなしログインを参照してください。

設定リファレンス

yaml
authentication:
  method: in_memory       # in_memory | database | oauth | clerk
 
  # In-memory options
  require_password: true
  user_config_path: path/to/users.jsonl   # optional persistence
 
  # Database options (mutually exclusive with user_config_path)
  database_url: "sqlite:///auth/users.db"
 
  # Self-service reset
  allow_password_reset: true
  reset_token_ttl_hours: 24
 
user_config:
  users:
    - username: "researcher"
      password: "secure-passphrase"
      role: admin
    - username: "annotator1"
      password: "initial-pass"
      role: annotator

参考資料

実装の詳細については、ソースドキュメントを参照してください。