@zanii/subject
v0.1.1
Published
Per-subject auditability: end users hold their own key and independently verify what agents did on their account — a pseudonymous, platform-scoped subject_tag receipt slice — without seeing anyone else's.
Readme
@zanii/subject
Per-subject auditability. A platform registers agents with Zanii; its millions of end users are the data subjects those agents act on. This package gives every end user their own key and their own independently verifiable slice of the ledger — what agents did on my account — without seeing anyone else's.
Owner-scoped views can't do this: an end user isn't an agent or an owner, and data subjects appear elsewhere only as salted, deliberately unqueryable commitments.
How it works. The platform stamps a pseudonymous, platform-scoped subject_tag on
each receipt (a signature-covered SPEC §3 field). The end user — holding their own
did:key the platform never sees — computes the same tag, pulls their slice from
GET /v1/subjects/{tag}, and verifies every receipt offline: signature, delegation
chain, scope, and tag match. Trust the maths, not the platform.
- The same user gets a different tag on every platform — no cross-platform linkage.
- A tag can't be reversed to an identity; receipts about other subjects aren't enumerable.
- Field-level payload disclosure composes with
@zanii/redact(the subject sees their fields, nothing else — payloads are off-ledger hashes).
npm install @zanii/subject @zanii/corePlatform side — stamp the tag
import { subjectTag } from '@zanii/subject';
const tag = subjectTag(endUser.did, 'platform.example.com');
await agent.record({ target: 'feed.rank', payload, subjectTag: tag }); // SDK ≥0.4.0End-user side — audit your own slice
import { subjectIdentity, fetchMyHistory, signSubjectClaim, verifySubjectClaim } from '@zanii/subject';
const me = subjectIdentity(); // your key — the platform never holds it
const history = await fetchMyHistory(me.did, 'platform.example.com');
history.verified; // every receipt checked offline
history.receipts.map((r) => r.receipt.target); // what agents did on YOUR account
// prove "this is my slice" to an app (sig by your key + the tag derives from your DID):
const claim = signSubjectClaim({ platform: 'platform.example.com', subjectDid: me.did, ts }, me.privateKey);
verifySubjectClaim(claim); // trueHonest limit: the slice is only as complete as the platform's stamping — a platform
that omits subject_tag hides that receipt from the subject's view (never from the log
itself). Systematic omission is detectable via reconciliation and consent receipts;
per-subject auditability is verifiable, not magic.
Changelog
- 0.1.0 — initial release:
subjectTag,subjectIdentity,signSubjectClaim/verifySubjectClaim,fetchSubjectHistory/fetchMyHistory.
License
Apache-2.0.
