2026 / 03
NOEMA — 内省ライフシステム
成果独自の認証モデルを持つ非公開の記録システムを構築しました。記録はアカウント単位で分離され、パスワード復旧にメールサーバーを必要とせず、データベースはこのアプリ専用です。
概要
非公開の記録・内省システム。日々の記録、長期のマイルストーンとライフフェーズを扱い、各アカウントの記録は、個人の最も私的なデータのために設計した認証モデルの背後で完全に分離されています。
背景
その日に実際に起きたことを記録し、数ヶ月単位で振り返る場所。ただしそれは、書く人が「他に誰が読めるのか」を一切気にしなくていい場合にのみ成立します。この要求が認証モデルを決めました——セルフサービスのアカウント、意図的にログインの第二要素にはしていない回復キー、任意のパスキー、そしてすべての記録がアカウント単位で分離されています。
システム
recovery: self-set secret · no mail server · no operator overrideOnly the person can recover the account.
Including me. That is the point.課題
メールサーバーを持たないマルチユーザーの記録システムには、パスワード再設定の経路が存在しません。用意しなければ、パスワードを忘れた時点でシステム上もっとも私的なデータが永久に失われます。かといって一般的な再設定フローを足せば、その復旧経路こそが、守るべきデータへの最短の侵入口になります。
調査
最初の仮説
管理者を Maintainer として追加できると考えました。
復旧は、登録時に本人が書く二つ目の秘密に依拠します。プロンプトと答えは本人が自由に決め、ログインパスワードとは独立にハッシュ化して保管します。併せて保存できるのは「ヒント」だけで、本人に見せ返すのもこのヒントに限られます——答えそのものはハッシュとしてのみ存在し、表示もメール送信もされず、運用者が復元することもできません。パスワード入力自体をやめたい人のために、パスキーも併用できます。
証拠
merge_request.check_mergeability
# poll until merge_status permits mergeGitLab 18 は Organization をまたぐメンバー追加を拒否し、保護された main へマージできるのは CI ボットだけでした。
判断
ボット所有の Merge Request をスクリプトで作成し、非同期のマージ可否判定をポーリングしました。
結果
メールサーバーもサポート窓口も介さないアカウント復旧を実現しました。アカウントを復旧できるのは、二つ目の秘密を設定した本人だけです。記録はアカウント単位で分離され、共有クラスターDBではなくこのアプリ専用の Postgres インスタンス上に置かれています。
次に変えること
現在の制約: これは当面の移行制約を解決したものであり、望ましい長期的な運用モデルとして扱ってはいません。スクリプト経路はクラスター内の管理コンソールを通り、対象はこのリポジトリ 1 つに限定され、Merge Request 自体が監査記録として残ります——ボットが作成した MR であってもレビュー可能な成果物であり、無言の直接 push ではありません。
次の一手: Organization のメンバーシップ仕様により管理者が通常の Maintainer 権限を持てるようになった時点で、この特殊経路は完全に削除します。回避策は、それを生んだ制約より長く残すべきではありません。