Skip to content

Identity

VirMesh の player identifier、公開鍵、署名入力の現在の扱いをまとめます。

ここで重要なのは、実装が公開鍵文字列をそのまま player id に埋め込む点です。

Player identifier

player identifier の形式は次です。

text
medi:player:<scheme>:<public key>

現在の既定 registry で有効な schemeed25519 だけです。

private action と me.virmesh.handle.updateHandle は、この from または payload.id を検証に使います。 me.virmesh.account.disableAccountpayload.accountId を検証に使います。

Public key formats

ed25519 では次の public key 形式を受け付けます。

Input formNotes
PEM public keyBEGIN PUBLIC KEY を含む文字列
raw 32-byte keyhex / base64 / base64url
SPKI DERhex / base64 / base64url

binary 系の入力は prefix 付きでも送れます。

text
hex:...
base64:...
base64url:...

prefix なしでも hex、base64、base64url を推定します。

Signature formats

署名も同じ flexible binary decoder を通ります。

Input formNotes
hexprefix 付きまたはなし
base64prefix 付きまたはなし
base64urlprefix 付きまたはなし

ed25519 署名は decode 後にちょうど 64 bytes でなければなりません。

Account id derivation

me.virmesh.ps.createAccountaccount.id は、検証後に次の式で生成されます。

text
medi:player:<keyType>:<publicKey>

ここで使われる <publicKey> は正規化後の bytes ではなく、リクエストに入っていた文字列そのものです。

そのためクライアントは 1 つの公開鍵表現を決めて固定する必要があります。たとえば同じ鍵を raw base64 と PEM の両方で使うと、実装上は別の player id になります。

Handle identity rules

ハンドル record は次の識別子群を持ちます。

json
{
  "id": "medi:player:ed25519:base64-public-key",
  "playerServer": "https://ps.example.com/",
  "primaryHandle": "[email protected]",
  "secondaryHandles": ["[email protected]"],
  "updated_at": 1711800000
}

ハンドルの比較と一意性判定は lower-case 正規化で行われます。[email protected][email protected] は同一ハンドルとして扱われます。

レスポンスは保存された値をそのまま返すので、比較が case-insensitive でも表示上の大文字小文字は維持されます。

Public profile model

公開プロフィールは、handle record と profile module 群を組み合わせて構成します。

json
{
  "handle": {
    "record": {
      "id": "medi:player:ed25519:base64-public-key",
      "primaryHandle": "[email protected]",
      "secondaryHandles": ["[email protected]"],
      "playerServer": "https://ps.example.com/",
      "updated_at": 1770000100
    },
    "signature": "base64-signature-by-player-for-handle-record"
  },
  "modules": {
    "profile+me.virmesh.player.displayName": {
      "payload": {
        "module": "profile+me.virmesh.player.displayName",
        "id": "medi:player:ed25519:base64-public-key",
        "displayName": "Alice",
        "updated_at": 1770000200
      },
      "signature": "base64-signature-by-player-for-display-name-module"
    },
    "profile+me.virmesh.player.card": {
      "payload": {
        "module": "profile+me.virmesh.player.card",
        "id": "medi:player:ed25519:base64-public-key",
        "bio": "VR world builder",
        "updated_at": 1770000300
      },
      "signature": "base64-signature-by-player-for-profile-card-module"
    }
  }
}

me.virmesh.player.resolveProfile は、この公開プロフィールを handlemodules に分けて返します。 verifier は payload.handle.recordpayload.handle.signature で検証し、 各 payload.modules.*.payload を対応する signature で検証します。 各 payload 内の id から公開鍵を導出し、すべて同じ player を指しているときだけ 1 つの公開プロフィールとして扱います。

v1 では必須 module profile+me.virmesh.player.displayNameprimaryHandle の両方が揃っている場合だけ公開プロフィールとして解決されます。 profile+me.virmesh.player.card は optional module で、bioimage を持つときだけ返ります。

Disabled account tombstones

me.virmesh.account.disableAccount が成功すると、対象 player id は tombstone 化されます。

tombstone 化済み account は v1 で irreversible です。以後は次の扱いになります。

Signing targets

現在の署名対象は endpoint によって異なります。

SurfaceSigned data
generic private actioncanonical JSON of { action, from, payload }
me.virmesh.account.disableAccountcanonical JSON of payload
me.virmesh.ps.createAccountcanonical JSON of payload.user
me.virmesh.player.resolveProfile response payload.handle.signaturecanonical JSON of payload.handle.record
me.virmesh.player.resolveProfile response payload.modules.*.signaturecanonical JSON of 対応する payload.modules.*.payload
me.virmesh.player.updateProfilecanonical JSON of patch 適用後に保存される module payload
me.virmesh.handle.updateHandlecanonical JSON of payload

Next steps

  • transport と canonical JSON は Transport を参照してください。
  • 公開されている action の具体的な request/response は Actions を参照してください。
  • profile module 更新、画像 upload、公開プロフィール取得は me.virmesh.player を参照してください。
  • ハンドル更新の version rule は me.virmesh.handle を参照してください。