TIMING: 45 min total — Act I ≈ 10, Act II ≈ 12, Act III ≈ 18, close ≈ 5. "Tonight I want to tell you about a problem I stumbled into by accident — and how solving it took me from a university IT office, through 1990s internet history, to the Himalayan kingdom next door."
30 seconds. Do not read the slide. "I do platform engineering at STARTsmall | Kubernetes, GitOps, the usual. I also help organize this meetup. I am not a cryptographer, and that is sort of the point of tonight.
- Minimal blockchain hype. - Maximum architecture. - There is a live demo at the end and the repo link is on the last slide." - Act II is a theory-heavy part.
- An IT officer relayed this from the government side. The engineering instinct fires immediately: - expose an API, - sync a database, - done. Let's follow that instinct all the way to the wall.
Walk it left to right: - KU's records DB replicates into the Nagarik App, or gives a readonly API. - the app renders the transcript, - the student forwards/show it to an employer. - And after all that integration work, the employer still picks up the phone and calls KU or asks us to present nagarik app. - We built a pipe. We did not build trust.
- Three sprints, - one integration test, - everyone's happy. - Let's look at what we actually shipped."
"Replicating student records into a central platform concentrates risk by construction. One breach exposes every transcript of every citizen in the system." Frame it for this room: - blast radius. - We spend our careers shrinking it - namespaces, - network policies, - least privilege - and this design maximizes it on day one. - "isn't that just an encryption problem": - encryption protects data at rest from an outsider. - It does not help when the platform itself is the thing that must decrypt and render. - The custodian is the risk, not the disk.
- Every verification is now a synchronous call into KU's infrastructure, - which must be up, fast, and secured — forever. - KU's records system was never designed to be a Tier-1 national dependency." - Availability targets, DDoS surface, rate limiting, 24/7 on-call. - Who owns that? The university? The Nagarik app team? Nobody budgeted it.
- The app fetches the data, - the app renders the data. - The verifier's trust in that payload is inherited entirely from trust in the middleman. Walls 1 and 2 are engineering problems - expensive, - but solvable with money and headcount. - Wall 3 is architectural. There is no amount of infrastructure that fixes it. - This is the wall the rest of the talk exists to break. Say that.
Thesis of Act I. Read it out loud. ▸ Time check: you should be at ~10 minutes.
"The CA vouches once, cryptographically. Every browser on Earth verifies independently. There is no per-handshake phone call to the CA." The trust anchor is a public key in your root store, not an uptime SLA. Signatures scale. Phone calls don't. ▸ Everyone in this room has debugged a cert chain at 2am. - i am not teaching them TLS, i am reminding them they already believe this.
"What if a transcript worked like a TLS certificate signed once by KU, verifiable by anyone, anywhere, forever?" That reframing turned an integration problem into an identity problem, and that is what led me into the Hyperledger ecosystem. The pattern has a name, and people have been building it for a decade.
"Self-sovereign means the individual holds and controls their own credentials, and verification happens against open cryptographic infrastructure instead of somebody's database." Three building blocks. One slide each. Then we build something.
Decentralized Identifier. Contrast it with everything we use today: usernames, domains, email addresses — all RENTED from a registrar who can revoke them tomorrow. A DID is generated from your own keypair and anchored on a verifiable data registry. Resolving it returns a DID document: public keys plus service endpoints. Anyone can resolve it; only the controller can update it. "Think of it as a TLS certificate subject, minus the CA's permission." ▸ Tonight's real issuer DID on BCovrin Test is SpvwxDc7Mcmgc9DyWU6Azd. The did:indy string on the slide is illustrative — if someone asks, say so plainly rather than bluffing.
A VC is a set of claims — name, program, CGPA, graduation year — signed with the issuer's private key. Tamper-evident like a TLS cert, but for facts about a person. The crucial part: it lives in the holder's wallet. It never touches the ledger. AnonCreds — the format Indy uses — adds selective disclosure: reveal some attributes, and prove predicates about others (CGPA ≥ 3.0) without revealing the value at all. W3C standardizes the underlying model. ▸ Don't go deep on ZKPs here. One sentence, plant the seed, move on.
Map it straight onto TLS: Issuer ≈ Certificate Authority. Credential ≈ certificate. Verifier ≈ browser. Indy ledger ≈ the root store that ships with your OS. "The property that matters: the issuer and the verifier never talk to each other. Both only consult the public registry."
Trace the two dotted lines with your hand — both parties talk to the registry, never to each other's databases. "The middleman from Act I doesn't get secured. It gets deleted from the architecture."
"My path went through Hyperledger Fabric first. Great for supply chains. Overkill and under-fit for identity." Indy is purpose-built. Its ledger stores exactly four object types: DIDs, schemas, credential definitions, revocation registries. Kill the misconception now, out loud: nobody is putting transcripts on a blockchain. The ledger is a cryptographic phone book. Credentials live in wallets. ▸ IF ASKED about GDPR / right-to-be-forgotten: that is exactly why this split matters. Erasing a credential means the holder deletes it from their wallet. Nothing personal was ever written to an immutable log.
Citizens hold government-issued verifiable credentials in a mobile wallet — a privacy-preserving national digital identity, deployed next door, on the Indy stack. Bhutan also legislated for it, with a national digital identity act in 2023. "Bhutan has a smaller population than the Kathmandu valley, and they shipped a national SSI deployment before most of the world."
Governance matters to this audience more than cryptography does. LF Decentralized Trust (Linux Foundation, 2024–) is home to Hyperledger Indy, AnonCreds, Fabric, Besu. The OpenWallet Foundation hosts the agent stack — ACA-Py for cloud agents, Bifold for mobile wallets. Underneath it all: W3C DIDs and Verifiable Credentials, DIDComm. ame open-governance model as Kubernetes and the CNCF. Nobody's startup.Nobody's token. ▸ Time check: you should be at ~22 minutes.
The cast: - Issuer — an ACA-Py service KU runs to sign and issue transcripts. - Holder — the student's phone, running BC Wallet (open source, Bifold). - Verifier — an ACA-Py service ANY employer can run to request proof. - Ledger — BCovrin Test, a public Indy test network. I run no ledger nodes at all today. "The issuer and the verifier run the SAME software with different configs. The barrier to becoming a verifier is one container."
Three layers, top to bottom. (1) Two thin dashboards — an issuer console with 'Issue Transcript', a verifier console with 'Request Proof'. They call their agent's REST admin API and receive webhook events, so status flips from pending to verified live. No polling loop, no refresh button. (2) Two ACA-Py agents — Python, one container each. All the DIDComm, AnonCreds, and key management lives below this waterline. Pinned image: ghcr.io/openwallet-foundation/acapy-agent:py3.12-1.2-lts, wallet type askar. The old 'indy' wallet type is deprecated — if you follow a 2021 tutorial you will hit that wall. (3) The ledger. Note the arrow directions. Only the ISSUER writes, and only once — DID, schema, cred def. The verifier's arrow is read-only. The phone connects to both agents over DIDComm via QR codes, never to the ledger directly, never to a database. ▸ For this room: everything I run is two containers on a 2-vCPU VM behind nginx and Let's Encrypt. Ports bound to 127.0.0.1, TLS terminated at the host. That's the whole ops story.
Trace steps 1 through 7. Hammer step 7: "the employer verifies against public keys on the ledger. KU's servers can be switched off and verification still succeeds." That single property dissolves Wall 2 and Wall 3 at the same time. Say that explicitly — it is the payoff for the whole first half of the talk.
Three admin-API calls, all curl-able, Swagger at /api/doc: 1. POST /schemas — define ku_transcript v1.0: student_name, registration_no, program, cgpa, graduation_year. Written to the ledger ONCE, ever. 2. POST /credential-definitions — publishes KU's signing keys for this credential type. Also once. The agent can write because it was seeded with a ledger-registered DID. 3. Per student: create an out-of-band invitation → the console renders invitation_url as a QR → student scans with BC Wallet → DIDComm connection forms → send the credential with attributes filled in → wallet asks "Accept credential?" → tap. "The credential now exists in exactly one place. This phone." ▸ IF ASKED how the DID got registered: BCovrin Test has a self-service registration endpoint.
The employer's side mirrors it: 1. Send a proof request from the verifier agent — ask for 'program' and 'graduation_year', restricted to KU's cred_def_id. Rendered as a QR. 2. Student scans. BC Wallet shows exactly which attributes will be shared and asks for consent. Consent is architectural here, not a checkbox — the wallet constructs the presentation. 3. The employer agent resolves KU's DID on the ledger and verifies the signatures locally. The record comes back verified: true. "The employer trusted mathematics, not uptime." ▸ WHY IT STILL WORKS, if someone challenges it: the verifier needs the cred-def ID to build the request. The console caches it in localStorage, so the badge reads '(cached · issuer offline)'. That is not a demo hack — it is what a real verifier does. An employer knows which credential types it accepts without asking the issuer each time. ▸ IF THE STUDENT DECLINES on the phone: the exchange goes to 'abandoned', the console treats it as a clean ending and re-arms the button. Nothing is broken. Just ask them to scan again.
This slide answers the privacy question before it gets asked. Put it up, let people read it, don't narrate the table. One thing worth explaining: the revocation registry. It is how KU revokes a credential — a rescinded degree, a corrected record — without contacting a single verifier. Verifiers check a non-revocation proof against the ledger, and the issuer never learns where the credential was used. "Revocation without surveillance. That is hard to build any other way."
"For a DevOps audience, SSI is not cryptography homework." ACA-Py exposes a REST admin API. The crypto is below the waterline. What is left is orchestrating containers and terminating TLS — which is literally our job description. ▸ IF ASKED to reproduce it: pin the image tag (ghcr.io/openwallet-foundation/acapy-agent:py3.12-1.2-lts) and use --wallet-type askar. Most tutorials online are stale on both.
TU, KU, PU, Purbanchal — same schema standards, independent issuers, one verification experience for every employer. "No honeypot. No middleman. No single point of failure. A public good with no single point of concentration."
The asks, concretely — this is where you are recruiting: - HA Indy validator pools on k8s: StatefulSets, anti-affinity across failure domains, strict NetworkPolicies. - Stateless ACA-Py agents: askar wallets on HA Postgres, horizontal scaling, GitOps delivery via ArgoCD. - Observability for a network nobody owns: agent metrics into an LGTM stack, cross-organization SLOs for write latency and proof rates. - Supply-chain security for agents citizens will trust: signed images, SBOMs, DAST against the admin APIs. "Tonight's demo runs two containers on one VM with the admin APIs exposed. That is fine for a meetup and completely unacceptable for production and the gap between those two is our job."
- TRUST FRAMEWORK: someone must govern WHO may issue a national registry naming accredited issuers, and legal recognition of verifiable credentials alongside paper. Bhutan legislated this. - OPEN SCHEMAS: the transcript schema must be a national standard defined by registrars and exam controllers — the people with the domain knowledge — not by a vendor. Procurement language should mandate W3C VC and AnonCreds compatibility, or we trade one middleman for another with a nicer logo. - ONE PILOT: don't boil the ocean. One university, one credential type, one semester, published results. "The MVP you just watched is that pilot's skeleton. The missing ingredients are policy and domain expertise, not code." ▸ Invite
Stop. Take questions. Do not add a summary slide — the room is already past it. ▸ LIKELY QUESTIONS, short answers ready: - "Isn't this just blockchain hype?" → No personal data on chain; the ledger is a phone book of public keys. Four object types, that's it. - "What if the student loses their phone?" → Wallet backup/recovery is a real, unsolved-ish UX problem. Credentials are re-issuable by the issuer. Be honest that this is the weakest part of the story. - "Who pays for the ledger?" → In production, a consortium of issuers runs the validator nodes. BCovrin Test is free because it's a test net; it is not where you'd run this for real. - "Why not just sign a PDF?" → You can, and for some use cases you should. What you lose is selective disclosure, revocation without contacting verifiers, and a standard the whole world already implements.