Skip to content

Evidence and audit

client.evidence, the Evidence namespace, lets a person entitled to Export produce a signed, self-contained record. The record covers the tenant, a dataset or one subject. Anyone can check the record later, without an enrolled device. SealdHealthcare.verifyPack runs the check offline, against the trust root built into the SDK. A customer’s auditor needs no device certificate (card) and no live connection to trust a pack.

Exporting and resolving refs

The samples use the allowed helper from Access decisions.

const pack = await allowed(await client.evidence.export({ tenant: true }, { from, to }));
const byDataset = await allowed(await client.evidence.export({ datasets: ['encounters'] }, { from, to }));
// an accounting of disclosures: the same export, scoped to one subject
const bySubject = await allowed(await client.evidence.export({ subject: medicalRecordNumber }, { from, to }));
if (pack) await writeFile(`evidence-${pack.packId}.seald`, await pack.bytes());
// an ExportedPack: { packId, eventId, events, bytes() }
const epochsInPeriod = await client.evidence.epochs({ from, to });
for (const epoch of epochsInPeriod) {
const ref = await client.evidence.subjectRef(medicalRecordNumber, epoch); // { ref, epoch }
const personRef = await client.evidence.personRef(alice, epoch);
}

An accounting of disclosures is the same export, scoped with subject instead of datasets or tenant. The SDK tokenizes the customer’s own identifier on the device, per the epoch it falls in. The Seald Healthcare Cloud never sees it. To resolve a Ref back to a person or a subject, make the same ref for a candidate. Use subjectRef or personRef at the pack’s epoch, then compare the two refs.

Verifying a pack offline

const verification = await sealdhealthcare.verifyPack(await readFile('evidence-3f1c.sealdhealthcare'));
if (!verification.verified) return render(verification.failure); // the first failure, in the order the checks run
renderEvents(verification.events, verification.controlStatus);
// { verified, failure?, tenantId, period, scope, events, policyVersions, checkpoints, controlStatus }

PackVerification.failure, when present, names the first check that failed, in the order the checks run: chain, checkpoint, identity-authority, card, manifest, pack-manifest or policy-version. policyVersions carries every policy version in force over the period. checkpoints carries the timestamp authority checkpoints that fix the chain in time. controlStatus carries the tenant’s control status for the period.

PackEvent fields

FieldHolds
atWhen the event happened
actorA Ref: the acting person, tokenized, never a name
organizationThe actor’s organization as the identity provider named it
deviceThe RecipientId of the device that made the call
actionThe audit action, such as View or Export
subjectA Ref to the record’s subject, when the object has one
policyVersionThe versionId of the policy version that decided the event
outcomeallow, deny or challenge
riskScoreA relative measure of how unusual the event was, for triage, never a decision the SDK acts on
hashThe event’s own hash, chained to the one before it

What the SDK does for you

  • Sends the exporter’s own manifest over every event a pack covers. A pack is then signed evidence of what was exported and by whom.
  • Tokenizes a subject scope’s identifier on the device, per epoch, and never sends the identifier itself.
  • Checks a pack against the trust root built into the SDK and the timestamp authorities’ roots. It needs no key, session or tenant enrollment.
  • Reports the first failed check, not every downstream effect of it. verification.failure always points at the actual break in the chain.

Decisions and errors you may see

Outcome or ErrorCodeWhenWhat to do
deny on exportThe caller does not hold Export for the scope asked.Ask a person entitled to Export that scope.
failure.check is chain or checkpointThe pack’s hash chain or its timestamp checkpoints do not verify.Treat the pack as untrusted. Ask for a fresh export.
failure.check is card or identity-authorityAn actor’s card or the tenant’s identity authority failed its check against the trust root built into the SDK.Treat the pack as untrusted. Contact support.
failure.check is policy-versionAn event names a policy version the pack cannot verify.Treat the pack as untrusted. Contact support.

Next