Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

sachncs/underwrite

Open more actions menu

Repository files navigation

Underwrite

Indian Lending Platform (Beta) — nano-service event-driven architecture with Ed25519 cryptographic attestation.

Python License CI PyPI Stars

A nano-service platform for Indian retail lending. Designed for RBI Digital Lending Guidelines compliance, with DPDPA 2023 data protection and 30+ independently deployable services connected by an event bus with Ed25519 cryptographic attestation.

Beta — not yet production-ready. Known gaps include stubbed PAN / Aadhaar / CKYC / CIBIL integrations, no video KYC, stubbed e-NACH / UPI Autopay mandate collection, basic RBAC only, undocumented disaster-recovery procedures, and rough developer experience (no prebuilt Docker images, no Helm charts, manual service wiring required). See Status below.

Features

  • 31 nano-services — KYC / AML (PAN + Aadhaar Verhoeff), CIBIL / Experian / Equifax credit bureau, CKYC registry, RBI rate-capped pricing, KFS generation, DPDPA consent + DSR, Razorpay PG, risk scoring, fraud detection, collections, recovery, notifications, governance
  • Event-driven — Typed events with Ed25519 signatures, saga orchestration, dead-letter queues, circuit breakers
  • Pluggable backends — Memory / filesystem / Postgres stores; local / SQS / Modal event bus; console / OTLP tracing
  • 1167 tests — Rate limiting, idempotency guards, PII redaction, Prometheus metrics
  • DPDPA 2023 + RBI DLG aligned — Per-product rate caps, all-in-cost APR, penal-interest cap, KFS cooling-off, consent lifecycle, DSR fulfillment, breach notification, auto-purge

Status

This is the v0.9 release line. Security and correctness fixes from the hardening pass:

  • Ed25519 event signatures bind the source and enforce a 5-minute replay window; private keys persist through the configured SecretsManager.
  • /v1/publish binds the publisher identity from the request payload, with an optional authz gate.
  • PII is redacted at the audit, DLQ, and Prometheus tag boundaries with token-based field matching.
  • DLQ, bus buffer, and idempotency guard are bounded against unbounded memory growth.
  • Config redaction covers every secret-shaped field; config data_dir is validated against sensitive system paths.
  • Indian holiday calendar covers 2025–2030 with a sensible fallback for unknown years.
  • KFS APR math, pricing EMI, NPA thresholds, and the underwriter rule engine are all aligned with RBI norms.
  • Real KYC provider integrations — PAN (NSDL/ITD), Aadhaar (UIDAI KUA), CIBIL, and CKYC have full wire-protocol clients in services/kyc_providers/. They are wired into the compliance and credit-bureau services and configured via Configuration.kyc_providers.
  • Production Docker image — multi-stage build, non-root user, healthcheck, OCI labels, Buildx + GitHub Actions workflow. Build with ./scripts/build-image.sh or docker build -t underwrite:dev ..
  • CI matrix 3.10-3.13, coverage gate 80%, ruff format check, TruffleHog secret scan, mypy / bandit / pip-audit.

Remaining work to reach v1.0:

  • Video KYC provider integration (Digilocker, NSDL).
  • Helm chart for k8s deployment.
  • Pre-built multi-arch (amd64 + arm64) images.
  • Read-only underwrite role for psql / Vault operations.
  • Production runbook for on-call (incident response, key rotation, DLQ replay).

Installation

From PyPI

pip install underwrite
pip install "underwrite[risk,serve,postgres,otlp,vault,aws]"

From source

git clone https://github.com/sachncs/underwrite.git
cd underwrite
./setup.sh
source .venv/bin/activate
pip install -e ".[dev,risk,serve,postgres,otlp,vault,aws]"
Extra Provides
risk NumPy, scikit-learn — ML risk models
serve Uvicorn, FastAPI — HTTP server
postgres psycopg2-binary — Postgres state store
otlp OpenTelemetry SDK — distributed tracing
vault hvac — HashiCorp Vault secrets
aws boto3 — SES, SQS, Secrets Manager
security bandit, pip-audit — vulnerability scanning
dev pytest, ruff, mypy, hypothesis, testcontainers

Prerequisites

  • Python 3.10+
  • PostgreSQL 14+ (optional — memory / filesystem backends work without it)
  • Docker (optional — for docker compose up with Postgres + Vault + OTLP)

