# Verifying Events

EventSourcingDB gives every event a hash, which covers its metadata, its data, and the hash of the event before it. If the database runs with a signing key, it also signs every event it hands out. The store checks the hash of every event it reads, without being asked to.

To check the signatures as well, call `signature_verification` on the builder of the store, with the verification key of the database:

```rust
let store = Store::builder(client, "https://library.eventsourcingdb.io")
  .signature_verification(verification_key)
  .build();
```

The verification key is a `VerifyingKey` of the `ed25519_dalek` crate, which the kit brings along as `architecturekit::ed25519_dalek`, in the version the client SDK verifies signatures with. To read it from a PEM file, turn on the feature `pem` of the kit:

```shell
cargo add architecturekit --features pem
```

Then read the file, and call `VerifyingKey::from_public_key_pem` of the trait `DecodePublicKey`, which fails for a PEM that holds no Ed25519 public key:

```rust
use architecturekit::ed25519_dalek::{VerifyingKey, pkcs8::DecodePublicKey};

let pem = std::fs::read_to_string("verification-key.pem")?;
let verification_key = VerifyingKey::from_public_key_pem(&pem)?;
```

The store checks every event it reads, for `execute`, `load`, and `read` as well as for every kind of projection, and it does so before any upcaster sees the event. The events that `execute` has just written are not checked, since they are not read. If an event fails its verification, reading fails with `Permanent::Unverified`, a permanent failure of its own, since it may point to a security incident rather than a mistake (see **[Handling Errors](/docs/architecturekit/rust/handling-errors)**). A projection stops rather than skipping the event.

The two checks prove different things:

- A matching hash proves that an event is what was written. It proves no more than that, since whoever can change the stored data can compute a new hash as well.
- A matching signature proves that an event comes from a database that holds the signing key. The database signs events when handing them out, so the signature guards the way from the database to your application, but not the stored data itself.

The hashes are enough wherever reading is under your control. Check the signatures as well where events cross a trust boundary, for example when reading from a database that another organization runs. For details, see **[Verifying Event Signatures](/docs/eventsourcingdb/verifying-event-signatures)**.

*Note that checking a hash takes about a microsecond per event, so there is rarely a reason to turn it off. If there is one, call `without_hash_verification` on the builder. It can not be combined with `signature_verification`, since checking a signature includes checking the hash, so `build` panics if it gets both. Checking a signature, on the other hand, takes some tens of microseconds per event, which adds up when a projection catches up on millions of events.*

*Note that the database signs with the key it has at the moment, so after the signing key is rotated, the store needs the new verification key.*

*Note that neither check detects a history that has been rewritten as a whole. For that, audit the chain of hashes (see **[Auditing the Event Store](/docs/eventsourcingdb/auditing-the-event-store)**).*
