Skip to content

Verifying identity without storing more than you should

  • Home
  • Blog
  • Verifying identity without storing more than you should
Verifying identity without storing more than you should

KYC data minimisation means verifying who a customer is while storing only the outcome — a decision, a method, a reference and a timestamp — instead of the passport scans, selfies and forms behind it. You can satisfy most legal checks on a few kilobytes per customer. The rest belongs in a vendor's vault or nowhere at all.

Key Takeaways

  • Store the decision, not the documents: verification outcome, method, reference and timestamp — not the scans and selfies behind them.
  • FATF-aligned AML rules commonly require keeping identification records at least five years after a relationship ends.
  • Redirect uploads to a vendor SDK or a pre-signed URL so files never touch your application servers.
  • If raw artifacts never reach your systems, no backup, log or export can leak them.
  • Automate deletion with bucket lifecycle rules and scheduled pruning; a policy that relies on memory is not a policy.
  • Encryption is not minimisation — data you can decrypt is still data you can leak.
KYC data minimisation flow: collect, verify, record, purge, retainFive ordered stages showing customer identity data being minimised at each step of onboarding.A KYC flow that keeps the verdict, not the paperwork1Collectessentials2Verify viaprovider3Record thedecision4Purge rawartifacts5Retain aslim record
The KYC data minimisation workflow: capture the essentials, verify through a provider or controlled queue, record only the decision, purge raw artifacts on a schedule and retain the minimal record your regulator actually asks for.

What does KYC data minimisation actually mean?

Minimisation is a storage rule, not a privacy slogan: collect the least identity data that completes the legally required check, then delete the remainder on a schedule. In practice that splits everything into three classes — what you must keep, what a vendor holds for you, and what you never write down at all.

The principle comes from data-protection law: the GDPR names it in Article 5, and Nepal's Individual Privacy Act 2018 gives the idea local force. Engineers can treat it as a plain design constraint — fewer columns, shorter retention, smaller blast radius, meaning the total harm one breach can do. A row reading "customer 4821 passed a document check, vendor X, 3 March" can sit in Postgres for years without costing you sleep. A bucket of forty thousand passport scans cannot.

Why does over-collection become a production liability?

Every stored passport scan widens the blast radius of your next bad day. A leaked table of verdicts — references, timestamps, pass or fail — reveals almost nothing usable. A leaked table of documents enables identity theft, triggers years of notifications and turns a two-hour incident call into a six-month project.

Three costs stack up. First, access sprawl: support tooling, CRM syncs, analytics exports and staging restores all inherit sensitive columns nobody remembers adding. Second, breach scoping: every stored artifact must be assessed, notified and explained. Third, deletion requests: answering a right-to-erasure ask is quick when the mandate is a five-field table. A common mistake we see is reaching for encryption first. Your application holds the key, so an attacker who takes the database usually takes the key too. Not holding the data beats holding it encrypted.

What must you keep by law — and what can you delete today?

Retention cuts both ways: AML rules aligned with FATF standards commonly require identification records to survive at least five years after a relationship ends, while nothing obliges you to keep raw scans once the check has passed. Read your regulator's directive, then split the record — decision kept, documents discarded.

In Nepal that directive usually arrives via Nepal Rastra Bank's AML and KYC guidance for banks, wallets and lenders; the shape is similar abroad. Note the genuine conflict: when a customer invokes a right to erasure, AML retention overrides it for the mandated set. Everything outside that set should be deletable by a job, not defended case by case.

Store, vault or purge: treating each KYC artifact correctlyRows mapping each kind of identity data to its correct storage treatment.Store, vault or purge: each artifact's treatmentKeepVerification outcome, method, reference and timestampVault itDocuments the law requires: encrypted, isolated, auditedPurgePassport scans and selfies once the check has passedPurgeAny extra ID you collected but the check never neededNever logIdentity fields in logs, error trackers or analytics
How each kind of KYC artifact should be treated: keep the decision record, vault only what the law demands, purge scans and extras on a schedule, and never let identity fields reach logs or analytics.

How should a collect–verify–discard flow actually work?

A minimised flow runs in four moves: capture once, verify through a provider or a controlled queue, write the decision to your own database, then purge artifacts automatically. The design goal is simple — raw documents should never touch your application servers, your logs or your backups.

Two patterns cover most cases. In the vendor-held pattern, onboarding opens the provider's hosted screen — an SDK in your Flutter or native app, a redirect on the web — and the customer photographs their document there. A webhook returns a reference, a decision and a score; your servers never carry the bytes. In the self-held pattern, uploads go from the browser straight to a private object store via a pre-signed URL, a time-limited upload grant, and a purge job removes objects once verification completes. Pick the first unless a regulator requires documents under your direct control. If a human must review, give them a restricted queue with watermarked, time-boxed access — never the main database.

How do you implement store-the-decision, step by step?

