認証を実装

認証はすべてのプロジェクトが必要とする機能であり、不注意に実装するとセキュリティインシデントを最も引き起こしやすい機能でもあります。アウトソーシングプロジェクトでは、認証はしばしばクライアントが最初に評価する成果物であり、6ヶ月後に何か問題が起きたときに責任を問われる機能でもあります。Sun Agent Kitは完全な認証スタック — 登録、ログイン、メール確認、パスワードリセット、OAuthプロバイダー、オプションの2FA — をOWASP標準に準拠した上でテスト付きで、わずかな時間で実装します。

概要

目標: ゼロから完全で本番対応のセキュアな認証システムを実装する、または既存のものを拡張する
所要時間: 20〜40分(手動では4〜8時間)
使用エージェント: plannerimplementertesterreviewer
コマンド: /sk:plan/sk:cook/sk:test/sk:code-review

前提条件

  • Sun Agent Kitがインストール済みで、動作するプロジェクトスキャフォールドがあること
  • データベースマイグレーションツールが設定済みであること(Prisma、Drizzle、または生SQL — どれかを指定)
  • 開発環境でメール送信インフラが利用可能またはモック済みであること(SendGrid、Resend、nodemailer)
  • 環境変数が設定済みであること: JWT_SECRETREFRESH_TOKEN_SECRETDATABASE_URL
  • この納品に含まれる認証機能の明確なリスト

ステップバイステップのワークフロー

ステップ1:認証システムを計画する

/sk:plan "implement full authentication system: email/password registration with email verification, JWT access tokens (15min TTL) + refresh tokens (7 days), password reset via email, Google OAuth, optional TOTP 2FA. Stack: Node.js/Express, PostgreSQL, Prisma."

処理内容: エージェントが以下を実行します:

  1. 既存の認証関連コード、モデル、ミドルウェアのコードベースを分析
  2. トークンストレージ戦略、メール確認フロー、OAuth統合アプローチを設計
  3. レビュー用にセキュリティノートをフラグした段階的な実装計画を plans/ に保存

ステップ2:コア認証を実装する(登録、ログイン、JWT)

/sk:cook "implement Step 1 from plans/phase-auth-system.md: user registration, login, JWT access token + refresh token pair, token refresh endpoint, and logout with refresh token revocation"

処理内容: エージェントが以下を実行します:

  1. リフレッシュトークンテーブルを含むデータベーススキーマを更新してマイグレーションを適用
  2. 登録、ログイン、トークンリフレッシュ、ログアウト操作を含むauthサービスを実装
  3. 適切なステータスコードを持つすべてのコアauthエンドポイントのルートハンドラーを作成
  4. アクセストークンを検証してユーザーをリクエストにアタッチするauthミドルウェアを追加

ステップ3:メール確認とパスワードリセットを追加する

/sk:cook "implement Step 2 from plans/phase-auth-system.md: email verification on registration, resend verification endpoint, password reset request + confirmation with time-limited signed tokens"

処理内容: エージェントが以下を実行します:

  1. 有効期限と単一使用トラッキングを含む確認・パスワードリセットトークンテーブルを追加
  2. HTMLとプレーンテキストのフォールバックを含むメールテンプレートを作成
  3. verify-email、resend-verification、forgot-password、reset-passwordのルートハンドラーを実装

ステップ4:Google OAuthを追加する

/sk:cook "implement Step 3 from plans/phase-auth-system.md: Google OAuth 2.0 login and registration using Passport.js, handle both new users (create account) and existing users (link or login)"

処理内容: エージェントが以下を実行します:

  1. Google OAuthストラテジーでPassport.jsを設定し、起動時に必要な環境変数を検証
  2. OAuthリダイレクトとコールバックハンドラーを実装
  3. Googleメールが既存の登録済みアカウントと一致する場合のアカウントリンクを処理

ステップ5:TOTP二要素認証を追加する

/sk:cook "implement Step 4 from plans/phase-auth-system.md: optional TOTP 2FA — setup flow with QR code, verification, backup codes, and enforcing 2FA on login when enabled"

