react-native-matrix-crypto
    Preparing search index...

    Interface EventEnvelope

    Typed envelope for an encrypted or decrypted event.

    interface EventEnvelope {
        algorithm: CryptoAlgorithm;
        ciphertext: Uint8Array;
        eventType: string;
        scope: CryptoScopeId;
        sender: string;
        senderVerification?: SenderVerification;
    }
    Index
    algorithm: CryptoAlgorithm

    From encryptEvent, the group-session algorithm this build used.

    From decryptEvent, spec section 7.1: this library decrypts events, it does not authenticate their senders. This value is read from the incoming event, not independently verified, and is unauthenticated transport metadata — treat it accordingly, not as a claim this library has confirmed. This carried a milestone twice, and both have now passed without the property changing: cross-signing has landed and this value is still read from the incoming event and never re-derived. It is not scoped to a milestone at all, so there is no version to wait for. What cross-signing adds is EventEnvelope.senderVerification, a separate value, and not a promotion of this one.

    ciphertext: Uint8Array

    Do not trust this field's name on the decrypt path.

    From encryptEvent, this is the wire ciphertext: send it as the content of your m.room.encrypted event.

    From decryptEvent, this is the plaintext that call just recovered. One type describes both directions, so the name comes from the direction that produced it first and is wrong for the other. There is no second field to read instead.

    The consequence is a handling rule, not a naming quibble. Everything a product does to plaintext, it must do to this value on the decrypt path: do not log it, do not persist it unencrypted, do not put it in a crash report or an analytics event, and do not let it into a console statement written while debugging. The Rust core hand-writes a redacting Debug for exactly this reason, and it cannot reach across this boundary to do the same for JavaScript.

    eventType: string
    sender: string

    Fully qualified @user:server, verbatim. Spec section 10.

    From encryptEvent, this device's own identity — authenticated by definition.

    From decryptEvent, spec section 7.1: this library decrypts events, it does not authenticate their senders. This is the sender the homeserver delivered on the outer, not-yet-decrypted event, not a value this library independently confirmed, and it is unauthenticated transport metadata. Verifying the sending device does not change that, by string or by scanned code; cross-signing is what would, and it has landed without moving this field, which is the point senderVerification forty lines below makes at length. This said "and it is M4", naming a milestone as a thing still to come. A product that reads it as the cryptographic sender of a successfully decrypted event has assumed something this library does not provide, and that assumption is the shape impersonation takes. Read it together with senderVerification below, which is what says how much of a claim it is -- and note that 'mismatched_sender' is exactly the case where this string is a lie decryption did not catch.

    senderVerification?: SenderVerification

    What this library knew about the sender of this event at the moment it decrypted it -- see SenderVerification, including which of its values cannot arrive here yet and why completing a verification does not change this one. That said "which three of its values" until M4, and the count is the kind of detail that goes stale in silence, so there is no count here now.

    Present on every successful decryptEvent. Absent from encryptEvent. The same one-type-two-directions caveat algorithm and sender above each carry, in its strongest form: those two hold a real value in both directions, and this one is discarded on the encrypt path rather than missing from it. The layer underneath does receive a value when it encrypts, and that value is 'verified' -- upstream reporting on this device's own keys, which is a statement about a device and is true of a machine that has never verified anything. It is dropped rather than forwarded onto the field a decrypted event reads. This used to add "the one word this release cannot honestly attach to an event", which stopped being true when the core learned to cross-sign; the asymmetry it was pointing at is real and survives the correction. On the encrypt path the word costs nothing and means nothing. On the decrypt path it costs the whole seven-step chain, which is why forwarding the free one would be a fabrication rather than a shortcut. Absent here means "this question was not asked of this event".

    It is a snapshot, and it can go stale. Upstream defines it as the state of the sending device at the time of decryption: it "may change in the future if a device gets verified or deleted", and callers who persist it are told to mark it dirty when a device change is received down the sync. That obligation is yours once you hold this value. The trigger is already in your hands -- device_lists.changed on the /sync response you pass to receiveSyncChanges -- and nothing in this library re-derives a stored value for you. A record that looks static is not the same as a fact that stays true.

    Going stale is the only direction it moves. It does not improve. Verifying someone changes what their next messages say, not what their old ones said. The value belongs to the session the event was encrypted with, it is computed once when that session's key arrives, and nothing recomputes it for a session whose sender was already identified: so a message decrypted while its sender was merely cross-signed keeps reading 'unverified_identity' until that session is replaced, however thoroughly you verify them afterwards. Design a badge that says "from here on" rather than one that backfills a conversation, because the backfill will not arrive. Asserted end to end, not inferred: the core's tests/verified_sender.rs::history_does_not_improve_when_the_sender_is_verified_later decrypts one event before a full verification and the same event after it, and then a message on a session created afterwards to show that the verification really did take effect.