MIRAIS 設計・実装記録 #6|守り方と到達点 — セキュリティ設計・残課題・学んだこと
第 6 回 守り方と、到達点
最終回です。個人情報を扱うシステムとして何をどう守ったのか、そして率直に何が残っているのか。最後に、このプロジェクトの設計判断を通して学んだことを 3 つ書き残します。
第 XII 部 品質とセキュリティ設計
40. セキュリティの設計方針
個人情報を扱うシステムである以上、セキュリティは機能の一部ではなく前提条件だと考えました。設計上、以下の考え方を軸にしています。
40-1. 表示制御と、データを渡さないことを区別する
フロントエンドで隠すことはセキュリティではありません。未認証に見せないと決めたデータは、API のレスポンスに載せない。 公開用のレスポンス型を必要最小限のフィールドだけで定義し、型のレベルでこの方針が守られるようにしました。
40-2. 制約はアプリケーションとデータベースの両方に置く
二重投票の防止、1 学生 1 提出、1 学生 1 賞——これらはいずれも、アプリケーションのロジックとデータベースの一意制約の両方で担保しています。ロジック側だけで守ると、別の経路から書き込まれたときに崩れるためです。
40-3. 危険な操作には多重の条件を課す
開発・デモ用の機能群は、開発モードであることと運営ロールであることの両方を満たさなければ実行できません。フラグ 1 つの立て忘れが致命傷にならないようにしています。
40-4. ファイルは受け取る前に疑う
アップロードは、ロール・登録状態・運用フェーズ・宣言された種別・拡張子・実際のファイル内容の先頭バイト・サイズを多段で確認します。また、保存先のファイル名は認証済みユーザーの情報から生成し、リクエストの値には由来させません。他人のファイルを上書きする経路を、そもそも作らないという考え方です。
40-5. 権限は「必要な人が、必要な範囲だけ」
全学生の連絡先を含む一覧は運営に限定し、教員には自分の担当ゼミの学生のみを返す専用の経路を用意しました。「教員だから全部見られる」ではなく、「担当している範囲だけ見られる」が正しい設計だと判断しています。
40-6. 個人情報をリポジトリに置かない
実データ(研究テーマ・受賞者・ポスター)はバージョン管理の対象外に隔離し、デモ用のコードにも氏名を書かない方針にしました。ソースコードは共有されるものであり、そこに個人情報を置いた時点で回収が困難になります。
41. 残っている課題(性質のみ)
外部公開版のため、具体的な箇所や再現手順は記載しません。性質と対処方針のみを記します。
| 分類 | 課題の性質 | 対処方針 |
|---|---|---|
| 認可 | 一部のエンドポイントで、公開ポリシーと認可設定の粒度に不一致がある | ポリシーに合わせて認可を厳格化する。最優先で対応 |
| 認証保持 | 認証情報の保持方式が、より安全な方式へ移行できる余地がある | 保持方式の変更と、それに伴う対策の追加 |
| 濫用対策 | 試行回数を制限する仕組みがない | 流量制限の導入 |
| 追跡性 | 重要な操作の変更履歴が残らない | 監査ログの追加 |
| 依存管理 | 依存ライブラリの脆弱性を継続的に検査していない | CI への検査の組み込み |
| 秘密情報 | 設定値の管理方式に改善余地がある | 専用の管理機構への移行 |
| スキーマ変更 | データベースのスキーマ変更を安全に適用する仕組みが未導入 | マイグレーションツールの導入。最優先で対応 |
| 監視 | 構造化ログと障害追跡の仕組みが未導入 | ログ基盤と監視の整備 |
| テスト | 自動テストが未整備で、変更が既存機能を壊しても検知できない | テスト基盤の構築。最優先で対応 |
41-1. 最優先の 3 つについて
認可の不一致は、公開遮断ポリシーを厳格に定めた一方で、後から追加した一部の機能でその適用が徹底されていなかったものです。ポリシーを文章とコメントで守るだけでは不十分で、型や共通の依存関係で機械的に強制する仕組みが必要だったと考えています。
スキーマ変更の仕組みは、開発初期に「起動時に自動でテーブルを作る」方式を選んだことに起因します。開発中は快適でしたが、運用開始後にカラムを追加する手段がありません。運用フェーズに入る前に必ず解消すべき負債です。
テストの不在は、率直に言って最大の課題です。表彰アルゴリズムのように分岐が多く、かつ間違えたときの影響が大きい処理が、人手の確認だけで担保されている状態です。機能を増やすより先に、ここを埋めるべきだと考えています。
第 XIII 部 到達点と展望
42. 機能の実装状況
| ID | 機能 | 状態 | 残課題 |
|---|---|---|---|
| F-01 | 現行機能の完全踏襲 | ✅ 完了 | 式次第がフロントに固定値で入っている。設定から取得する形へ |
| F-02 | Google OAuth 認証 | ✅ 完了 | 認証情報の保持方式の改善 |
| F-03 | 学生マイページ | ✅ 完了 | — |
| F-04 | 運営用ダッシュボード | ✅ 完了 | 定期的な自動同期(現状は手動実行) |
| F-05 | 自動リマインダー | 🟡 部分実装 | 自動実行が未実装。個別 DM 送信も未対応 |
| F-06 | 高度な研究一覧 | ✅ 完了 | 全文検索、ファセット検索 |
| F-07 | LLM セマンティックマッチング | ✅ 完了 | ベクトル拡張への移行、関連研究の推薦 |
| F-08 | 多角型フィードバックコメント | ✅ 完了 | 「先輩」バッジの自動判定、匿名/実名切替 |
| F-09 | 3D 会場・バーチャル展示 | ✅ 完了(想定超え) | 企業ブースの 3D 配置の反映 |
| F-10 | リアルタイム投票・表彰 | ✅ 完了 | 真のリアルタイム反映(現状はポーリング) |
| F-11 | 過年度アーカイブ | ✅ 完了 | 過年度データの読み取り専用化 |
| F-12 | 運営設定管理画面 | ✅ 完了 | — |
42-1. 設計になかったが実装された機能
要件定義の時点では見えておらず、ヒアリングと実装の過程で必要性が判明したものです。
| 機能 | 生まれた経緯 |
|---|---|
| 表彰選定アルゴリズム | 「序列」「格上げ」という運用実態を知って設計 |
| 表彰スライド自動生成 | 「既存マクロが不安定」という具体的な困りごとから |
| ブース案内スライド自動生成 | 「ポスターの上に貼る紙」の存在を知って |
| ブース自動割り当て | 3 部制の割り振りが手作業だと判明して |
| 企業担当者管理 | 「毎年、担当者が変わる」「CC 管理が大変」から |
| 企業オファー | マッチングを「見るだけ」で終わらせないために |
| 企業 3D ブース | 3D 空間を企業側からも使えるようにするため |
| 学生の所属年度判定 | 卒業間近の学生の導線を壊さないため |
| 同期ジョブ履歴 | 「実行したが結果が分からない」を防ぐため |
| 過年度 CSV 取り込み | 実データでの検証と、アーカイブの初期投入のため |
| 3D 会場の「現在の部」連動 | 現地と 3D 空間の体験を同期させるため |
このリストは、要件定義は最初に完成しないということの証拠でもあります。ヒアリングで運用の細部を知るたび、必要な機能が立ち上がってきました。第 2-2 節 / 第 1 回で決めた「細かい要件は変わってよいが、コア体験は変えない」という合意が、この変化を混乱ではなく前進として扱うための土台になりました。
43. 現在地と、これから
43-1. フェーズ別の到達状況
| フェーズ | 内容 | 状態 |
|---|---|---|
| Phase 0 基盤整備 | 型・時刻処理・起動処理・CI の整備 | ✅ 大半完了(マイグレーションとテストが残る) |
| Phase 1 MVP 完成 | 認証・提出・ダッシュボード・投票・静的ページ | ✅ 完了 |
| Phase 2 中核機能 | LLM 推薦・3D 会場 | ✅ 完了 |
| Phase 3 運営強化 | 自動リマインド・検索強化・アーカイブ・設定管理 | 🟡 リマインドの自動実行が残る |
| Phase 4 製品化 | セキュリティ・テスト・監視・パフォーマンス | 🔲 未着手が中心 |
| Phase 5 引き継ぎ | 運用マニュアル・障害対応手順・操作ガイド | 🟡 運用手順は整備済み |
43-2. 残るクリティカルパス
① 【最優先・半日規模】 セキュリティと基盤の 3 点
・認可設定をポリシーに合わせて厳格化
・本番環境での開発機能無効化の確認
・スキーマ変更の仕組み導入(または変更禁止の運用ルール明文化)
② 【高・数日規模】 テスト基盤
表彰アルゴリズム / ブース割り当て / 認可境界のテスト
→ これが無いと、今後の変更が既存機能を壊しても誰も気づけない
③ 【中・1 週間規模】 リマインドの自動実行
唯一「部分実装」で残っている必須級の機能
43-3. このプロジェクトで学んだこと
最後に、技術的な結論ではなく、設計判断を通して学んだことを 3 つ書き残します。
1. 制約は設計を明確にする
「外部の商用サービスに依存しない」という前提は、最初は不自由に見えました。しかし実際には「商用 API に依存できない」→「学内資源を使う」→「それが使えないときも動く構成にする」という判断の連鎖を強制し、結果として外部依存に強いアーキテクチャを生みました。この前提がなければ、素直に商用 API を呼んで、それが落ちた日にすべてが止まっていたはずです。開発途中で学内サーバーでの運用許可が下りたことで、この構成はそのまま「継続コストのかからない運用」にも繋がっています。
2. 相手の運用のどこに手を入れないかを決める
企業ロゴの収集を自動化しないと決めたこと、スプレッドシートとの同期を一方向に限定したこと、「テンプレをコピーして入れる」という既存の作業モデルに合わせたこと。いずれも「できるのにやらなかった」判断です。
システムが解決すべきなのは相手の課題であって、相手の業務を作り変えることではない。何を作らないかを決めるのも設計のうちだと、ヒアリングを通して学びました。
3. 要件定義は最初に完成しない。だから軸を先に決める
第 2-2 節 / 第 1 回の合意——「細かい要件はたくさん変わる。しかしコアな体験は変えない」——が、このプロジェクトを最後まで支えました。実際、要件は大きく変わりました。テーブルは 7 個から 20 個に増え、設計になかった機能が 11 個増えています。
それでも迷子にならなかったのは、変わってよいものと変えてはいけないものを、最初に線引きしていたからです。変化に強い計画とは、詳細な計画ではなく、軸が明確な計画のことだと思っています。
第 XIV 部 付録
44. 用語集
| 用語 | 意味 |
|---|---|
| MIRAIS | 本システムの名称。MUDS & MIDS Innovative Research Activity Integrated System |
| MUDS | 武蔵野大学データサイエンス学部 |
| MIDS | 国際データサイエンス学部(今年度新設の通信制) |
| 未来創造発表会 | 学部の年次成果発表イベント |
| 3 部制 | 発表会の時間区分。1 部・2 部・3 部で発表者が入れ替わる |
| 学科賞 | ゼミから推薦される賞 |
| 企業賞 | 参加企業が選ぶ賞。学科賞の候補から「格上げ」される |
| 序列 | 参加企業の優先順位。運営が手動で管理し、企業賞の選出順を決める |
| マジックリンク | パスワードなしでログインできるトークン付き URL。企業向け |
| フェーズ | イベントの運用段階。準備中/提出受付中/投票期間中/アーカイブ |
| 推薦プール | 学科賞の候補集合。企業賞はここからのみ選出される |
| Hamilton 法 | 最大剰余方式。比例配分の小数部が大きい順に余りを配る配分手法 |
| 開発研究期間 / 開発期間 | キックオフ前の技術検証期間 / キックオフ後の実装期間 |
45. 技術スタック一覧
| 領域 | 採用技術 | 選定の要点 |
|---|---|---|
| バックエンド | Python / FastAPI / SQLAlchemy 2.0 / Pydantic v2 | 強い入力検証、OpenAPI 自動生成、チーム共通言語 |
| フロントエンド | TypeScript / Next.js 15 (App Router) / React 19 / SWR | 型による契約固定、サイトマップとの 1 対 1 対応 |
| スタイル | 自前デザイントークン(UI ライブラリ不使用) | 汎用テンプレ感の回避、テーマの動的注入 |
| データベース | PostgreSQL 16 | 遅延評価される一意制約、年度運用に必要な整合性 |
| 3D | React Three Fiber / 物理エンジン / マルチプレイ同期 / PDF レンダラ | 宣言的なジオメトリ構築、コリジョン、動的テクスチャ |
| LLM | 学内サーバー + 決定論的フォールバック | 学内資源での完結と、外部依存の障害耐性 |
| 認証 | Google ID Token 検証 + 自前 JWT | 外部 SaaS に依存しない前提と、非標準フローの自由度 |
| インフラ | Docker Compose / nginx / 学内 GPU サーバー | 学内資源の活用、単一ホストでの完結、継続コストなし |
| CI | GitHub Actions | ビルド検証とイメージビルドの疎通確認 |
46. 数値で見る MIRAIS
| 項目 | 値 |
|---|---|
| バックエンド | 約 6,700 行 / 17 ルータ / 13 サービス |
| フロントエンド | 約 5,300 行 / 20 ページ / 9 コンポーネント |
| 3D 会場 | 約 3,100 行 / 12 ファイル |
| データモデル | 20 テーブル |
| 定義した機能 | F-01〜F-12(+実装過程で追加 11 機能) |
| ロール | 4 + 未ログイン + 開発用 |
| 3D 会場のポスター面 | 36 面 |
| 建物ジオメトリのカテゴリ | 18 種類 |
| 埋め込みベクトルの次元 | 256(フォールバック時) |
| 表彰の推薦枠 | 30 名(ゼミ人数比で配分) |
| 稼働環境 | 学内 GPU サーバー(継続コストなし) |
47. おわりに
このプロジェクトを始めたきっかけは、率直に言えば「発表会のサイトを作りたい」という程度のものでした。それが最終的に、20 テーブルのデータモデルと 3 つのアプリケーションからなるシステムになったのは、関係者の方にお時間をいただいて話を伺えたからです。
とりわけ、運営を担当されている方から伺った業務の実際は、私たちの想像とはまるで違いました。想像で作っていたら、名札の面付けも、ブース案内紙も、表彰スライドのテンプレート方式も、企業の序列も、どれ一つ実装されなかったはずです。それらは全部、実際に困っている人の話の中にしかありませんでした。
今まで感じていた不便を、この代から感じなくなる。
誰かがやらなければ、来年も再来年も、同じ手作業が繰り返されます。私たちが作ろうとしたのは、ハッカソンの提出物ではなく、次の代に引き継がれるインフラです。だからこそ、この資料には「何を作ったか」だけでなく「なぜそう判断したか」を書きました。
コードは読めば分かります。判断の理由は、書き残さなければ消えます。
多田有里 武蔵野大学データサイエンス学部 3 年 2026 年 9 月
全 6 回、お読みいただきありがとうございました。要点だけを 1 本にまとめた要約版の設計ノートもあります。