Skip to content
Ravisign

Audit trail

The audit trail is the record of everything that happens to an envelope, from the moment it is created until completion. It is the main evidence of an advanced electronic signature: it shows who did what, when, from where and with which identity confirmation.

What is recorded#

Event When it happens
envelope_criado The envelope was created (panel, API or ChatISP)
envelope_enviado The envelope was sent for signature
notificacao_enviada An invitation was delivered to a signer
link_aberto The signer opened the personal link
documento_visualizado The signer opened the document
otp_enviado A confirmation code was generated and sent
otp_validado The signer entered the correct code
otp_falhou The signer entered a wrong code
assinado The signer signed
recusado The signer declined, with the reason
lembrete_enviado A reminder was sent
expirado The deadline passed without all signatures
cancelado The sender canceled the envelope, with the reason
documento_final_gerado The final copy was assembled and signed by the platform
concluido The envelope was completed
conclusao_retomada Completion was resumed manually after a failure
webhook_entregue An event notification was delivered to the account's system
ancoragem The hash of the day was sealed with a timestamp (see below)

Each event stores the date and time in UTC with microseconds, the IP and browser of whoever acted (when a person is acting), the location when the signer consented, and data specific to the event type (for example, the code channel or the hash of the final copy).

Note the trail never stores name, email address, phone number, CPF, selfie or identity document. It refers to the signer only by an internal identifier; personal data is kept separately and encrypted.

Hash chaining#

The events form a chain: the hash of each event is calculated from the content of the event and the hash of the previous event. Changing, inserting or deleting any older record changes all the following hashes, and the break shows up in verification. In addition, the records are append-only: no path in the system changes or deletes an event.

The chain is single for the whole platform, spanning all accounts. This means that not even rewriting the entire trail of an envelope would go unnoticed: it would break the sequence of the events of all the other envelopes recorded afterwards.

The hash of the last event of each envelope is printed on the manifest of the final copy and shown in the public validator.

Formula#

For anyone who needs to verify the trail independently (a forensic expert, for example), the formula is public:

Text
hash = SHA-256( hash_anterior + "\n" + json_canonico(registro) )

Where:

  • hash_anterior is the hash of the previous event in the chain, as 64 lowercase hexadecimal characters. The first event of the platform uses 64 zeros.
  • "\n" is a line break (a single byte 0x0A).
  • registro is the object with exactly these fields: conta_id, envelope_id, signatario_id, tipo, dados, ip, user_agent, geo and ocorrido_em. The sequential identifier of the event itself is not part of the calculation.
  • The result is written in lowercase hexadecimal.

Canonical JSON#

json_canonico always produces the same text for the same content:

  1. Keys are sorted alphabetically at all levels (including inside dados and geo).
  2. No spaces or line breaks between elements.
  3. Accented characters and other Unicode characters stay as they are (they do not become \u00e7), and the slash / is not escaped.
  4. Integers are output as integers (42, not "42").
  5. A missing or empty field is output as null.
  6. ocorrido_em is a UTC text in the format AAAA-MM-DD HH:MM:SS.uuuuuu (with six digits of microseconds).

Verification example#

The snippet below recalculates the hash of an event from the previous hash and the record fields:

PHP
<?php
function ordenar($valor) {
    if (!is_array($valor)) return $valor;
    if (array_is_list($valor)) return array_map('ordenar', $valor);
    ksort($valor, SORT_STRING);
    return array_map('ordenar', $valor);
}

function hashEvento(string $hashAnterior, array $registro): string {
    $canonico = json_encode(ordenar([
        'conta_id'      => $registro['conta_id'],
        'envelope_id'   => $registro['envelope_id'],
        'signatario_id' => $registro['signatario_id'],
        'tipo'          => $registro['tipo'],
        'dados'         => $registro['dados'],
        'ip'            => $registro['ip'],
        'user_agent'    => $registro['user_agent'],
        'geo'           => $registro['geo'],
        'ocorrido_em'   => $registro['ocorrido_em'],
    ]), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    return hash('sha256', $hashAnterior . "\n" . $canonico);
}

To verify a sequence, start from the hash_anterior of the first event in the range, recalculate each event in order and compare it with the recorded hash. The first difference points exactly to the altered record.

Daily anchoring#

Once a day, Ravisign takes the hash of the last event of the previous day and obtains an ICP-Brasil timestamp for it. The timestamp proves, through an independent authority, that this hash (and therefore the entire chain up to it) already existed on that date. The timestamp itself is recorded in the trail as an ancoragem event.

As a result, even if someone with full access to the platform tried to recalculate the entire chain from a given point, the hashes already anchored on previous days would no longer match the timestamps issued.

Where to view the trail#

  • Panel: in the envelope detail view, in the History section, with the IP and hash of each event.
  • API: the envelopes/eventos action returns the events in order with the hash of each one. For privacy, the API does not return personal data, IP or browser. See Envelopes in the API.
  • Public validator: shows the hash of the last event, the same one printed on the manifest.

Tip for a forensic examination that requires recalculating the chain with all fields, the account holder can request the complete records of the envelope from Ravi Systems support.

Retention#

The trail is evidence: it is kept even when the documents and personal data of an account are purged, for the period required for the regular exercise of rights. See Privacy and security.

Did not find what you were looking for?

Contact Ravi Systems support at the e-mail below.

contato@ravisystems.com.br