Implementation is mostly subtraction: strip fields, move the capture point, then automate deletion. Work through the sequence below in order. Each step is small and reversible on its own, so you can stop between steps without leaving the system half-migrated.

  1. Inventory everything. List every table, log, bucket, spreadsheet and third-party tool where identity data lands today — error trackers, analytics events and CRM syncs included. You cannot minimise what you have not mapped.
  2. Define the minimal record. Agree the exact columns you will keep: outcome, method, provider reference, timestamp, re-verification date. Everything else becomes a deletion candidate.
  3. Move the capture point. Switch onboarding to the provider's hosted SDK or a pre-signed upload into a private bucket. Before the first file moves, enable Block Public Access for S3 or your cloud's equivalent — public buckets are how these stories reach the news.
  4. Purge the back catalogue. This deletes documents permanently, so treat it as destructive: export to encrypted offline media only if your retention policy truly requires it, get written sign-off, then remove old objects and truncate legacy tables. There is no undelete.
  5. Lock what remains. Restrict reads on the identity table to a single service role. PostgreSQL row-level security enforces this inside the database, so even a leaked application session cannot select its way to the vault:
ALTER TABLE kyc_verifications ENABLE ROW LEVEL SECURITY;
ALTER TABLE kyc_verifications FORCE ROW LEVEL SECURITY;
CREATE POLICY kyc_service_read ON kyc_verifications
  FOR SELECT TO kyc_service
  USING (true);

Web and support roles get no policy at all, so their queries return nothing.

  1. Scrub the edges. Drop identity fields from application logs, set the error tracker to strip request payloads, and keep personal data out of Redis unless the key carries a short TTL.
  2. Automate retention. Add the bucket lifecycle rule — it deletes objects permanently, so set the window before enabling it — plus a scheduled purge. On Laravel, define prunable() on the model and schedule php artisan model:prune; run it with --pretend first to preview the deletions.

Which settings decide whether minimisation actually holds?

Three settings quietly decide whether minimisation holds: object storage lifecycle rules that delete without a human, log scrubbing at the framework boundary, and backup retention that expires almost as fast as production. Miss one, and data you believed deleted survives in a snapshot or an error tracker.

Backups deserve the sharpest look, because they defeat careful deletion by design: a row removed on Tuesday still sits in Sunday's snapshot until retention lapses. The cleanest mitigation is upstream — if discarded artifacts never reach your systems, no backup ever contains them. Watch environments too: teams restore production snapshots into staging for realistic testing, and suddenly every developer has a copy of the vault. Mask or synthesise instead. And check gateway logs; load balancers can capture request bodies by default.

How do you prove nothing sensitive is hiding anywhere?

Verification is a quarterly drill: query the database for rows older than policy, search logs for identity patterns, and restore one backup to confirm expiry actually works. Twenty minutes per system catches drift long before an auditor — or an attacker — does.

  • Count stale rows: SELECT count(*) FROM kyc_documents WHERE created_at < now() - interval '30 days'; — expect zero, not "a few old ones".
  • Search logs and your Loki indices for sixteen-digit runs and name-plus-date-of-birth pairs; hits mean the scrubber has a gap.
  • Restore the latest backup to a scratch instance and rerun the stale-row query. Backups that forget on schedule are the goal.
  • Open the vendor dashboard and confirm the retention setting is still on — settings do get reset during platform migrations.
  • Count the humans who can open a raw document today. If the answer is "most of support", the access model is wrong.

How does minimisation quietly break — and what do you check first?

Breakage is never dramatic: a developer logs the request body during an incident, a support tool starts showing full documents, a vendor's retention toggle resets during an upgrade. Check in this order — logs, then admin views, then vendor settings — because each rules out a whole class of leak.

When a check fires, confirm the source before scrubbing: a Loki query over the incident window tells you whether the leak is application logs, gateway logs or the error tracker replaying payloads. Fix the emitter first; deleting copies afterwards is cleanup, not the cure. The repeat offenders:

  • Debug-logging whole request bodies "temporarily", then never removing it.
  • Document previews visible to every agent through one shared admin login.
  • Scans in the same Postgres table as everything else, so one careless SELECT * exposes the vault.
  • Production snapshots restored into staging, unmasked.
  • The "we might need it later" bucket, which becomes everyone's liability.

Which storage approach should you choose?

Choose by who carries the risk: a verification provider that retains nothing leaves you the smallest target, a provider vault suits regulated teams that need audited artifacts, and self-hosting earns its keep only when a regulator demands documents under your direct control. Most businesses should pick the first option.

ApproachWhat you holdFitsWatch out for
Provider discard modeDecision, reference, timestampMost onboarding: wallets, marketplaces, portalsRe-checks need recapture; read the contract
Provider vaultA token pointing at vendor-held filesRegulated teams needing audited artifactsLock-in — keep the account in your name
Self-hosted vaultEncrypted object store, isolated schemaRegulators demanding local custodyYou own patching, access reviews, breach response
Full copy in main DBEverythingAlmost nobodyLargest blast radius — the anti-pattern this article retires

