壊さないもの¶
arkhe の設計は、その多くが拒否でできている。すべては 1 つの約束から出ている—— 一度配った名前が、別のものを指すようになることはない。
これらは方針文書ではなくコードで守っている。人が覚えていることに頼る規則は、 いつか破られる。たいていは深夜に、別の何かを直している最中に。
ARK は削除しない¶
行を消すと解決が止まる。解決しなくなった識別子は、壊れた識別子である。Ark は
ORM の層で削除を拒む。
対象が本当に失われたときは tombstone にする。識別子と記述は残り、到達性だけが落ちる。
以後リゾルバは、転送ではなく記述を返す。これは FAIR A2——データが利用できなくなっても メタデータは参照できるべき——そのものである。
名前空間も削除しない¶
shoulder を消すと、乱数割当が既に使われた文字列を再び当てうる。消さずに
status=retired にする。既存の ARK は解決し続ける。
とくに delegated の shoulder は消せない——外部の minter が、この台帳の知らない名前を
その中に作っている可能性がある。
採番が更新に化けない¶
arklet で最重大の欠陥がこれだった。 主キーの衝突が save() に吸収されて
UPDATE に化け、既存の ARK の向き先を黙って書き換えていた。arkhe は採番を
1 か所の経路に閉じ、衝突は失敗させ、数えて、別の名前で採り直す。
衝突回数を握りつぶさず返しているのは、衝突率の上昇が名前空間の枯渇を知らせる唯一の 合図だから。
到達範囲はリクエストで広がらない¶
authority / manager_id / shoulder_id / allowed_scopes は登録の属性である。
リクエストは shoulder を名指すことはできるが、答えは常に「それが主体の範囲の内側か
どうか」だけ。
トークンは自分が運ぶ scope を狭めることはできる。増やすことはできない。
人と機械は別の型¶
machine の主体は鍵で認証し、外部ログインでは名乗れない。person の主体は身元を
外部が保証し、API キーを持てない。
前段のプロキシを正しく置けばなりすましは防げる。だが設定 1 つの誤りが「一括投入 バッチとして全件書き換え」に化けるのは、放置してよい鋭さではない。
記録は対象より長く残る¶
AuditEvent は他の表と外部キーで結んでいない。記録は対象が消えても残るべきもので、
参照整合性で縛ると逆の力が働く——「消せないから記録も消す」が楽になってしまう。
NAAN 以上に届く操作は全件記録する。届く範囲が広いほど、後から誰が何をしたかを 辿れる必要が高いから。
どこで守っているか¶
| 不変条件 | 実装 |
|---|---|
| ARK と shoulder の削除禁止 | db/models.py の before_delete |
retired から戻せない |
domain/admin_ops.py の遷移表 |
| 採番が更新に化けない | domain/minting.py の単一 INSERT 経路 |
| 到達範囲は登録の属性 | domain/authz.py(判断は 1 か所) |
| 人と機械の別 | auth/apikey.py と auth/login.py の subject_type 検査 |
いずれも、外すと落ちるテストが付いている。tests/test_models.py と
tests/test_authz.py を参照。