Quick Start

git clone https://github.com/sachncs/underwrite.git
cd underwrite
./setup.sh
source .venv/bin/activate
python -m pytest tests/ --tb=short -q   # 1167 tests

To run an Indian lending scenario:

underwrite init
# edit underwrite.json to enable: mechanism,audit,risk,fraud,compliance,consent,credit_bureau,kfs,pricing,underwriter,decision
underwrite run mechanism audit risk fraud compliance consent credit_bureau kfs pricing underwriter decision
# In another terminal:
python docs/examples/indian_lending.py
# See docs/QUICKSTART.md for the full walkthrough

CLI

underwrite

Commands:
  init [PATH]              Create default config
  run <service>...         Start one or more services
  list                     List all 31 nano-services
  identity <service>       Generate Ed25519 keypair
  health                   System health status
  dlq [--replay] [--max N] Show or replay dead-letter queue
  metrics                  Metrics snapshot (Prometheus-format on /v1/metrics)
  migrate                  Run pending schema migrations
  serve                    Start HTTP daemon (requires [serve] extra)

HTTP API (with underwrite serve)

Endpoint Method Description
/healthz GET Liveness probe
/readyz GET Readiness probe
/v1/health GET Full system health
/v1/metrics GET Prometheus-format metrics
/v1/publish POST Publish a domain event

Authentication via Authorization: Bearer <token> when started with --require-auth.

Configuration

Configure via JSON file (created with underwrite init), env vars, or both (env vars override). See .env.example for every supported variable — including RBI pricing caps, AML thresholds, credit-bureau API keys, Razorpay credentials, and DPDPA retention periods.