Cost follows data volume and retention: vendor charges rise with stored artifacts, while self-hosting swaps fees for engineer hours on patching and access reviews. Confirm current figures with each vendor's calculator, or ask us for a quote.

What does this look like in a real business?

Picture a Kathmandu lending platform onboarding a few hundred customers a day. Before minimisation it holds three years of scans in one bucket, synced into a CRM and copied across every backup. After a short refactor it holds one verdict row per customer. Onboarding time barely moves.

The after-state works like this: the app opens the provider's SDK, the backend writes outcome, method, reference and timestamp, and the provider purges artifacts on a 30-day retention setting. Support sees a verified badge, not a document viewer. When auditors ask for identification records five years on, the team exports a small table that satisfies the directive without holding a single scan. This is how we structure record-keeping in the custom systems we build — see, for instance, our work for Moksha Legal Group — and the principle holds for wallets, portals and internal tools alike. The blast radius of a bad day drops from everyone's identity documents to a list of verdicts.

Lifecycle of one minimised KYC record, from capture to final deletionA timeline showing when a record is created, when artifacts are purged and when legal retention ends.Lifecycle of one verified customer recordDay 0Verify andstore verdictDay 1ArtifactspurgedMonthlyPurge jobre-runsClosureRetentionclock starts+5 yearsFinal, safedeletion
The retention timeline for a minimised record: the verdict is stored on day zero, raw artifacts are purged within a day, the purge job re-runs monthly, and deletion completes once the multi-year retention period lapses.

In short: store the verdict, not the paperwork; let the vendor or a lifecycle rule hold whatever must exist. Keep only what your regulator's retention schedule demands, automate every other deletion, and audit quarterly — logs, admin access, backups, vendor settings. Drift, not design, is what leaks.

People also search for

Planning onboarding for a wallet, a lender or a customer portal — or inherited a system with a growing document pile? Our team can map where identity data lands, put the purge on rails and hand over a setup your own staff can operate. Start from our services or contact us for a review; the code, accounts and records stay yours either way.

Frequently asked questions

  • Collecting only the personal data strictly needed to verify identity and meet legal obligations — for example, the result of a document check rather than the passport scan itself. Under GDPR Article 5(1)(c) it is a formal principle, not a preference: if a field has no verification purpose or retention basis, it should not be stored at all.

  • When regulation or risk demands it: financial services and money transmission trigger AML/CFT obligations, age-restricted goods require age verification, and some marketplaces face seller-identity rules. If no obligation applies, simpler signals — verified email, payment-provider identity, fraud scoring — often suffice. Over-verification creates obligations too, because once you hold identity documents you must protect and eventually delete them.

  • Route the check through an identity verification provider such as Onfido, Sumsub or Persona: applicants upload documents to the vendor, and you store only the returned decision, timestamp and reference ID. Verify the provider's retention settings yourself so raw images and extracted fields are purged on their side soon after the check completes.

  • Two clocks run in opposite directions. AML rules commonly require keeping verification records for five to ten years depending on jurisdiction, while GDPR's storage limitation says data must not be kept longer than necessary. The practical fix is a written retention schedule per data category, automated deletion jobs, and confirmation from your regulator or counsel on the exact period.

  • Encrypt identity records at rest with keys held in a managed KMS, restrict document access to named staff through least-privilege roles, and log every read of verification data so access stays auditable. Rehearse the breach path too: stolen passport scans trigger notification duties and real harm to customers, so the blast radius of any compromised credential must stay small.

  • Every extra document raises breach impact: a leak of passport scans is reportable and directly harmful to customers, while a leak of pass/fail flags usually is not. Over-collection also surfaces in subject access requests, complicates deletion, and regulators treat weak minimisation as an aggravating factor when setting GDPR penalties.

  • Logs, error trackers and analytics. Webhook payloads from verification vendors, request bodies, stack traces and screenshots pasted into tickets frequently carry names, dates of birth or document images. Debug by grepping log storage and crash reporting for sample identities, then add redaction filters, strip raw payloads before persisting, and shorten log retention.

  • Run a data inventory first: list every table, bucket, third party and backup holding identity data, including vendor dashboards. Then test it — submit a subject access request under GDPR Article 15 against a test account and check the export contains nothing beyond your retention schedule. Re-run the audit after any release that changes onboarding or verification flows.

  • Let someone else carry it: reuse identities your customers already hold — sign-in with a bank-based scheme, Apple or Google, or national digital identity wallets — and store only the assertion. Verifiable credentials with selective disclosure go further, proving "over 18" without revealing a birth date. The trade-off is dependency on a third party's uptime and per-check fees.

  • Vendor per-verification fees dominate, plus whatever storage, encryption and audit logging you keep, and one-off work: data mapping, a retention schedule, deletion automation and a DPIA if processing is large-scale. Ongoing overhead is modest once deletion jobs and access reviews are routine. Our team can help you scope the review — reach us through /contact.

0 comments

Be the first to share your thoughts.

Leave a comment

Chat on WhatsApp