The two paths
RBI Master Direction KYC. Video-based Customer Identification Process (V-CIP). A live video call with an authorised official; ID document capture; liveness check; declaration. Suitable for full-KYC accounts with high transaction limits.
Aadhaar Offline KYC. XML-signed by UIDAI, downloaded by the customer, uploaded to your service. Signature verification against UIDAI’s public key. Suitable for limited-KYC use cases (deposit accounts up to a ceiling, small transactions).
Both are RBI-approved; different use cases trigger different paths.
When to use which
| Use case | Pathway |
|---|---|
| Full bank account opening | Master Direction V-CIP |
| Deposit account up to ₹50K | Aadhaar OKYC (with reverse-KYC after) |
| Sandbox / lite KYC for product trial | Aadhaar OKYC |
| Enhanced due diligence (high-value customer) | Master Direction + additional documents |
| Re-KYC for existing customer | Master Direction OR Aadhaar OKYC depending on tier |
Most fintechs build both. The customer experience differs: OKYC takes 60-120 seconds; V-CIP takes 10-15 minutes (slot booking + call).
What OKYC actually validates
The Aadhaar OKYC XML contains:
- Name (matching UIDAI records)
- DOB
- Gender
- Address
- A photograph
- A signed timestamp
Verification:
- Parse the XML.
- Verify the signature against the UIDAI public key (rotated annually).
- Decrypt the share-code-protected contents.
- Match the name + DOB against your service’s input.
What it doesn’t validate:
- That the person uploading is the person in the XML. (You need a separate liveness check for that.)
- That the XML is recent. (UIDAI’s signed timestamp tells you when generated; you decide if 30/60/180 days is acceptable for your use case.)
What V-CIP validates
- Live video presence (the person is real and present).
- Document authenticity (the official inspects the ID on camera).
- Identity match (the official compares the document photo to the live face).
- Address (where applicable; some V-CIPs include address verification via geolocation).
V-CIP gives you stronger evidence; OKYC gives you faster onboarding.
The Go implementation shape
// Master Direction V-CIP — most of the complexity is the video pipeline,
// scheduling, and review queue, not the verification itself.
func processVCIP(ctx context.Context, session *VCIPSession) (Verdict, error) {
// Liveness check via the recording
// Document OCR + match against captured fields
// Sanctions screening
// Final verdict; if Approved, persist to the bank's core
}
// Aadhaar OKYC
func processOKYC(ctx context.Context, xml []byte, shareCode string) (Profile, error) {
decrypted, err := okyc.DecryptZip(xml, shareCode)
if err != nil { return Profile{}, err }
if err := okyc.VerifyUIDAISignature(decrypted, uidaiPublicKey); err != nil {
return Profile{}, ErrSignatureInvalid
}
if time.Since(decrypted.GeneratedAt) > 60*24*time.Hour {
return Profile{}, ErrOKYCExpired
}
return decrypted.Profile, nil
}
The audit shape
For each KYC, the audit log captures:
- Path taken (V-CIP / OKYC / both).
- Decision (Approved / Rejected / Pending review).
- Reason codes (sanctions hit, document mismatch, etc.).
- Operator ID for V-CIP (who reviewed the call).
- Hash of the supporting documents (not the documents themselves; storage is separate, KMS-encrypted).
A regulator’s audit ask is usually: “show me 50 random KYC decisions from last month; explain each.” The audit row plus the document store should make this a 30-minute exercise, not a week of compilation.
Genie’s approach
agents/kyc_orchestrator implements both paths as separate decision trees. The supervisor decides which path based on the use case. The audit chain is unified across both. The patterns are documented at the agent-doc level; the implementation is reviewable Go.
For any Indian fintech doing KYC, both paths are non-negotiable. The implementation effort is similar; the operational maturity is what differs (V-CIP requires a trained-operator team).