social.smallbury.actor.trust

lexicon.pds.smallbury.social

{
  "id": "social.smallbury.actor.trust",
  "defs": {
    "main": {
      "key": "literal:self",
      "type": "record",
      "record": {
        "type": "object",
        "required": [
          "trusted",
          "keyEpochs"
        ],
        "properties": {
          "trusted": {
            "type": "array",
            "items": {
              "ref": "#trustedEntry",
              "type": "ref"
            },
            "description": "DIDs this actor trusts. Cleartext for AppView; does not by itself reveal per-post subset audiences. Listing a DID here may occur before they reciprocate (pre-emptive trust)."
          },
          "createdAt": {
            "type": "string",
            "format": "datetime"
          },
          "keyEpochs": {
            "type": "array",
            "items": {
              "ref": "#keyEpoch",
              "type": "ref"
            },
            "description": "Ordered content-key epochs. Only the latest epoch (no endedAt) is used for new posts and comments. Earlier epochs remain for decrypting historical content."
          },
          "updatedAt": {
            "type": "string",
            "format": "datetime"
          },
          "pendingPairwiseSecrets": {
            "type": "array",
            "items": {
              "ref": "#pendingPairwiseSecret",
              "type": "ref"
            },
            "description": "Temporary delivery of a pairwise trust secret to a peer during establishment (encrypted to the peer's profile encryptionPublicKey). Removed after the peer has retrieved and acknowledged. Used when the acceptor generates the secret (new-user path) or when the initiator pre-delivers it (existing-user path)."
          }
        }
      },
      "description": "Contacts this actor trusts, content-key epochs for E2EE, and optional in-flight pairwise-secret delivery during trust establishment. Trusted DIDs are cleartext for AppView indexing. Mutual trust is derived: A trusts B and B trusts A (each side's trusted array). Feed visibility requires mutual trust on both records. Per-epoch content keys use opaque slots (see #contentKeyWrap)."
    },
    "keyEpoch": {
      "type": "object",
      "required": [
        "keyEpochId",
        "startedAt",
        "contentKeyWraps"
      ],
      "properties": {
        "endedAt": {
          "type": "string",
          "format": "datetime",
          "description": "Set when a newer epoch is created. Omitted on the current epoch."
        },
        "startedAt": {
          "type": "string",
          "format": "datetime"
        },
        "keyEpochId": {
          "type": "string",
          "maxLength": 64,
          "minLength": 1,
          "description": "Stable identifier for this epoch (e.g. sequential \"0\", \"1\", …). Referenced by encrypted posts and comments."
        },
        "contentKeyWraps": {
          "type": "array",
          "items": {
            "ref": "#contentKeyWrap",
            "type": "ref"
          },
          "description": "One wrapped copy of this epoch's symmetric content key per intended recipient. Opaque slots so wraps are not labeled with recipient DIDs. May include dummy wraps."
        }
      }
    },
    "trustedEntry": {
      "type": "object",
      "required": [
        "did",
        "since"
      ],
      "properties": {
        "did": {
          "type": "string",
          "format": "did"
        },
        "since": {
          "type": "string",
          "format": "datetime",
          "description": "When this actor added the contact to trusted."
        }
      }
    },
    "contentKeyWrap": {
      "type": "object",
      "required": [
        "slot",
        "wrappedKey"
      ],
      "properties": {
        "slot": {
          "type": "string",
          "maxLength": 128,
          "minLength": 1,
          "description": "Opaque lookup key. Recipients compute slot = Base64URL(HMAC-SHA256(pairwiseTrustSecret, keyEpochId)). pairwiseTrustSecret is agreed at trust establishment and stored only on the two clients—not published on the PDS."
        },
        "wrappedKey": {
          "type": "bytes",
          "maxLength": 512,
          "description": "This epoch's symmetric content encryption key, encrypted to the recipient's encryptionPublicKey from social.smallbury.actor.profile."
        }
      }
    },
    "pendingPairwiseSecret": {
      "type": "object",
      "required": [
        "peerDid",
        "wrappedSecret"
      ],
      "properties": {
        "peerDid": {
          "type": "string",
          "format": "did",
          "description": "The contact who should decrypt wrappedSecret."
        },
        "inviteId": {
          "type": "string",
          "maxLength": 128,
          "minLength": 1,
          "description": "Optional link to social.smallbury.graph.invite on the initiator's repo."
        },
        "wrappedSecret": {
          "type": "bytes",
          "maxLength": 512,
          "description": "32-byte pairwiseTrustSecret for this pair, encrypted to peerDid's encryptionPublicKey from social.smallbury.actor.profile."
        }
      }
    }
  },
  "$type": "com.atproto.lexicon.schema",
  "lexicon": 1
}

Validate Record

Validate a record against social.smallbury.actor.trust

Validation Options
Treat any remaining unresolved references as valid

Metadata

DID
did:plc:wnagcp6h73nxmvmwid2xxukx
CID
bafyreiawqhom36swihdvoyluhngbufdrxznidyhozcbmciqkjuvamjd3hy
Indexed At
2026-06-26 11:59 UTC
AT-URI
at://did:plc:wnagcp6h73nxmvmwid2xxukx/com.atproto.lexicon.schema/social.smallbury.actor.trust

Lexicon Garden

@