···93939494 defp validate_record(event) do
9595 with :ok <- validate_lexicon(event.record),
9696- :ok <- validate_rkey_matches_subject(event.rkey, event.record["subject"]) do
9696+ :ok <- validate_rkey_matches_subject(event.rkey, event.record["subject"]),
9797+ :ok <- validate_not_self_vouch(event.did, event.record["subject"]) do
9798 :ok
9899 end
99100 end
···102103 case Atvouch.Lexicons.Vouch.main(record) do
103104 {:ok, _} -> :ok
104105 {:error, errors} -> {:error, "lexicon validation failed: #{inspect(errors)}"}
106106+ end
107107+ end
108108+109109+ defp validate_not_self_vouch(creator_did, subject) do
110110+ if creator_did != subject do
111111+ :ok
112112+ else
113113+ {:error, "subject must not be the same as creator did '#{creator_did}'"}
105114 end
106115 end
107116
+44
appview/test/atvouch/tap_handler_test.exs
···254254 # Also no vouch with the subject as rkey
255255 at_uri2 = "at://#{creator_did}/dev.atvouch.graph.vouch/#{target_did}"
256256 assert Atvouch.Vouch.one(at_uri2) == nil
257257+258258+ # No identities should have been created either
259259+ assert Atvouch.Identity.one(creator_did) == nil
260260+ assert Atvouch.Identity.one(target_did) == nil
257261 end
258262259263 test "rejects record with invalid DID in subject", %{port: port} do
···374378375379 # No vouch created
376380 at_uri = "at://#{creator_did}/dev.atvouch.graph.vouch/some-rkey"
381381+ assert Atvouch.Vouch.one(at_uri) == nil
382382+ end
383383+384384+ test "rejects record where subject equals creator did (self-vouch)", %{port: port} do
385385+ {:ok, _pid} =
386386+ Atvouch.Tap.Socket.start_link(
387387+ uri: "ws://localhost:#{port}/channel",
388388+ handler: Atvouch.TapHandler,
389389+ password: "123",
390390+ name: :"tap_handler_self_vouch_test_#{port}"
391391+ )
392392+393393+ assert_receive {:ws_connected, ws_pid}, 5_000
394394+395395+ self_did = "did:plc:cpzv5kdrtinsnj5rsblsttz6"
396396+397397+ Atvouch.Test.FakeTapServer.send_event(ws_pid, %{
398398+ "id" => 504,
399399+ "type" => "record",
400400+ "record" => %{
401401+ "action" => "create",
402402+ "did" => self_did,
403403+ "rev" => "3mgmqjki6sz2n",
404404+ "collection" => "dev.atvouch.graph.vouch",
405405+ "rkey" => self_did,
406406+ "record" => %{
407407+ "$type" => "dev.atvouch.graph.vouch",
408408+ "createdAt" => "2026-03-09T10:53:26.922Z",
409409+ "subject" => self_did
410410+ },
411411+ "cid" => "bafyreig2uvo5annaomcmrjfrwyshnjannfrr2xje5txnsyuk7l4o2tdmju",
412412+ "live" => false
413413+ }
414414+ })
415415+416416+ # Should still be ACKed
417417+ assert_receive {:ws_message, %{"type" => "ack", "id" => 504}}, 5_000
418418+419419+ # No vouch created
420420+ at_uri = "at://#{self_did}/dev.atvouch.graph.vouch/#{self_did}"
377421 assert Atvouch.Vouch.one(at_uri) == nil
378422 end
379423