EquiHire: Building a Job Board That Forgets Your Name
How we built a Web3 anonymous job board around SDG 10, using zero-knowledge-style credentials, verifiable certificates, and an in-app learning track that lets candidates prove skill without ever revealing identity.
There is a well-known résumé experiment where two CVs are sent to the same job with the same content, the only difference being the name at the top. The CV with a name that sounds white gets noticeably more interview callbacks than the one with a name that sounds Black. The study is from 2004, the gap has been replicated since, and most hiring platforms still hand recruiters the candidate's name, photo, and education badge on the first screen.
EquiHire is my attempt to build the opposite of that. A job board that, by default, forgets your name. Not as a toggle in an admin panel, not as a checkbox in a careers policy, but as the only mode the product has.
The brief, in one line
EquiHire was built during Brunel's Startup2 module, aligned with UN SDG 10 (Reduced Inequalities). I was the Scrum Master and full stack developer. My owned surface was the Jobs page, the application flow, and the design language of the product. Mid-sprint I also shipped a learning and certification track that was not in the original deliverable, because the product needed it and the team agreed in the demo.
Why Web3 was the right primitive, not a buzzword
I did not want to use Web3 because it sounded modern. I wanted two specific things from it. First, selective disclosure: a candidate should be able to prove 'I hold this certificate' without showing who issued it to whom, when, or what their wallet has done since. Verifiable Credentials with zero-knowledge-style proofs give you exactly that shape.
Second, Sybil resistance: if applying is anonymous, what stops one person spamming a hundred fake applications to the same role? Proof-of-personhood, expressed on-chain as a uniqueness commitment, lets the platform enforce one account per real human without ever learning who that human is. Anonymity and accountability stop being opposites the moment you stop using identity as the proxy for both.
Architecture in plain English
The front end is a React app with an anonymous profile, an application flow that strips identity at submit time, and a dossier page where a candidate (or, with permission, an employer) can verify a certificate. The back end runs a verification service for credentials, a uniqueness registry that holds commitments rather than identities, and a small smart contract that anchors certificate hashes so a certificate cannot be quietly altered after issuance. Every privileged action writes to an append-only audit log.
// Verify-then-reveal handshake, pseudo-code
async function applyToJob(jobId, credentialProof, uniquenessProof) {
const okCred = await verifier.verifyVC(credentialProof); // 'I hold cert X'
const okUniq = await registry.checkAndCommit(uniquenessProof, jobId); // one per human per role
if (!okCred || !okUniq) return reject('proof-failed');
// Employer sees: skill badges, anchored cert hashes, opaque applicant id.
// Name, email, wallet address are NOT in this payload.
return inbox.push(jobId, { applicantId: opaqueId(), badges: okCred.claims });
}The important property is what is missing from that payload. The employer never receives the candidate's name, email, or wallet. They receive a list of verifiable claims and an opaque applicant id. If the conversation progresses, the candidate can selectively reveal more, on their own terms, through a separate channel.
The Jobs page I owned
The Jobs page has three states: browse, detail, apply. Browse is a search-and-filter list. Detail is the job description with a clear statement of what the employer will and will not see at submit time, written in plain English at the top of the page. Apply is a single screen that asks for the proofs the role requires (for example, a verified course certificate plus a uniqueness proof) and nothing else.
The redaction step is enforced both client side and server side. Client side strips identity-bearing fields before sending. Server side compares the incoming payload against an allowlist of fields the employer is permitted to see pre-interview and rejects anything outside it.
const PRE_INTERVIEW_ALLOWLIST = ['applicantId', 'badges', 'certHashes', 'coverNote'];
function sanitiseApplication(payload) {
const clean = {};
for (const k of PRE_INTERVIEW_ALLOWLIST) if (k in payload) clean[k] = payload[k];
return clean; // anything else is dropped, not just hidden
}The cover note is interesting. We left it in because candidates wanted a place to say something in their own words. We also ran it through a small classifier that flags identity-revealing phrases ('as a 42-year-old mother of two') and warns the candidate before submit. The warning is advisory, not blocking. People know their own lives better than a model does.
Glassmorphism, and why I argued for it
We ran a Figma critique with three theme directions: hard editorial, friendly neumorphism, and glassmorphism. I argued for glass. The reasoning was specific to this product. EquiHire deliberately removes the things most job boards lean on for warmth: avatars, names, company logos shown alongside candidates, education badges. The surface had to do more emotional work than usual.
Frosted layers with soft depth made the product feel approachable without smuggling identity back in through visual flourish. It also signalled, before a single label was read, that this was a different kind of platform. People who landed on it for the first time noticed the difference immediately, which is exactly the moment a product gets to set expectations.
The learning track I added mid-sprint
Once the core Jobs work was stable, I noticed a gap. Anonymous applications work if the candidate already has credible proofs to attach. For a junior candidate, or someone changing field, that is exactly what they do not have. So I prototyped a small learning track over a weekend: short course, embedded material, end-of-course quiz, signed certificate, verifiable dossier page.
I demoed it to the team on a Monday. They were positive, so I integrated it for real. The flow is: pick a course, work through the material, pass the quiz, receive a certificate whose hash is anchored on-chain and whose content can be selectively disclosed at application time. The dossier page lets anyone with the right link verify the certificate without contacting the issuer.
This was the business-edge moment. EquiHire now had something most anonymous-application research projects do not: a built-in supply of fresh, verifiable skill proofs. Candidates who arrived with nothing could leave with something portable.
Scrum, but actually
I configured the Jira board, broke epics into stories with estimates and owners, and ran the standups. The unglamorous part of being a Scrum Master is that most of the value is in two things: rebalancing tasks when one person is drowning and another is idle, and removing the thing that is silently blocking someone who has not said anything yet.
When the back-end ZK work slipped, we did not pretend the deadline still held. We re-scoped the sprint to ship the FE with a mocked verifier behind the same interface, so the demo flow worked end to end and the real verifier could drop in later without UI changes. GitHub branches per feature, merges through PR review, OneDrive for shared docs, Teams for meetings with written notes saved the same day. None of it was clever. It just stopped things falling through the cracks.
The failure modes I cared about
Anonymity is easy to claim and hard to actually deliver. Four ways it leaks, and what we did about each:
Ranking algorithms quietly reintroducing bias. We sort by proof-match strength and posting recency only. No 'engagement' signal, no employer-side reordering before the candidate has agreed to reveal anything.
Gendered or coded language in job ads pushing certain candidates away before they apply. We run posted ads through a language check based on the published research and surface flagged phrases to the poster, not the candidate.
Metadata leaking identity (file names, timestamps, document author fields). The application pipeline strips metadata from any uploaded artefact and re-encodes documents server side before they reach the employer view.
Writing style as a fingerprint. We cannot fully solve this without distorting the candidate's voice, which would itself be a fairness problem. We do warn candidates that long free-text fields are the most identifying surface on the platform, and we keep those fields short by default.
What I would do differently
Four things, in order of how much I think they would move the product:
Replace the local DB with a proper Verifiable Credentials registry so certificates issued by EquiHire interoperate with credentials issued elsewhere, instead of being a walled garden of one.
Add a hybrid reputation graph that lets candidates build a track record across applications without that record becoming a re-identification vector. The shape exists in the research, the engineering is non-trivial.
Ship on-chain certificate revocation so an issuer can invalidate a compromised certificate without an out-of-band email saying 'please ignore that one'.
Build an employer-side fairness dashboard that shows, in aggregate, how their shortlist compares to their applicant pool on the dimensions employers usually do not see. The point is not to shame anyone. The point is to give them the same feedback loop the platform is giving the candidates.
Fairness is a product decision, not a paragraph in a careers page. If your default screen shows a name and a photo, you have already decided what kind of bias your platform tolerates, no matter what the policy says.