Setting Env Variable Default Description
State backend UNDERWRITE_STORE_BACKEND memory memory / file / postgres
Store DSN UNDERWRITE_STORE_DSN e.g. postgresql://user:pass@localhost:5432/underwrite
Personal-loan rate cap UNDERWRITE_PERSONAL_LOAN_RATE_CAP 0.28 RBI cap
Penal interest cap UNDERWRITE_PENAL_INTEREST_CAP 0.24 RBI cap
Bearer auth UNDERWRITE_REQUIRE_AUTH false Require bearer token on /v1/*

Architecture

Each nano-service extends NanoService with a single handle(event: Event) -> None:

  1. Subscribe — declare interest in event types via config
  2. Dispatch — handler wrapped with authz, idempotency, tracing, metrics, timeout
  3. Emitself.emit(event) signs with Ed25519 and publishes to the bus
  4. Persist — state via Store (MemoryStore / FileStore / PostgresStore)

Cross-cutting concerns (authz, tracing, metrics, sagas, supervisor, circuit breaker) are injected by the bus and runtime — not inherited by services.

Principle Implementation
Event provenance Ed25519 signature on every event, verified before dispatch
Fault isolation DLQ with replay; per-subscriber circuit breaker; per-handler timeout
Security-first No str(default) in signing; joblib gated by env var; bearer auth; PII redaction
RBI compliance Per-product rate caps, all-in-cost APR, penal interest limit, KFS cooling-off
DPDPA compliance Consent lifecycle, DSR fulfillment, breach notification, auto-purge

API

Symbol Type Description
underwrite.NanoService ABC Base class; implement handle(event)
underwrite.__bus__ module Event bus — pub/sub, DLQ, rate limiter
underwrite.__store__ module State store — MemoryStore / FileStore / PostgresStore
underwrite.__saga__ module Saga orchestrator
underwrite.__authz__ module Access control + Ed25519 verification
underwrite.__identity__ module Ed25519 key management
underwrite.__events__ module 105+ event types
underwrite.__pii__ module PII redaction (Aadhaar, PAN, etc.)
underwrite.__config__ module Pydantic configuration (28 sections)
underwrite.__cli__:main function underwrite CLI entry
services.* packages 31 nano-services (mechanism, compliance, pricing, kfs, consent, dsr, credit_bureau, razorpay, risk, fraud, audit, npa, recovery, …)

Project Structure

underwrite/
├── underwrite/                    # Source (90+ modules, fully typed)
│   ├── __config__.py              # Pydantic configuration (28 sections)
│   ├── __bus__.py                 # Event bus — pub/sub, DLQ, rate limiter
│   ├── __store__.py               # State store — memory / file / postgres
│   ├── __saga__.py                # Saga orchestrator
│   ├── __authz__.py               # Access control & Ed25519 verification
│   ├── __identity__.py            # Ed25519 key management
│   ├── __events__.py              # 105+ event types
│   ├── __pii__.py                 # PII redaction (Aadhaar, PAN, etc.)
│   └── services/                  # 31 nano-services
│       ├── base.py                # NanoService ABC
│       ├── mechanism/             # Delegation state machine (core)
│       ├── compliance/            # KYC/AML — PAN category, Aadhaar Verhoeff, risk score
│       ├── pricing/               # RBI caps, APR, EMI, penal interest, foreclosure
│       ├── kfs/                   # Key Fact Statement generation
│       ├── consent/               # DPDPA consent lifecycle
│       ├── dsr/                   # Data Subject Rights fulfillment
│       ├── credit_bureau/         # CIBIL/Experian/Equifax + CKYC
│       ├── razorpay/              # Payment gateway integration
│       ├── risk/                  # ML risk scoring
│       ├── fraud/                 # Fraud detection
│       ├── audit/                 # Event ledger (PII-redacted)
│       ├── npa/                   # Asset classification (SMA/NPA/DLG)
│       ├── recovery/              # Default recovery (store-backed)
│       └── ...                    # 17 more services
├── tests/                         # 58 test files, 1167 tests
└── docs/                          # 9 updated docs for Indian market

Documentation Index

Area Documents
Getting Started Installation · Quickstart (Indian scenario) · Configuration · Env Vars
Architecture Overview · System Design · Domain Model · Design Decisions
Development Guide · Testing · Debugging · Code Style · Build
Operations Deployment · Operations · Observability · Security (DPDPA) · Performance
Reference API · Troubleshooting · FAQ · Glossary
Project Contributing · Maintenance · Roadmap

Development

pip install -e ".[dev,risk,serve,postgres,otlp,vault,aws]"
pytest tests/ --tb=short -q
ruff check underwrite/
ruff format underwrite/
mypy underwrite/
bandit -r underwrite/
pip-audit
mutmut run                     # mutation testing (optional)

Testing

pytest tests/ --tb=short -q
pytest tests/ -x --timeout=30
pytest --cov=underwrite --cov-report=term-missing

The suite contains 1167 tests across rate limiting, idempotency, PII redaction, RBAC, saga orchestration, and Prometheus metrics.

Build

pip install build
python -m build

Release

pytest && ruff check underwrite/ && mypy underwrite/ && bandit -r underwrite/
# Bump version (setuptools_scm derives the version from git tags)
git tag vX.Y.Z && git push origin vX.Y.Z
# .github/workflows/release.yml publishes to PyPI via trusted publishing

Tech Stack

Category Technology
Language Python ≥ 3.10
Cryptography cryptography (Ed25519)
CLI Typer
Config Pydantic
State store Memory / File / Postgres (psycopg2-binary)
Tracing OpenTelemetry SDK + OTLP
HTTP FastAPI + Uvicorn
Secrets HashiCorp Vault (hvac)
Cloud boto3 (AWS), google-cloud-storage (GCS), modal
ML risk NumPy, scikit-learn
Lint / format ruff
Type check mypy
Tests pytest, pytest-asyncio, pytest-cov, hypothesis, testcontainers
Security bandit, pip-audit
Mutation testing mutmut

Roadmap

  • v0.8.x — Current beta: 31 nano-services, 1167 tests, Ed25519 event provenance, RBI/DPDPA-aligned defaults.
  • v0.9.0 — Planned: real PAN (NSDL/ITD) and Aadhaar (UIDAI) integrations; CKYC live lookup; CIBIL production keys.
  • v1.0.0 — Planned: video KYC; e-NACH / UPI Autopay mandate collection; full RBAC; documented DR procedures; Docker images + Helm charts.

Contributing

See CONTRIBUTING.md.

Code of Conduct

This project follows the Contributor Covenant v2.1.

Security

Report vulnerabilities to sachncs@gmail.com — see SECURITY.md.

License

MIT © 2026 Sachin — not legal advice. Consult a qualified attorney before deploying in a regulated environment.

About

Event-driven delegated underwriting for unsecured lending, with typed signed events, saga orchestration, ML risk scoring, and production-ready observability.

Topics

Resources

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.