オンプレ保護者認証仕様
- 文書バージョン: 0.4
- 作成日: 2026年8月23日
- ステータス: 計画(β実装前)
- 対象: 認証版(β版)を主対象とし、モック版・デモ版との共通実装方針も定める
- 関連文書: オンプレ・閉域向け自前認証、ベータ開始時の本番データ移行、デモデータ仕様、保護者向けプッシュ通知
1. 目的
認証版(β版)の保護者ポータルへ、ローカルパスワード認証とメール招待による初回登録を追加する。施設が登録したメールアドレスへ招待リンクを送り、保護者が照合用の保護者氏名、園児氏名、生年月日を入力し、園が申請を確認・承認した後に本人がパスワードを設定する。外字を含みうる漢字氏名は照合に使用せず、日本人は原則カナ、外国人は原則英字で照合する。
資格情報、照合、承認、セッション、監査はオンプレサーバーとローカルDBで完結させる。メール配送だけは施設管理のSMTPリレーまたは設定済みSMTPサーバーへ接続する。職員認証と同じ資格情報・セッション・試行制限・監査の基盤を使用するが、職員と保護者のログイン入口、Cookie、権限、運用を分離する。
本仕様は実装前の契約である。現在の保護者ポータルはモック認証であり、本仕様に記載する保護者ログイン、初期設定、パスワード変更、管理者による再設定は未実装である。
2. 決定事項
| 項目 | 決定 |
|---|---|
| 認証方式 | オンプレDBに保存したArgon2idパスワードとopaque sessionを使用する |
| アカウント単位 | 保護者1人につきParentAccountを1件作成する。家族共通アカウント・共通パスワードは禁止する |
| ログイン入口 | 保護者は/parent-portal/login、職員は/staff/loginを使用する |
| 認証主体の分離 | 同じログインIDが存在しても、職員入口では職員、保護者入口では保護者だけを検索する |
| 園児への認可 | ParentChildLinkを唯一の認可根拠とする。family_idだけを理由に園児を閲覧させない |
| 初回登録 | 登録済みメールへの招待、本人情報照合、園の承認、パスワード設定の順に行う |
| 本人情報照合 | 保護者の照合用氏名と、明示的に紐付く園児1名の照合用氏名・生年月日を登録済み台帳と照合する |
| 氏名表記 | 外字を含みうる漢字を使用しない。日本人は原則カナ、外国人は原則英字とし、園が人ごとに照合表記を設定する |
| 園の承認 | 自動照合だけで有効化せず、施設管理者の承認を必須とする |
| 再設定 | 施設管理者が本人確認後に有効期限付きコードを直接交付する。初期フェーズではメールによる自己再設定を行わない |
| ログインID | 承認時点の登録済みメールアドレスを初期ログインIDとする。登録完了後はプロフィールのメールアドレスとは独立して保持する |
| メールアドレス | 初期フェーズでは保護者アカウントごとに一意な受信可能アドレスを必要とする。夫婦で資格情報を共有しない |
| メール配送 | SMTPを差し替え可能にし、認証秘密や園児情報をメール本文へ記載しない |
| β版DB | β版専用DBへ資格情報、セッション、監査を保存し、アプリ再起動後も維持する |
| 本番相当環境 | モック認証への自動フォールバックを禁止する |
| MFA | 初期フェーズの対象外とする。資格情報テーブルは将来追加を妨げない設計とする |
3. 現状調査と不足点
3.1 利用できる既存基盤
現行実装には次の共通モデルがあり、principal_type=parentを格納できる。
PasswordCredential: ログインID、Argon2idハッシュ、状態、セッション世代CredentialActionToken: 初期設定・再設定用コードまたはtokenのハッシュ、有効期限、使用日時AuthSession: opaque sessionのハッシュ、アイドル期限、絶対期限、失効日時LoginThrottle: アカウント単位・送信元単位の試行制限AuthenticationEvent: 成功、失敗、ロック、失効等の監査イベント
職員についてはローカルパスワード認証が実装済みである。保護者についてはMockParentPortalAuthBackendだけがあり、ローカル認証バックエンド、認証画面、資格情報管理画面、ライフサイクル処理が未実装である。
3.2 β開始前に解消する認可上の問題
現行の保護者ポータルには、同じ家庭に属する全園児を自動的に閲覧対象へ広げる処理がある。また、家庭の保護者と園児の直積でParentChildLinkを再生成する処理がある。この挙動は、再婚家庭、別居、里親、一時的な送迎者等で過剰な閲覧権限を生むため、実データを使うβ開始前に廃止する。
必須の修正は次のとおりとする。
- 保護者が閲覧できる園児は、有効な
ParentChildLinkがある園児だけとする。 family_idは住所・請求・画面上のグルーピングに使用できるが、認可判定には使用しない。- 家庭の追加・編集時に、保護者と全園児の紐付けを自動生成しない。
- 一覧、詳細、連絡、アンケート、出欠、申請、プッシュ通知の対象展開で同じ認可条件を使用する。
- 未認可の園児IDを直接指定された場合は、存在の推測を防ぐため
404 Not Foundを返す。
この修正とアクセス境界テストが完了するまで、β版で実在する保護者へ認証情報を発行してはならない。
4. 対象範囲
4.1 初期フェーズに含める
- 保護者のローカルパスワードログイン・ログアウト
- 登録済みメールアドレスへの初回招待メール送信・再送
- カナまたは英字の照合用保護者氏名・園児氏名、生年月日の入力と台帳照合
- 施設管理者による登録申請の承認・却下
- 承認後のパスワード設定メールと保護者本人による初期パスワード設定
- ログイン済み保護者によるパスワード変更
- 施設管理者による再設定コードの発行
- アカウント停止、資格情報停止、全セッション失効
- アカウント単位・送信元単位のログイン試行制限
- セッションのアイドル期限・絶対期限
- 認証イベント・管理操作の監査
- 保護者ごとの明示的な園児アクセス制御
- β版専用DBでの永続化とバックアップ・復旧手順
4.2 初期フェーズに含めない
- SMSによる自動配信
- 保護者自身によるメールリンク型の「パスワードを忘れた」処理
- MFA、パスキー、外部IdP、ソーシャルログイン
- 家族での資格情報共有
- 施設をまたぐ単一アカウント
- 保護者によるログインIDの変更
5. 認証主体と権限
5.1 保護者
ログインできる条件はすべて満たす必要がある。
ParentAccount.statusがactive- 対応する
PasswordCredentialが存在し、有効 - パスワードが一致
- 試行制限中ではない
- 発行済みセッションが失効・期限切れでない
ログイン後もリクエストごとに保護者アカウントと資格情報の状態、セッション世代を検証する。アカウント停止後に既存Cookieだけで利用を継続できてはならない。
5.2 施設管理者
初期フェーズでは、招待送信、登録申請の承認・却下、保護者資格情報の管理を行えるのはadmin権限を持つ職員だけとする。園児台帳の編集権限だけでは、招待送信、承認、再設定コードの発行、ログインID変更、資格情報停止を行えない。自分で登録した保護者情報を同じ職員が承認することは許容するが、操作理由と監査を必須とする。
将来、専用権限can_manage_parent_authenticationを追加する場合も、園児台帳権限とは分離する。
5.3 認証と認可の分離
ログイン成功は、すべての園児情報へのアクセスを意味しない。各園児操作で、現在のparent_account_idと対象child_idの有効なParentChildLinkを照合する。
6. データ仕様
6.1 既存モデルの利用
PasswordCredential、CredentialActionToken、AuthSession、LoginThrottle、AuthenticationEventは職員と共用する。ただし、次の制約を維持する。
principal_type=parentではparent_account_idだけを設定し、職員IDを設定しない。- 保護者1人につき有効な資格情報は1件とする。
- 正規化済みログインIDの一意性は主体種別内で保証する。
- 生のパスワード、初期設定コード、再設定コード、セッション値をDBへ保存しない。
ParentAccount.password_hashは旧互換フィールドとして扱い、新しい認証では読み書きしない。既存値を自動移行してログイン可能にしてはならない。移行完了後の別リリースで削除する。
6.1.1 照合用氏名
ParentAccountとChildへ、初回登録専用の次の項目を追加する。
| フィールド | 内容 |
|---|---|
registration_verification_name |
園が登録した照合用のカナ氏名または英字氏名 |
registration_verification_name_type |
kanaまたはlatin |
- 日本人は原則
kana、外国人は原則latinを園が選択する。 - 国籍や氏名の文字からシステムが自動判定しない。通称、国際結婚、複数国籍等では園が本人と確認して適切な表記を選ぶ。
kanaは戸籍上の漢字や外字ではなく、園に届け出たカナ氏名を登録する。latinは旅券、在留カードまたは園へ届け出た英字表記を登録する。大文字・小文字は問わない。- 園内表示・帳票用の正式氏名は従来項目へ保持できるが、初回登録の照合には使用しない。
- 招待送信前に、対象保護者と少なくとも1名の紐付く園児へ照合用氏名が登録されていなければならない。
- 照合用氏名または表記種別の変更時は、未完了の招待・登録申請を失効する。
6.2 初回登録申請
初回招待と施設承認の状態を保持するParentRegistrationRequestを追加する。
| フィールド | 内容 |
|---|---|
id |
推測困難な申請ID |
parent_account_id |
対象保護者 |
email_normalized_snapshot |
招待送信時の正規化済みメールアドレス |
status |
invited、pending_review、approved、rejected、expired、completed、cancelled |
invitation_token_hash |
招待リンクtokenのハッシュ |
invitation_expires_at |
招待リンクの期限 |
verification_attempt_count |
本人情報の入力試行回数 |
guardian_name_matched |
登録済みの保護者照合用氏名との一致結果 |
child_name_matched |
明示的に紐付く園児の照合用氏名との一致結果 |
child_birth_date_matched |
同じ園児の生年月日との一致結果 |
matched_child_id |
3項目が一致した園児。未一致時は空 |
submitted_at |
園への確認申請日時 |
reviewed_by_user_id |
承認・却下した職員 |
reviewed_at |
承認・却下日時 |
review_reason |
承認・却下理由 |
completion_token_hash |
承認後のパスワード設定リンクtokenのハッシュ |
completion_expires_at |
パスワード設定リンクの期限 |
completed_at |
登録完了日時 |
created_at / updated_at |
作成・更新日時 |
入力された照合用保護者氏名、照合用園児氏名、生年月日はリクエスト内で登録済み台帳と照合し、申請には一致結果だけを保存する。入力値を別の個人情報レコードとして長期保存せず、アプリログや監査ログにも記録しない。
同じ保護者に有効な申請は1件だけとする。新しい招待を発行した場合、過去の未完了申請とtokenを失効する。招待後に登録メールアドレス、ParentChildLink、保護者または園児の照合用氏名・表記種別・生年月日が変更された場合も、未完了申請を失効して再招待する。
6.3 追加する監査モデル
管理者による資格情報操作を認証イベントとは別に追跡するため、ParentCredentialProvisioningAuditを追加する。
| フィールド | 内容 |
|---|---|
id |
主キー |
parent_account_id |
対象保護者 |
credential_id |
対象資格情報。作成前の操作では空を許可 |
operation |
invitation_issue、invitation_resend、registration_approve、registration_reject、completion_issue、reset_issue、disable、reactivation_issue、login_id_change |
actor_user_id |
操作した職員 |
reason |
再設定・停止等の理由。必須 |
created_at |
操作日時 |
コード本文、パスワード、セッション値は監査へ記録しない。
6.4 保護者–園児紐付け
ParentChildLinkは一意な(parent_account_id, child_id)を持つ。削除は原則として論理削除または履歴を残す方式へ変更し、最低限、誰がいつ追加・解除したかを監査できるようにする。初期実装で物理削除を維持する場合は、同一トランザクションで変更監査を必ず記録する。
7. セキュリティ仕様
7.1 パスワード
職員認証と同じArgon2id設定を使用する。
time_cost=3memory_cost=65536 KiBparallelism=1hash_len=32salt_len=16- 長さ8~128文字
- ログインID、メールアドレス、表示名を含む推測しやすいパスワードを拒否
- 組み込みの弱いパスワード一覧と、施設が追加できるブロックリストを使用
Argon2idパラメータは環境変数で弱められない。将来パラメータを強化した場合は、ログイン成功時に再ハッシュできる設計とする。
7.2 メール招待・パスワード設定リンク
- tokenはCSPRNGで256 bit以上とし、DBにはハッシュだけを保存する
- 招待リンクと承認後のパスワード設定リンクは、それぞれ発行から24時間有効とする
- いずれも1回限り使用でき、再送時は以前のtokenを失効する
- メール本文には保護者名、園児名、生年月日、ログインID、仮パスワードを記載しない
- GETで申請状態を変更せず、メールセキュリティ製品のリンク確認だけでtokenを消費しない
- tokenはURL fragmentに格納し、同一オリジンの初回登録画面がPOST bodyで交換する。交換後は短命なHttpOnly登録用Cookieを発行し、ブラウザ履歴からfragmentを除去する
- 初回登録画面は外部画像、解析タグ、CDNスクリプトを読み込まず、
Referrer-Policy: no-referrerとCache-Control: no-storeを返す - token、保護者の入力値をWebサーバーのアクセスログ、アプリログ、監査ログへ出力しない
リンクの送信先は施設が事前登録したParentAccount.emailだけとし、初回登録画面で変更できない。宛先を変更する場合は施設が台帳を訂正し、過去の申請を失効して再招待する。
7.3 本人情報の照合
- 保護者氏名は
ParentAccount.registration_verification_nameと照合する - 園児氏名と生年月日は、対象保護者に明示的に紐付く同一園児の
registration_verification_nameと生年月日に照合する - 兄弟姉妹が複数いる場合はいずれか1名が3項目すべて一致すれば申請可能とし、候補園児一覧を公開画面へ表示しない
- 公開画面の項目名は「園に登録した保護者氏名(カナまたは英字)」「園に登録した園児氏名(カナまたは英字)」とし、漢字氏名を求めない
kanaはUnicode NFKC、前後・氏名間の空白除去、ひらがなからカタカナへの変換を行う。長音符・中点を保持し、正規化後の完全一致とするlatinはUnicode NFKC、前後空白除去、連続空白の統一、Unicode casefold、ハイフンとアポストロフィの代表文字への統一を行い、正規化後の完全一致とする。アクセント記号を勝手に除去しない- 漢字・外字の字体変換、異体字変換、読みの推測、あいまい一致は行わない
- 生年月日は年月日の完全一致とする
- 一致・不一致にかかわらず公開画面には「園に確認を依頼しました」とだけ表示し、どの項目が違うかを返さない
- 1招待につき5回までとし、上限到達時は申請を停止して管理者による再招待を必要とする
- 3項目の一致は園が承認できる条件であり、認証完了や園児アクセス許可を意味しない
園の確認画面には登録済み台帳、照合用氏名の表記種別、対象のParentChildLink、3項目の一致結果を表示する。入力された生の氏名・生年月日は表示しない。不一致がある申請は承認できず、照合用氏名または台帳の誤りを訂正した上で再招待する。
7.4 初期設定・再設定コード
- 紛らわしい文字を除いた6文字
- 有効期限30分
- 1回限り使用可能
- DBにはコードのハッシュだけを保存
- 同じ目的の新しいコードを発行した時点で旧コードを失効
- コードをURLクエリ、アクセスログ、アプリログへ含めない
- 画面表示は発行直後の1回だけとし、再表示できない
コード交付前に、施設が定める本人確認を行う。本人確認方法は運用記録へ残すが、本人確認資料そのものを不要に保存しない。
この6文字コードはメールが利用できない場合の管理者交付による初回登録救済と、パスワード再設定に使用する。通常の初回登録はメール招待を使用する。
7.5 ログイン試行制限
職員認証と同じ仕組みを使い、保護者用バケットを分離する。
- 判定窓: 15分
- アカウント単位: 5回失敗で一時制限
- 送信元単位: 20回失敗で一時制限
- 存在しないログインIDでもダミーハッシュ検証を行い、応答差を小さくする
- エラーメッセージは「ログインIDまたはパスワードを確認してください」に統一する
7.6 CSRF・レスポンス
- ログイン、ログアウト、初期設定、再設定、パスワード変更はPOSTとしCSRF検証を行う
- 認証画面、コード画面、管理画面は
Cache-Control: no-storeを返す - リダイレクト先は
/parent-portal配下の同一オリジン相対パスだけを許可する - 認証秘密、個人情報をログへ出力しない
8. セッションとCookie
| 項目 | 開発・HTTP | β/本番・HTTPS |
|---|---|---|
| Cookie名 | hoikuict_parent_session |
__Host-hoikuict_parent_session |
HttpOnly |
有効 | 有効 |
Secure |
HTTP確認時のみ無効 | 有効 |
SameSite |
Lax |
Lax |
Path |
/ |
/ |
Domain |
設定しない | 設定しない |
- アイドル期限: 12時間
- 絶対期限: 7日
- セッション値は十分な乱数で生成し、DBにはハッシュだけを保存する
- ログアウト時は現在のセッションをDBで失効し、Cookieを削除する
- 本人によるパスワード変更時は他の全セッションを失効し、現在のセッションtokenをrotateする
- 管理者発行コードによる再設定時は対象保護者の全セッションを失効し、再ログインを求める
- 資格情報停止・アカウント停止時は、全セッションを同一トランザクションで失効する
職員Cookieと保護者Cookieは別名とし、片方のCookieで他方の入口へログインできない。
9. 画面・URL仕様
9.1 保護者向け
| メソッド | URL | 用途 |
|---|---|---|
| GET | /parent-portal/login |
ログイン画面 |
| POST | /parent-portal/login |
ログイン処理 |
| POST | /parent-portal/logout |
現在のセッションを失効 |
| GET | /parent-portal/register/invite |
メール招待の初回登録画面。URL fragmentをサーバーへ送らない |
| POST | /parent-portal/register/invite/verify |
fragmentから受け取った招待tokenを交換し、短命な登録用Cookieを発行 |
| GET | /parent-portal/register/identity |
カナまたは英字の保護者氏名・園児氏名、生年月日の入力画面 |
| POST | /parent-portal/register/identity |
登録済み台帳と照合して園への確認申請を作成 |
| GET | /parent-portal/register/status |
申請受付済み・期限切れ等の一般化した状態表示 |
| GET | /parent-portal/register/complete |
園承認後のパスワード設定画面 |
| POST | /parent-portal/register/complete/verify |
パスワード設定tokenを短命な登録用Cookieへ交換 |
| POST | /parent-portal/register/complete |
初期パスワード設定と資格情報有効化 |
| GET | /parent-portal/activate |
メールを利用できない場合の救済コード入力画面 |
| POST | /parent-portal/activate/verify |
救済コード検証。成功後に短命な設定用状態を発行 |
| POST | /parent-portal/activate/complete |
救済経路での初期パスワード設定 |
| GET | /parent-portal/account/password |
パスワード変更画面 |
| POST | /parent-portal/account/password |
現在のパスワード確認後に変更 |
| GET | /parent-portal/reset |
管理者発行の再設定コード入力画面 |
| POST | /parent-portal/reset/verify |
再設定コード検証 |
| POST | /parent-portal/reset/complete |
新パスワード設定、全セッション失効 |
招待token、パスワード設定token、救済コードの検証後に発行する登録用状態は通常のログインセッションと分離し、対象保護者、申請ID、目的、有効期限、使用済み状態を拘束する。登録用Cookieだけでは保護者ポータルの認証済み画面へアクセスできない。
9.2 施設管理者向け
/parent-accounts/{id}の詳細または専用の認証管理画面に、次を表示する。
- ログインID
- 資格情報状態(未招待、招待済み、園確認待ち、承認済み・設定待ち、有効、却下、期限切れ、再設定待ち、停止)
- 最終ログイン日時
- 招待先メール、送信日時、有効期限、送信結果。token本文は表示しない
- 本人情報3項目の一致結果と照合対象の園児
- 申請日時、承認・却下者、日時、理由
- 再設定コードの発行日時と有効期限。コード本文は再表示しない
- 有効なセッション数
- 招待送信・再送、申請承認・却下、救済コード発行、再設定コード発行、資格情報停止、再有効化の操作
管理操作はすべて理由入力、CSRF検証、再認証済みの職員セッションを要求する。招待メールの再送は60秒以上の間隔を設け、1日あたりの上限を設定する。URLに短い救済コードを含めない。
9.3 画面上の文言
「パスワードを忘れた場合」は、外部メール送信を装わず「施設へご連絡ください」と案内する。連絡先は施設設定から表示できる設計とし、未設定時は固定の個人連絡先を表示しない。
10. 業務フロー
10.1 新規保護者のメール招待と園承認
- 園児台帳担当者が保護者と園児の照合用氏名・表記種別、受信確認済みメールアドレス、必要な
ParentChildLinkを登録する。 - 管理者が対象保護者、メールアドレス、園児紐付けを確認して招待を送信する。
- システムは24時間有効な単回使用tokenを作り、登録済みメールアドレスへ招待リンクを送る。メールには個人情報を記載しない。
- 保護者はリンクを開き、園に届け出たカナまたは英字の保護者氏名、紐付く園児1名のカナまたは英字氏名と生年月日を入力する。漢字氏名は入力しない。
- システムは登録済み台帳と照合する。公開画面では照合結果を明かさず、園への確認受付だけを表示する。
- 照合結果にかかわらず申請を
pending_reviewとし、管理者の確認一覧へ表示する。3項目のいずれかが不一致の場合は承認操作を無効にする。 - 管理者は登録済み保護者、園児、明示的な紐付け、一致結果を確認し、理由を入力して承認または却下する。
- 承認時にシステムは24時間有効なパスワード設定tokenを作り、同じ登録済みメールアドレスへ設定リンクを送る。まだログイン可能にはしない。
- 保護者が設定リンクからパスワードを登録する。
- システムはtokenを使用済みにし、資格情報と登録申請を有効・完了状態にする。初回は自動ログインせず、通常ログイン画面へ戻す。
園が却下した場合、公開画面やメールには詳細な却下理由を記載せず、施設への連絡を案内する。メール不達の場合は宛先を園側で訂正して再招待する。保護者が初回登録画面で宛先を変更することはできない。
10.2 メールを利用できない場合の初回登録救済
施設管理者が本人確認後に30分有効な6文字コードを発行し、施設承認済みの方法で本人へ交付する。救済経路でも、管理者による対象保護者とParentChildLinkの確認を省略しない。救済コードによる完了を監査し、通常のメール招待と同じパスワードポリシーを適用する。
10.3 パスワードを忘れた場合
- 保護者が施設へ連絡する。
- 管理者が本人確認と対象アカウントを確認する。
- 管理者が理由を入力し、再設定コードを発行する。
- システムは既存の再設定コードを失効する。コード発行だけではログイン中の本人を締め出さず、再設定完了時に全ログインセッションと全端末のプッシュ購読を無効化する。ただし、侵害が疑われる場合は管理者が発行と同時に資格情報を一時停止できる。
- 保護者が再設定コードで新パスワードを登録する。
- 通常ログインを行う。
管理者は保護者のパスワードを閲覧・任意値へ直接変更できない。
10.4 ログイン中のパスワード変更
現在のパスワードを再確認して新しいパスワードへ変更する。変更成功後は他の全セッションを失効し、現在のセッションtokenをrotateする。全端末のプッシュ購読を無効化し、現在のブラウザも必要に応じて再購読させる。監査イベントを記録する。
10.5 退園・利用停止・紐付け変更
- 保護者ポータル全体を止める場合は
ParentAccount.status=inactiveとし、資格情報、全セッション、全プッシュ購読を同一処理で無効化する。 - 特定の園児だけを外す場合は該当
ParentChildLinkを解除する。次のリクエストからアクセス不能にする。 - 園児の退園だけを理由に、同じ保護者に紐づく在園中の兄弟姉妹まで利用停止しない。
- 再有効化時は既存パスワードを黙って復活させず、通常は新しいメール招待を送り、メールを利用できない場合だけ救済コードを発行する。
11. プッシュ通知との連携
保護者セッションとブラウザのプッシュ購読は別データだが、資格情報の侵害や停止時には連動して無効化する。
| 操作 | セッション | プッシュ購読 |
|---|---|---|
| 通常ログアウト | 現在だけ失効 | 現在のブラウザだけ無効化 |
| パスワード変更 | 他の全件を失効、現在はtoken rotate | 全件無効化 |
| 管理者による再設定発行 | 原則維持。侵害時は資格情報停止を併用 | 原則維持。侵害時は全件無効化 |
| 再設定完了 | 全件失効 | 全件無効化 |
| 資格情報・アカウント停止 | 全件失効 | 全件無効化 |
| 特定園児の紐付け解除 | 維持 | 維持。ただし以後その園児を通知対象へ展開しない |
12. 環境設定
新しい環境変数を追加する。
HOIKUICT_PARENT_AUTH_MODE=mock|local_password|disabled
HOIKUICT_PARENT_MAIL_TRANSPORT=capture|smtp|disabled
HOIKUICT_PARENT_REGISTRATION_BASE_URL=https://hoiku.example.jp
HOIKUICT_SMTP_HOST=mail.example.local
HOIKUICT_SMTP_PORT=587
HOIKUICT_SMTP_STARTTLS=1
HOIKUICT_SMTP_USERNAME=...
HOIKUICT_SMTP_PASSWORD=...
HOIKUICT_PARENT_MAIL_FROM=...
| 環境 | 職員認証 | 保護者認証 | DB |
|---|---|---|---|
| モック版 | mock |
mock |
開発用DB |
| テスト版 | テストごとに明示 | テストごとに明示 | 一時DB |
| デモ版 | デモ方針に従う | 原則mock |
デモ専用DB |
| 認証版(β版) | local_password |
local_password |
β専用永続DB |
| 本番 | local_password |
local_password |
本番専用DB |
captureはメールを外部へ送らず、完全なメール内容をアクセス制限されたテスト専用メールボックスへ保存する。tokenを通常のアプリログや監査ログへ出力せず、テストDB初期化時にcaptureメールも消去する。モック版・自動テスト・実在しないデータでのβリハーサルだけに使用する。実在保護者を招待するβ・本番ではSMTPを使用する。
起動時検証は次を必須とする。
- β・本番で
mockを指定した場合は起動失敗 - 保護者ポータルを公開するβ・本番で
disabledを指定した場合は起動失敗 local_passwordなのにHTTPS前提Cookie、login throttle用HMAC鍵、DB等の必須設定が不足する場合は起動失敗- β・本番でメール招待を有効にする場合、
smtp、HTTPSの公開base URL、送信元、TLS設定が不足すると起動失敗 - β・本番で
captureを指定した場合は起動失敗 - SMTPパスワードをDB、リポジトリ、画面へ保存せず、サーバーのsecret設定から読み込む
- 職員認証と保護者認証を暗黙に同じモードへ揃えず、両方を明示する
13. オンプレ運用
13.1 オンプレ境界とメール配送
認証、本人情報照合、園承認、パスワード、token hash、監査、セッション管理は施設内サーバーとDBだけで完結する。メール本文の生成と送信要求もアプリ内で行い、配送は設定したSMTPサーバーへ委譲する。外部ID基盤やメール配信SaaS固有APIは使用しない。
一般の保護者メールアドレスへ届けるには、施設内SMTPリレーからインターネットへ送信できる構成、または利用許可を受けたSMTPサーバーが必要である。完全閉域・インターネット停止中はメール招待を利用できないため、管理者交付の救済コード経路を維持する。通常ログイン、園内での再設定コード発行、既存セッションの検証はSMTP停止中も動作する。
保護者が園外からリンクを開く場合、登録base URLは園外から到達できるHTTPS URLでなければならない。オンプレサーバーをリバースプロキシまたはVPNの内側で公開し、TLS証明書、ファイアウォール、名前解決を整備する。園内LANだけで利用する場合は、招待リンクを開いて登録する場所も園内LANに限定される。送信ドメインのSPF、DKIM、DMARC等の配送設定はSMTP・DNS側の運用項目とする。
SMTP送信は同期画面処理と分離し、キュー、再試行上限、送信結果を保持する。同じメールを無制限に再送しない。送信失敗で申請を有効化せず、管理画面へ失敗理由コードと再送操作を表示する。SMTP応答本文に個人情報が含まれる可能性があるため、そのまま監査へ保存しない。
13.2 バックアップ
β版DBはモック・デモDBから分離する。SQLiteを使用する場合は、稼働中の.dbだけをファイルコピーせず、SQLite backup APIまたは停止後の整合したコピーを使用する。WALモードでは.db-walと.db-shmは一時的な動作ファイルであり、バックアップ成果物として個別に扱わない。
バックアップには資格情報・セッション・監査が含まれるため、暗号化、アクセス制限、保存世代、復元テストを必要とする。復元後は安全側の措置として全保護者セッションを失効できる手順を用意する。
13.3 管理者の救済
保護者の再設定は管理画面から行う。管理者自身がログインできない場合の救済は、既存の初期管理者CLIと管理者再設定手順を使用する。日常運用では管理者を最低2名登録し、アプリ起動ごとの管理者再作成は行わない。
13.4 デモ・テストデータ
デモデータ仕様に従い、84家庭中9家庭(10.7%)を外国籍想定の固定シナリオとする。対象家庭にはlatinの照合用氏名を持つ保護者または園児を含め、カナ/英字混在家庭、兄弟家庭、招待・承認の各状態を確認できるようにする。
国籍そのものは認証・認可データとして保持せず、対象判定はダミーデータ内のregistration_verification_name_type=latinだけで行う。デモ用メールは実在宛先へ送信せず、capture transportを使用する。β版でこのデータを使う場合もβ専用DBへ明示的に投入し、起動時に既存βデータを上書きしない。
14. 移行方針
- 現行βデータをバックアップする。
- スキーマ追加を適用する。既存の保護者を自動的にログイン可能にしない。
- 家庭直積による
ParentChildLink生成を停止し、明示的な紐付けへ修正する。 - 既存紐付けを一覧出力し、施設側が保護者ごとに確認する。
- アクセス境界の自動テストと実データを使わないリハーサルを実施する。
- 実在しないメールアドレスと
capturetransportで、招待、照合申請、承認、パスワード設定をリハーサルする。 - βのSMTP、公開HTTPS URL、送信ドメイン設定を確認し、施設管理者自身のテスト保護者へ招待を送る。
- β管理者が対象保護者へ順次、メール招待を送信する。
- 招待、不達、申請、承認・却下、登録完了、最終ログイン、停止を監査から追跡する。
モックCookie、モック用選択状態、ParentAccount.password_hashの既存値はローカル認証へ引き継がない。
15. 実装順序
フェーズ1: 認可境界の修正
ParentChildLinkを唯一の園児認可根拠に変更- 家庭直積の自動同期を廃止
- 全保護者機能の直接URL・一覧・通知対象テストを追加
フェーズ2: 認証基盤
- 保護者ローカル認証バックエンドと環境設定を追加
- 共通認証サービスを職員・保護者で安全に再利用
- ログイン、ログアウト、セッション検証、試行制限を実装
- メールtransport、送信キュー、招待token、初回登録申請を実装
- 管理者向け招待・承認・却下・再設定・停止を実装
フェーズ3: 本人操作と運用
- 本人情報照合、承認後パスワード設定、救済初期設定、再設定、本人パスワード変更を実装
- プッシュ購読失効を連携
- β専用DBのバックアップ・復元・再起動試験を実施
フェーズ4: 横断反映
- 共通コードとテストをモック版・テスト版・デモ版へ反映
- 各版では認証モードとDBだけを分離し、業務機能を別実装にしない
- デモ版には本物の資格情報やβデータをコピーしない
16. 受入テスト
16.1 認証
- 正しい保護者資格情報だけが保護者入口で成功する
- 同じログインIDの職員資格情報は保護者入口で使えず、その逆も成立する
- 未登録IDと誤パスワードで、外部から区別できる応答差を作らない
- 非アクティブ保護者、停止資格情報、期限切れ・失効セッションを拒否する
- アカウント単位・送信元単位の試行制限が保護者バケットだけへ作用する
16.2 メール招待と園承認
- 招待は登録済みメールアドレスだけへ送られ、保護者が画面上で宛先を変更できない
- 招待tokenとパスワード設定tokenは256 bit以上、ハッシュ保存、24時間、有効1回、再発行時失効となる
- tokenをURL fragmentからPOSTで交換し、GETやメールスキャナーのアクセスだけでは消費しない
- メール本文と件名に保護者名、園児名、生年月日、仮パスワードを含めない
- 登録された表記種別に従って保護者氏名、同一園児の氏名・生年月日を照合し、3項目すべて一致した場合だけ園が承認できる
- 正式氏名に外字が含まれても照合へ影響せず、漢字氏名を入力しても照合に使用されない
- カナの全半角・ひらがな/カタカナ、英字の大文字・小文字等は定義済み正規化後に比較される
- 国籍や入力文字から
kana/latinを自動判定しない - 複数園児が紐付く場合でも、候補園児一覧や一致しなかった項目を公開画面へ表示しない
- 入力値をログ・監査・申請へ平文保存せず、一致結果だけを保持する
- 1招待5回の試行上限、招待期限、メール変更・紐付け変更時の失効が機能する
- 自動照合後も園の承認までは資格情報を有効化しない
- 園の承認後も本人が設定リンクからパスワードを登録するまではログインできない
- 承認・却下・再送・送信失敗が管理画面と監査で追跡できる
16.3 コードとパスワード
- 初期設定・再設定コードはハッシュ保存、30分、有効1回、再発行時失効となる
- コードをログ、URL、監査へ平文保存しない
- 弱いパスワードと個人情報を含むパスワードを拒否する
- パスワード変更で他の全セッションを失効して現在tokenをrotateし、再設定完了で全セッションを失効する
- パスワード変更・再設定完了で全プッシュ購読を無効化する
- 管理者は現在または新しいパスワードを閲覧できない
16.4 認可境界
- 明示的な
ParentChildLinkがある園児だけを一覧・詳細で閲覧できる - 同じ
family_idでも紐付けのない兄弟姉妹を閲覧できない - 未認可の園児IDを直接指定すると404になる
- 連絡、出欠、アンケート、申請、請求表示、通知対象展開でも同じ境界を維持する
- 保護者プロフィールのメール変更だけではログインIDが変わらない
16.5 セッション・Web安全性
- 開発・βのCookie属性とCookie名が仕様どおりになる
- 職員Cookieと保護者Cookieが相互利用できない
- アイドル12時間、絶対7日の期限、明示ログアウト、セッション世代失効が機能する
- CSRF、
no-store、安全なリダイレクト制限を確認する
16.6 環境・運用
- β再起動後も保護者資格情報と監査がβ専用DBに残る
- モック版・デモ版・β版でDBと秘密情報が混在しない
- β・本番が
HOIKUICT_PARENT_AUTH_MODE=mockで起動しない - β・本番が
capturemail transportやHTTPの登録base URLで起動しない - SMTP停止時も既存保護者のログインと管理者交付の救済コードが動作する
- 84家庭の固定seedで外国籍想定家庭が9家庭となり、カナ/英字混在・兄弟家庭・登録状態別サンプルを再現できる
- バックアップを別環境へ復元し、全セッション失効後に管理者・保護者の再ログインを確認できる
17. 完了条件
次をすべて満たした時点で、保護者認証を「β利用可能」とする。
- 認可境界の必須修正と自動テストが完了している。
- メール招待、本人情報照合、園の承認・却下、承認後パスワード設定が動作する。
- ログイン、ログアウト、本人変更、管理者再設定、メール不通時の救済、停止が動作する。
- 試行制限、Cookie、セッション期限、CSRF、監査が職員認証と同水準である。
- β版専用DBのバックアップ・復元・再起動試験に合格している。
- モック認証や
captureメールへフォールバックしないことを起動時検証で保証している。 - 実在する保護者へ発行する前に、紐付け一覧、SMTP、送信元ドメイン、公開HTTPS URLを施設側が確認している。
18. 主な実装対象(予定)
security_config.py:HOIKUICT_PARENT_AUTH_MODE、mail transport、SMTP、公開base URLと本番相当環境の検証auth.py:LocalPasswordParentAuthBackend、保護者Cookie、認証依存関数local_auth.py: 主体種別を明示した共通処理、保護者初期設定・再設定・セッションmodels.py/database.py: 初回登録申請、管理操作監査、送信キュー、必要な索引・制約・移行routers/parent_auth.py(新設案): 保護者認証、メール招待token交換、本人情報照合、本人操作routers/parent_accounts.py: 管理者向け招待・承認・資格情報管理と明示的な園児紐付けparent_auth_mail_service.py(新設案):capture/ SMTP transport、テンプレート、キュー、再試行routers/parent_portal.py:ParentChildLinkだけを使う認可へ変更family_support.py: 家庭直積による紐付け同期の廃止templates/parent_portal/、templates/parent_accounts/: 認証・管理画面tests/test_local_parent_auth.py(新設案): 招待、本人情報照合、園承認、認証、コード、セッション、環境差- 保護者ポータル各機能のテスト: 園児アクセス境界と直接URL拒否