Skip to content
GitHubOpen source
Product
Docs
Solutions
IndustriesAll industries
CompareCompare all AI data-leak tools
Benchmarks
GitHubApache-2.0

Secure LLM use in HR and recruiting: protect candidate and employee data in AI prompts

Shadow is for HR teams, recruiters, staffing agencies and HR tech vendors that use large language models on CVs, employee records and people-related documents. It runs on your own laptops, servers or pods, replaces candidate and employee names, emails, phone numbers, addresses and recognised national IDs with fakes before a request reaches the AI provider, and restores them in the answer. It reduces personal data sent to AI vendors; it does not make automated hiring decisions fair or lawful by itself.

What data leaks into AI tools in HR and recruiting

Section titled “What data leaks into AI tools in HR and recruiting”
WorkflowWhat typically ends up in the prompt
CV screening and summarisingFull CVs: names, contact details, addresses, dates of birth, photos, employment history
Writing job offers and rejection emailsCandidate names, salaries, start dates, personal emails
Interview notes and scorecardsCandidate and interviewer names, opinions, sometimes health or family details
Employee relations and investigationsNames, allegations, sick leave, disciplinary history
Payroll and benefits questionsSalaries, bank details, national insurance or social security numbers
People analyticsExports of the workforce with names, demographics and performance ratings

Much of this is sensitive by any standard, and some of it falls into GDPR special categories: health, ethnicity, trade union membership, religion.

Shadow masks values in every AI request and uploaded file with fakes from a persistent persona, keeps the mapping in an encrypted local vault, and restores responses, including streams and tool calls.

DataHow Shadow handles it
Candidate, employee and referee namesName detector, person: terms, the NER sidecar or Presidio for multilingual free text
Emails, phones, street addressesBuilt-in detectors (addresses in English and German styles; others need the NER sidecar or Presidio)
National IDsUS SSN and ITIN, UK National Insurance and NHS numbers, Indian Aadhaar and PAN, Australian TFN built in; more with Presidio
Bank detailsIBAN detector with mod-97-valid fakes
Employer and client company namesorg: terms, organisations with a legal suffix detected automatically
CVs and HR documentsDOCX masked in place; PDF text extracted and masked
Candidate lists and workforce exportsreport intent: typed tokens for people and contact details
organization = ["Acme Staffing Ltd"]
terms = ["org:Globex", "org:Initech", "term:Requisition Falcon"]
internal_domains = ["acme-staffing.example"]
[model_detector]
enabled = true # ml/serve_hf.py: multilingual names and addresses
url = "http://127.0.0.1:8878/detect"
[policy.report]
person = "token"
email = "token"
phone = "token"
address = "token"
national_id = "token"
default = "surrogate"
[files]
pdf = "text"
images = "block" # CV photos and scanned documents are not OCR'd
RequirementHow Shadow helps
GDPR Art. 5(1)(c), 25 and 32Data minimisation and pseudonymisation by design before candidate and employee data reaches an AI vendor. Pseudonymised data remains personal data for you (Recital 26)
GDPR Art. 9 special categoriesReduces identifiers attached to sensitive content; it does not remove the sensitive content, so a lawful basis is still needed
GDPR Art. 22 automated decisionsNot addressed by masking. Keep humans in the decision
EU AI Act, Annex III employment use casesHigh-risk obligations apply from 2 December 2027 under the 2026 Digital Omnibus. Shadow supports data governance and security; it is not a risk management system, conformity assessment or human oversight measure
NYC Local Law 144 (automated employment decision tools)Unrelated to masking: a bias audit and notices are still required where the law applies
ISO/IEC 27001, ISO/IEC 42001, SOC 2Evidence of a technical control on AI data flows

What the recruiter sends (all data fictional):

Summarise this CV for the hiring manager: Daniel Okoye, daniel.okoye@mail.example,
+44 7700 900456, 7 Station Road, Bristol. NI number AB 12 34 56 C. Five years at Globex
as a data engineer.

What the provider sees (your fakes will differ):

Summarise this CV for the hiring manager: Tao Zhu, tao.zhu@xinghe.cn,
+86 139 2245 7710, 88 Tianfu Road, Bristol. NI number CE 48 21 07 B. Five years at Zhilan
Technology as a data engineer.

The summary comes back about Daniel Okoye. His experience, which is what the hiring manager needs, is unchanged.

A recruiter pastes a CSV of 40 shortlisted candidates with notes and asks for a comparison against the job description. With that many names and contact details in tabular form, Shadow classifies this as report: candidate names, emails and phones become [PERSON_0001], [EMAIL_0001] and so on. The model compares tokens and the ranking comes back with real names. A human still makes the decision.

An HR partner uploads a DOCX offer template filled in for a candidate. Names, address and bank details are masked inside the Word document, it stays valid, and the edited letter comes back with the real details restored.

If an assistant emails or schedules candidates itself, they still get the message. The candidate the instruction names (“Invite Daniel Okoye, daniel.okoye@mail.example, to a Tuesday interview”) is the recipient, so their name and email pass through as written and each keep is logged; the model writes to the right person. Other candidates, notes and IDs in the request stay masked and are restored in the tool-call arguments before your code sends the invite. Set [policy.act] targets = "surrogate" to fake the recipient too. With a provider-hosted tool, Shadow cannot restore inside the provider, so by default the contact details the action needs are kept real and each keep is logged. See intent-aware policy.

PatternWhen to use it
Endpoint install for recruiters and HR partners: shadow install --applyAPI-backed chat clients and desktop apps on HR laptops
Gateway for an ATS or HR tool integration: http://127.0.0.1:8877/gw/openai/v1Screening, scheduling and letter-writing features you build
Sidecar in KubernetesHR tech products calling LLMs for many customers. See Docker and Kubernetes

For agencies serving several clients, a separate data directory per client (SHADOW_HOME or --data-dir) keeps vaults apart. There is no central admin console yet; an optional local audit log is on the roadmap.

Frequently asked questions

Can recruiters paste CVs into ChatGPT?

Sending CVs to a consumer AI service puts candidate personal data with a third party, often without a clear lawful basis or agreement. Shadow masks names, emails, phones, addresses and recognised national IDs in CVs and documents before they reach a provider API. Consumer web apps such as chatgpt.com are not built-in hosts, so give recruiters an approved API-backed client.

Does masking candidate names make AI screening fair or unbiased?

No. Removing names and contact details can reduce some signals a model might react to, but bias can come from schools, employers, gaps, language and many other features that Shadow does not mask. Fairness needs testing, oversight and, where required, a bias audit.

Is AI-assisted hiring high-risk under the EU AI Act?

AI used for recruitment, selection, promotion, termination and task allocation is listed as high-risk in Annex III. Under the 2026 Digital Omnibus, those obligations now apply from 2 December 2027. Shadow is a data protection control; it does not perform conformity assessment or provide human oversight.

Can Shadow mask CVs uploaded as PDF or Word files?

Yes for text. DOCX CVs are masked in place and stay valid documents. PDF text is extracted, masked and sent as text, so layout is lost. Scanned CVs and photos are not OCR'd; block images if they may be uploaded.

Can we compare a shortlist without the model seeing who the candidates are?

Yes. A request that pastes many candidates in at once, such as a table with their names and contact details, is classified as a report, so names, emails, phones and addresses become typed tokens such as [PERSON_0003]. The model ranks and compares tokens, and the answer is restored with real names on your screen.