処理内容: エージェントが以下を実行します:

  1. 暗号化されたTOTPシークレット、有効フラグ、ハッシュ化されたバックアップコードでユーザースキーマを拡張
  2. setup、verify-setup、disableエンドポイントを実装
  3. 2FAが有効な場合に一時トークンを返すようにログインフローを更新し、2FA検証エンドポイントを追加

ステップ6:テストとセキュリティレビュー

/sk:test "comprehensive auth test suite: registration, login, token refresh, logout, email verification, password reset, OAuth callback, 2FA setup and login flow, and all security boundaries (expired tokens, revoked tokens, token reuse)"

処理内容: エージェントが以下を実行します:

  1. ハッピーパスとセキュリティ境界ケースをカバーする各auth機能のテストファイルを作成
  2. フルテストスイートを実行 — すべてのテストが合格
  3. タイミング攻撃ベクトル、メール列挙、トークンローテーション、JWTペイロード内の機密データなどの一般的なセキュリティ問題をレビュー

完全な実例:ECアプリに完全な認証システムが必要

シナリオ: 新しいECクライアントが、プラットフォームに完全な認証システムを必要としています。買い物客はメールで登録し、モバイルのコンバージョンのためにGoogleソーシャルログインが必須で、管理ユーザーには2FAがハード要件です。バックエンドはNode.js/Express/PostgreSQLです。Sprint 1の締め切りは来週金曜日です。

月曜日の朝 — 1セッションで完全な認証システムを構築:

# 1. 何かを書く前に既存のものを確認する
/sk:scout "check what auth-related code, middleware, or database tables already exist in this project"

# 2. クライアントの具体的な要件に基づいて計画する
/sk:plan "auth system for e-commerce: email registration with verification, JWT (15min) + refresh (30 days for 'remember me', 24h otherwise), password reset, Google OAuth (required), TOTP 2FA (required for admin role users, optional for shoppers). PostgreSQL + Prisma."

# 3. まずコア認証 — 他のスプリント作業のブロックを解除する
/sk:cook "implement core auth per plans/phase-auth-system.md steps 1-2: registration, login, token pair, refresh, logout, email verification, password reset"

# 4. Google OAuth — クライアントはモバイルに必須と言っている
/sk:cook "implement Google OAuth per plans/phase-auth-system.md step 3 — handle the case where a Google email matches an existing email-registered account"

# 5. 2FA — 管理ユーザーに必須
/sk:cook "implement TOTP 2FA per plans/phase-auth-system.md step 4 — enforce 2FA for users with role=admin, make it optional for shoppers"

# 6. リリース前のセキュリティレビュー
/sk:code-review "security review of the full auth implementation — check against OWASP Authentication Cheat Sheet: timing attacks, enumeration, brute force, token storage, secret handling"

# 7. セキュリティの指摘事項を修正する
/sk:cook "apply security fixes from plans/reports/review-auth.md"

# 8. すべてをテストする
/sk:test "full auth test suite — focus on security boundaries: token reuse attacks, expired token handling, 2FA bypass attempts, OAuth failure paths"

# 9. コミット
/sk:git cm "feat: complete authentication system — JWT, email verification, password reset, Google OAuth, TOTP 2FA"

結果: 火曜日の午後までに認証システムがステージングに入ります。Sprint 1の残り(商品カタログ、カート)は、認証がブロッカーになることなく同じコードベースで並行して進めることができます。セキュリティレビューはクリーンです。クライアントのモバイルチームはすぐにGoogleOAuthエンドポイントに対して構築を始められます。

セキュリティチェックリスト(OWASPに準拠)

実装に対して /sk:code-review "OWASP auth security checklist" を実行して以下を確認してください:

制御項目確認内容
パスワードハッシュbcrypt/argon2 with cost factor ≥ 10
タイミング攻撃crypto.timingSafeEqual または bcrypt.compare — 早期リターンなし
トークンエントロピーリフレッシュトークンは ≥ 256 ビットのランダムデータ
トークンストレージリフレッシュトークンはDBにハッシュ化して保存、生トークンは保存しない
メール列挙forgot-passwordはメールが存在するかどうかに関わらず200を返す
ブルートフォースログインとforgot-passwordエンドポイントへのレート制限
トークン失効ログアウトでリフレッシュトークンを失効させる。パスワードリセット時は全セッションを失効させる
JWTクレームペイロードにはuser_idのみ — ロール、メール、PIIはトークンに含めない
シークレットの検証JWT_SECRETが弱い、または未設定の場合はアプリが起動を拒否する
2FAバックアップコード一回使い切り、ハッシュ化済み、再生成可能

