social.smallbury.actor.trust

lexicon.pds.smallbury.social

Documentation

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).

main record

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).

Record Key literal:self Fixed literal value

Properties

createdAt string datetime Optional

An RFC 3339 formatted timestamp.

keyEpochs array of ref #keyEpoch Required

Ordered content-key epochs. Only the latest epoch (no endedAt) is used for new posts and comments. Earlier epochs remain for decrypting historical content.

pendingPairwiseSecrets array of ref #pendingPairwiseSecret Optional

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).

trusted array of ref #trustedEntry Required

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).

updatedAt string datetime Optional

An RFC 3339 formatted timestamp.

View raw schema
{
  "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)."
}
contentKeyWrap object

No description available.

Properties

slot string Required

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.

maxLength: 128 bytesminLength: 1 bytes
wrappedKey bytes Required

This epoch's symmetric content encryption key, encrypted to the recipient's encryptionPublicKey from social.smallbury.actor.profile.

maxLength: 512
View raw schema
{
  "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."
    }
  }
}
keyEpoch object

No description available.

Properties

contentKeyWraps array of ref#contentKeyWrap Required

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.

endedAt string datetime Optional

Set when a newer epoch is created. Omitted on the current epoch.

keyEpochId string Required

Stable identifier for this epoch (e.g. sequential "0", "1", …). Referenced by encrypted posts and comments.

maxLength: 64 bytesminLength: 1 bytes
startedAt string datetime Required

An RFC 3339 formatted timestamp.

View raw schema
{
  "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."
    }
  }
}
pendingPairwiseSecret object

No description available.

Properties

inviteId string Optional

Optional link to social.smallbury.graph.invite on the initiator's repo.

maxLength: 128 bytesminLength: 1 bytes
peerDid string did Required

The contact who should decrypt wrappedSecret.

wrappedSecret bytes Required

32-byte pairwiseTrustSecret for this pair, encrypted to peerDid's encryptionPublicKey from social.smallbury.actor.profile.

maxLength: 512
View raw schema
{
  "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."
    }
  }
}
trustedEntry object

No description available.

Properties

did string did Required

A decentralized identifier (DID).

since string datetime Required

When this actor added the contact to trusted.

View raw schema
{
  "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."
    }
  }
}

Lexicon Garden

@