Attest
Attest replaces "he said / she said" home-service disputes with a signed, self-verifying evidence record, built on the Ring Partner API — what the devices observed, what the worker and the household each reported, what a coordinator concluded.
Records, not verdicts — the evidence gets a verdict; nobody's story does. Not attendance tracking, not EVV, not surveillance: the record proves it wasn't quietly rewritten — it never claims to know who was at the door.
New York's comptroller found $14.5B paid against 82M personal-care visits with no matching record; Ohio's auditor found 34% of electronic-visit-verification entries manually adjusted — invisibly. Editable records are the problem; Attest makes them tamper-evident — and private home services (cleaners, caregivers, contractors) have no EVV mandate and no shared record at all. That's the gap — and Ring's own throw-away-the-key move makes independent attestation more valuable, not less: when the platform can't see the video either, the signed record is the shared truth everyone can hold.
90 minutes scheduled. The camera observed 65.25. The worker disputes the record: "I dispute this record — I arrived before the first observation shown." The household first wrote: "My mother was home all morning and says the doorbell never rang — nobody came to the door before ten." — then the same account contradicted itself: "I was home that afternoon; I heard the doorbell a little after six and saw someone at the door. I can't say how long she stayed." Every version, verbatim and signed — including a garbled re-send — in one record nobody can quietly rewrite. Read the story the signed bytes tell (every quote in it deep-links to its verification) — or open the live record page.
"He said / she said" disputes stop being memory contests:
every observation, statement, and conclusion is a separate signed receipt on a
hash-chained ledger — disagreements stay on the record, flagged and verbatim,
because the record never adjudicates. And the exported pack carries its own
verifier: the same verify.html bundled inside the zip is the page
this site hosts — it checks any pack you drop on it, ours or a stranger's
email attachment. (How is this different from Ring
Event History? — receipts keep verifying even if Attest disappears.)
sample-pack.zip and runs the
moment this page opens. Drop any exported pack; nothing leaves your browser.
Verify the tampered twinFAIL
Same pack, but someone inflated the contested visit's observed span — 65.25 to 135.25 minutes, past its 90-minute schedule.
Deep link — lands on a red FAILED stamp; then "name what changed" points at
the forged field itself.
Forge it yourselfFAIL
The tamper lab: pick a signed field, type your own number, download the
rebuilt zip — the signature refuses your forgery, not ours.
Watch the two-minute tour
Twelve beats, self-playing — every frame is the real product page, not a
screenshot. The fastest possible entry if you'd rather look than click.
Run the whole gauntlet9/9
One click, every artifact: clean pack, its older export sibling,
the four attack twins, the real-API sweep, the signed fork, the
Bitcoin anchor — each verdict scored
against the shared oracle, live. The whole demo as a single stream.
Compare two packsDIFF
"The copy the agency produced" vs "the copy I kept" — each verifies on
its own merits, then their signed membership is diffed: the forged field named,
and the two log heads proven to reconcile — or caught forking. Two verifying
packs that aren't the same records is the whole point. Downloads the comparison
as a self-contained page — the same reading attest diff --html
writes.
Compare across timeGROWTH
The pack a family kept vs the export an agency produced weeks later —
the signed heads aren't adjacent, so the reconcile walks the newer pack's
embedded checkpoint chain hop-by-hop. Append-only growth proven offline;
read the report.
Verify the real-API sweepPASS
The signed verify-live --sign report from the actual
api.amazonvision.com run — a lone receipt, auto-verified on load.
Verify it on your phone
$ attest demo && attest attack-demo — loading the real transcript…
Real output from this repo's demo runtime, lightly trimmed —
including forging a signed resolution's reason code after the fact and
swapping media bytes on disk post-signing. Reproduce it yourself:
attest demo, then attest attack-demo on the same
runtime.
The trust chain — nobody in it is trusted
"The record gets a verdict; nobody's story does."
Every observation and statement becomes a signed receipt; receipts chain by hash into a publicly checkable Merkle tree; independent witnesses cosign the tree head — the shipped sample pack below carries two real counter-signatures from separate deployments, each anchored in the witness's own log. Export a pack and strangers verify it — in a browser, in bare Python, in an AWS Lambda — without asking us, Ring, or the issuer whether the bytes are still honest.
"Isn't this just Ring's event history?"
| aspect | Ring Event History | Attest |
|---|---|---|
| Who vouches | Ring says so | the math — anyone re-checks, offline |
| Voices | device events only | worker + household + coordinator, kept separate |
| Edits | platform-controlled | append-only; tampering breaks the math |
| After export | a screenshot | a self-verifying evidence pack |
Ring's event history is Ring's word. An Attest receipt verifies without Ring — and without us. Incumbent tracking puts a GPS ankle monitor on the worker's phone, spoofable and resented; Attest anchors observation to the household's own premises, with the household's own cameras. And the trend cuts our way: as Ring moves traffic toward throw-away-the-key encryption (TAKE — Throw Away the Key Encryption, the new default where Ring deletes the content keys within ~24h, so Ring can't produce the footage unilaterally afterward — re-provisioning needs the customer's device), the platform holds less and less producible content — which makes a signed, independently checkable evidence trail more valuable, not less. Encryption decides who can see the bytes; attestation decides whether anyone can quietly change them.
The product behind the proofs
attest demo boots a local Ring emulator and plays an eight-day story
(9 visits over 8 days) —
a disputed visit, a camera blackout mid-window, a lapsed subscription, a coordinator
live view — then serves the whole product on a printed localhost URL (--port 8000 pins it).
Or peek at a snapshot first, no install:
the coordinator dashboard ·
the site page (day-by-day coverage strips,
the live-view band) ·
the contested visit (source-divergence callout, signed
dispute) · the household
view (en español) ·
the scoped family link
(en español) — what the
household actually gets texted ·
the worker's review link
(en español) — what the
scoped /review/ token sees ·
the printable brief ·
the self-audit page (revoked-key suspect
windows, annotated — 9 receipts in scope) ·
its machine-readable JSON — and the raw layer
underneath all of it: 447 signed receipts
(the demo store's full log) —
drawn as the literal hash chain (every edge a prev_hash link —
all 447 verify), each one-click verifiable in the same browser page —
or all 447 at once
(raw JSON). Twenty-eight of them are the deployment
auditing itself — attest verify --attest signed the
verdicts on the clean pack and the forged twin across regenerations, and
attest diff --attest signed the reconciliations, into the same
log — and each diff report names the receipt that signed its comparison —
the audit trail of the audit is checkable too. New to the math?
Anatomy of a signed receipt
decomposes one field-by-field — what the signature covers, what the
prev_hash edge means, and what a valid signature can never
prove.
And because "trust our log" isn't a stopping point either: the demo
deployment anchors its journal head to Bitcoin —
the signed anchor, one-click verified
(journal head + transparency-log root pinned inside it) sits under a real
OpenTimestamps submission (pending —
public calendars commit to a block on their own schedule;
attest stamp --upgrade completes it). "This record existed before
that block" — verifiable without trusting us.
/— coordinator dashboard: KPI cards, coverage gaps labeled "no observation — not absence", and a per-worker check-in-timing table (median + worst camera-vs-self-report lag — "a pattern, not proof")/sites/…— the site page: per-day coverage strips for the whole window, interruptions marked why (offline/online lifecycle), the live-view session band, coverage certificates — the clearest picture of what gets recorded/integrity— the deployment auditing itself: receipt chain, mutation journal, transparency head, key custody, webhook posture — each section signed (/integrity.jsonserves the same audit machine-readable)- any visit — timeline, source-by-source corroboration, signed anchors, worker + household + coordinator voices kept separate, suspect-window warnings
?lang=es— household, worker, and public surfaces localize (Accept-Language respected too) — accessibility is a Ring priority category; verificar.html is the verification guide in Spanish — what the stamp means, what it never proves, how to re-check without trusting this page
The attack gallery — pick one, watch it get caught
One doctored number is the easy case. Each attack below dies to a different check in the same verifier — the links land directly on the red FAILED stamp:
- Doctored field —
the contested visit's observed span inflated 65.25 → 135.25 minutes:
the signed
payload_hashno longer matches → payload hash mismatch. zip - Deleted record — a visit bundle removed from the zip, but the signed manifest still names its receipt → missing or invalid bundle. zip
- Smuggled file —
extra-evidence.jsoninjected after signing → present but not in the signed manifest. zip - Forged verifier —
the embedded
verify_case.pyswapped for an always-green stub → bytes differ from the issuer-signed pin. The pack defends its own checker. zip
Nineteen more attacks die inside the store — forged rows, erased
journal entries, grafted keys, swapped media —
the battery's live verdict table
renders all 23 verdicts from a real attest attack-demo run
against the demo store (22 caught, rolled back — the 23rd is a named
detection boundary, marked EXPECTED MISS on purpose).
Mint your own: attest export --tamper-twin twin.zip --attack
missing-record — the exporter self-verifies the twin and refuses to ship
it if the doctored copy still passes.
Or skip the shipped attacks entirely: the tamper lab lets you commit the forgery yourself — pick a signed field in the sample pack, type your own number, and the verifier rebuilds a real zip around your edit, downloads it for you, and refuses it. Nothing is staged: the doctored pack is a real artifact, and the same signature catches your number, not just ours.
And the harder corpus, public: 44
conformance vectors — the Wycheproof-style packs every verifier
surface must judge identically. The interesting attacks aren't obvious tampers;
they're grammar traps — leaf_index: true, "5" as a
string, 5.5 fractional, space-padded hex, a tree_size of
240 that breaks JS bitwise ops. Each row is a one-click
verify.html deep link landing on the verdict the oracle predicts.
Two verifiers silently diverging is exactly how a pack gets ruled valid in one
room and invalid in another — this corpus exists so ours can't.
The fork nobody can hide
The transparency log's whole point: even we can't rewrite history. One
issuer key, two histories — a witness pins one tree head, a monitor pins the
other. Neither side can tell alone; together they prove the fork, and the catch
itself is signed as a monitor_observation receipt committed inside a
signed tree head. Verify the caught
fork in your browser — the evidence doc's checkpoint signature, inclusion
proofs, and embedded observation all check out. Reproduce it:
attest split-demo fabricates the whole scenario in scratch space and
emits the same evidence document.
Ring surfaces called at runtime: signed webhooks · Event History · media & snapshots (regional redirect handled) · devices/capabilities · app-integrations · subscriptions · WHEP live view. Track fit: business systems + caretaking + accessibility + access control + IoT home automation — caretaking carried through the household view and the scoped-link QR the family scans at the door; access control through the hashed, expiring, revocable grant links those scoped pages run on; IoT telemetry through the device-lifecycle coverage journal (why observation stopped, signed).
Five AWS touchpoints — three verified live
- Lambda verified live —
attest-verify-packre-verifies a posted pack in AWS using the project's pinned verifier, never the pack's embedded script — data and code come from different parties:
$ aws lambda invoke --function-name attest-verify-pack \ --payload fileb://pack.json out.json {"ok": true} — 2 visit records, 43 receipts proven inside the log (transcript of the 2026-09-18 run — the current pack carries 9 visit records, 175 receipts proven at checkpoint size 305) $ # doctor one byte in a signed payload, invoke again {"ok": false} — payload hash mismatch (payload was altered) the function catches exactly what the local verifiers catch
- KMS verified live — the Ed25519 signing key
is envelope-encrypted under a KMS data key (AES-256-GCM + encryption context); every
unwrap is a CloudTrail-audited
Decrypt, verified end-to-end on a real CMK. - S3 verified live —
attest anchor --publishuploads signed checkpoints to a versioned, public-access-blocked bucket with the file sha256 stamped into object metadata — a checkpoint outside the deployment's control. - Bedrock Converse labeled fallback — multimodal: each camera snapshot's bytes are re-verified against their signed SHA-256 at summarization time and only digest-verified frames go to Nova Lite as image blocks — the prompt treats text-in-the-image as untrusted and forbids identity inference. The account's on-demand quota is zero, so every model call authenticates then throttles — and the record labels the deterministic fallback as its true source instead of pretending.
- Strands agent labeled fallback — the weekly
triage brief reads the ledger through real read-only tools; same quota wall, same
honest labeling (
strands-agentvsdeterministic+ reason).what the agent actually does — tools + a real brief
tools granted (read-only, bound to the store): list_sites · site_records · record_detail · integrity $ attest triage agent triage unavailable (LoginRefreshRequired); deterministic brief 6 record(s) need attention: - vis_70e42116a4cf (closed): worker disputes this record - vis_5b7958271e00 (closed): observation matched no schedule … [source: deterministic triage — agent unavailable: LoginRefreshRequired]
The fallback path is itself verified against real AWS failure modes —
expired aws login creds surface as LoginRefreshRequired,
quota as ThrottlingException — which is the designed behavior, not a
mock. An honest FAIL on the label beats a fake PASS.
Also entered: ring-sandbox — the Open Source mini-challenge
Ring ships no SDK and no simulator, so we built both: ring-sandbox is a typed Python client + FastAPI emulator of the documented surface (webhooks, Event History, media, subscriptions, WHEP), a YAML scenario DSL, chaos injection, and a pytest plugin — MIT-licensed, on PyPI, CI-tested on Windows/Linux × Python 3.11/3.14, shipping real Playground recordings as fixtures. Attest's whole demo runs on it — and every team after us gets Ring integration without a doorbell.
pip install ring-sandbox — then point the emulator at a scenario
YAML and your client talks to a full Ring surface on localhost.
Developer-experience feedback for the bonus: 17 documented friction-log entries (task → expected vs actual → severity → workaround → suggestion) in FRICTIONLOG.md.
What verification proves — and what it doesn't
A green verdict means
- Every signature is valid under the pinned issuer key.
- No record was added, dropped, or altered since signing.
- The receipts are committed in the signed transparency-log head the pack carries.
- Redacted media was withheld by policy — its signed digests still match the manifest.
It does not mean
- That the worker physically attended — camera activity is an observation, not attendance.
- That absence of events means absence — silence isn't absence.
- That the issuer is honest — a signature proves integrity under a key, not truth. That's why witness cosigning and the live-log cross-check exist.
What's inside the sample pack
The bundled sample-pack.zip is a real export from the
simulated Alvarez residence deployment — media withheld by redaction policy,
signed SHA-256 digests preserved. It exercises the hard parts, not just the happy path:
- a signing-key rotation mid-history: the pack names both issuer keys — the rotated-away key, its signed adoption, and the revocation receipt that retires it;
- receipts on both sides of the pivot, verified under different keys;
- a suspect-window annotation — the window signed while the old key was compromised inherits doubt, explicitly;
verifier_manifest.jsonpinning the verifier tooling's own hashes — the pack defends against a hostile verifier shipped inside itself;log_checkpoint.json: a signed RFC 6962-style Merkle tree head with inclusion proofs — the receipts are committed in a transparency log, and the verifier's cross-check can prove the deployment still serves the same head to everyone;- a witness cosignature anchored in the witness's own independent published log — the attestation is publicly committed the moment it's served;
- and outside the zip, one click over:
divergence-checkpoint.json— signed monitor evidence of a caught log fork (thesplit-demoscenario), verified by the same page.
The embedded index.html is a record browser, not a file listing:
worker, household, and coordinator voices rendered separately from the signed
payload (conflicting household accounts are flagged, never merged —
and the household's typo-correction appends as a new signed statement, so the
chain keeps the garbled original and the fix),
per-visit signed anchors and deep links, a plain-language tab that prints clean,
viewer-local times with the signed UTC literal on hover, and a six-element
Cures Act crosswalk — the federal EVV (electronic visit verification)
statute mapped to evidence fields,
labeled as corroboration, never as submission.
Pin the issuer out-of-band. The pack's self-declared key says who signed it; a judge who doesn't trust the site shouldn't take its word for the key either. Three ways to pin:
- Fetch the signed issuer document over an independent transport —
attest-issuer.json(the same document a live deployment serves at its origin well-known) — thenattest verify pack.zip --issuer-url attest-issuer.json. The pack and its trust anchor arrive by different surfaces; that's the point. - One click: verify the sample pack pinned to the issuer document this site serves — the browser fetches both and checks the pin itself.
- And the checker defends itself: every pack's signed
verifier_manifest.jsonbyte-pinsverify.html— the page hashes its own bytes → PINNED/PIN MISMATCH; andsite-manifest.jsonpins every artifact this site ships → SITE VERIFIED/SITE TAMPER, drifted files named.
Proof it talks to the real API
live-sweep-receipt.json is the signed
verify-live --sign report from a real sweep against
api.amazonvision.com (2026-09-30): five probes pass — users/me, devices, device
status, Event History, and media download through the regional redirect — and three
fail honestly on documented Playground limits (app-integrations 403, subscriptions 422,
WHEP 500: no streaming hardware on the account). Every probe signed, so the
claim verifies offline the same way a pack does.
Verify it in your browser, one click →
Attest is a hackathon prototype — evidence-preserving records for visit disputes, not an attendance-verification or EVV product. Source: github.com/josepha-mayo/attest · emulator: ring-sandbox · judging: JUDGE.md (the ten-minute path + scoring map) · threat model · the CI evidence gate (every pack must pass ∧ its doctored twin must fail) · a drafted Ring Appstore listing.