時間の比較

認証機能手動Sun Agent Kit使用時
登録 + ログイン + JWT1〜2時間5〜10分
トークンリフレッシュ + 失効30〜60分含む
メール確認30〜60分5〜10分
パスワードリセット30〜60分含む
Google OAuth1〜2時間5〜10分
TOTP 2FA2〜3時間5〜10分
セキュリティレビュー + テスト1〜2時間10〜15分
合計4〜8時間20〜40分

ベストプラクティス

1. 明示的なOWASPスコープで /sk:code-review を常に実行する ✅

一般的なレビューはコード品質の問題を検出します。セキュリティレビューには特定のフレームが必要です: /sk:code-review "OWASP auth security review — timing attacks, enumeration, brute force, secret handling"。エージェントは適切なチェックリストを適用します。

2. 計画プロンプトにトークンTTLを明示的に指定する ✅

「短命なアクセストークン」は曖昧です。クライアントが合意した正確なTTLをエージェントに伝えてください:「アクセストークン15分、リフレッシュトークン7日、remember-meリフレッシュトークン30日」。クライアントによってセキュリティ要件は異なります。

3. OAuthの前にメール確認を実装する ✅

OAuthユーザーはプロバイダーによって事前に確認されていますが、メール登録ユーザーは保護されたリソースにアクセスする前に確認が必要です。確認フローを先に構築し、その後OAuthを追加してください。

4. データベースにリフレッシュトークンをプレーンテキストで保存する ❌

データベースが侵害された場合、プレーンテキストのリフレッシュトークンは即座に使用可能です。常にハッシュを保存し、生トークンはクライアントに一度だけ送信してください。/sk:cook はデフォルトでこれを処理しますが、レビュー出力で確認してください。

5. アクセストークンとリフレッシュトークンに同じシークレットを使用する ❌

アクセストークンのシークレットが公開された場合(例:ログに出力)、リフレッシュトークンも侵害されるべきではありません。JWT_SECRETREFRESH_TOKEN_SECRET の環境変数を別々に使用してください。

トラブルシューティング

問題:メール確認リンクがユーザーがクリックする前に期限切れになる

解決策: APP_URL 環境変数が正しいパブリックURLに設定されていることを確認してください。リンクに localhost が含まれている場合、スマートフォンからクリックしたユーザーはリンク切れを見ることになります。/sk:fix --quick "email verification links use localhost instead of the APP_URL env variable" を実行してください。

問題:Google OAuthコールバックが空白ページまたは404を返す

解決策: Google Cloud Consoleに登録したコールバックURLはコードのものと完全に一致している必要があります。/sk:ask "what is the exact OAuth callback URL configured in the Passport.js Google strategy?" を実行し、Google Cloud Consoleの設定と照合してください。

問題:/sk:test がbcryptをモックしているため合格するテストを書く

解決策: テストプロンプトで指定してください:「bcryptやJWTをモックしない — 実際のハッシュと実際のトークン署名でテストし、別のテストデータベースを使用する」。暗号をモックしたインテグレーションテストは誤った自信をもたらします。

問題:認証アプリに正しいコードが表示されているのにTOTPコードが拒否される

解決策: TOTPは時刻に敏感です。サーバーのシステムクロックが同期されていることを確認してください(NTP)。/sk:fix --quick "TOTP verification is rejecting valid codes — add a 1-step (30s) time tolerance window to speakeasy.totp.verify" を実行してください。

次のステップ

  • REST APIを構築 — 構築した認証ミドルウェアでAPIエンドポイントを保護する
  • 新機能を追加 — SSO、マジックリンク、またはセッション管理UIで認証システムを拡張する
  • バグを体系的に修正 — 本番環境で認証フローのエッジケースが明らかになった場合

重要なポイント: 誤った認証実装はプロジェクトの寿命を超えた責任です。セキュリティレビュー済みの計画に対する /sk:cook は、40分で完全なスタックを構築し、6ヶ月後のペネトレーションテストで恥をかかないコードを生み出します。