Skip to content

About

Privacy-preserving credit risk scoring API: DP-SGD + API hardening defending against membership inference and model extraction (307K records, <1% AUC drop at ε=2.0)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

SentinelAI

Privacy-preserving credit risk scoring API with DP-SGD defense against Membership Inference and Model Extraction attacks.

Trained on 307K real loan applications. Achieves <1% AUC drop at ε=2.0 while providing a formal differential privacy guarantee (ε=2.0, δ=1e-5).

PyTorch FastAPI Opacus Python License: MIT


The Problem

Credit scoring models served via APIs face three simultaneous threats:

Threat 1 — Membership Inference Attack (MIA). An adversary queries the API to determine whether a specific person's financial records were used in training. This violates GDPR Article 22 and the Fair Credit Reporting Act.

Threat 2 — Model Extraction. An attacker clones the proprietary model with fewer than 10K API queries (Tramèr et al.), with no access to training data.

Threat 3 — Fairness Degradation. Standard DP-SGD defenses can disproportionately hurt underrepresented groups (Bagdasaryan et al., NeurIPS 2019).

Existing work addresses these threats in isolation. SentinelAI provides a unified pipeline: DP-SGD training, MIA evaluation, extraction defense, fairness auditing, and API hardening — all on real financial data at scale.


Architecture

Home Credit Dataset
(307K records, 122 features)
        |
        v
Data Preprocessing         <-- SMOTE to 25%, median impute, MinMax scale
+ Fairness Baseline            165 features after encoding
        |
        v
DP-SGD Training (Opacus)   <-- epsilon in {0.5, 1.0, 2.0, 4.0, 8.0}
        |
        v
FastAPI Deployment          <-- JWT auth + rate limiting + label-only output
        |
   /v1/predict
        |
        +-------> MIA Simulation (confidence-based RF classifier)
        |
        +-------> Model Extraction (KnockoffNets, 10K query budget)
        |
        v
Evaluation: Privacy x Utility x Fairness

Neural architecture: MLP with Input(165) → 256 (GroupNorm, ReLU, Dropout 0.3) → 128 → 64 → 2 (Softmax). GroupNorm replaces BatchNorm for Opacus compatibility — BatchNorm's cross-batch statistics break per-sample gradient isolation required by DP-SGD.


Results

Three-State Evaluation

Metric Normal Service Under Attack With Defense (ε=2.0)
Model AUC-ROC 0.7430 0.7430 0.7369 (−0.8%)
MIA Attack Advantage — 0.0049 0.0110
Extraction Fidelity (10K) — 0.9295 0.9087 (label-only)
Fairness AIR (gender) 1.2636 1.2636 1.0431
Equalized Odds Diff 0.1481 0.1481 0.0523
Privacy Guarantee None None ε=2.0, δ=1e-5

Key Findings

DP-SGD at scale costs almost nothing. Published literature predicted 15–20% AUC degradation. We measured under 1% across all epsilon values. The 307K training samples absorb the gradient noise — prior papers used much smaller datasets.

MIA attack advantage stays near zero. All six models fall under the 0.05 target threshold. DP-SGD adds a formal mathematical guarantee on top of the near-zero empirical resistance.

Two threats need two defense layers. Following ML-Doctor (2022), DP-SGD actually worsens model extraction by smoothing the decision boundary. DP-SGD handles MIA; API hardening handles extraction. Rate limiting at 50 req/hr makes a 10K-query extraction attack take 200+ hours.

DP improved fairness. Contradicting Bagdasaryan et al. (NeurIPS 2019), DP-SGD reduced Equalized Odds Difference from 0.148 to 0.052 on this financial dataset. First simultaneous measurement of all three on real financial tabular data at this scale.

Full numeric results: results/phase2_results.json

Three-way trade-off — Privacy × Utility × Fairness: Three-way tradeoff

MIA attack advantage across all epsilon values (lower = better privacy): MIA attack advantage

Three-state dashboard — Normal Service / Under Attack / With Defense: Three-state dashboard

Extraction defense — attack time with and without rate limiting + DP-SGD: Extraction defense timeline


Project Structure

sentinelai/
├── api/
│   ├── __init__.py
│   └── main.py              # FastAPI: JWT auth, rate limiting, label-only output, PII redaction
├── models/
│   ├── __init__.py
│   └── mlp.py               # CreditRiskMLP: 165 -> 256 -> 128 -> 64 -> 2
├── notebooks/
│   └── SentinelAI.ipynb     # Full experiment pipeline with all outputs
├── results/
│   ├── phase2_results.json  # All experimental metrics
│   └── README.md            # Describes all generated output files
├── train_baseline.py        # Standalone training script (supports --demo flag)
├── requirements.txt
├── .gitignore
└── README.md

Model weights, preprocessing artifacts, and the dataset are excluded from the repo (see .gitignore). All outputs are reproducible by running the notebook.


Getting Started

1. Clone and install

git clone https://github.com/siri423/sentinelai.git
cd sentinelai

# numpy must be installed first
pip install numpy==1.26.4
pip install -r requirements.txt

2. Dataset

Home Credit Default Risk — 307,511 records, 122 features, 8.1% default rate.

Download from Kaggle. Place application_train.csv in a data/home_credit/ directory, or set DATA_DIR in the notebook.

3. Run in Google Colab (recommended for full pipeline)

Open notebooks/SentinelAI.ipynb. Set runtime to T4 GPU. Run Cell 1, restart runtime, then run all remaining cells. Total runtime: ~35 minutes on T4.

4. Baseline training only (local)

# Quick demo on synthetic data, no download required
python train_baseline.py --demo

# On the real dataset
python train_baseline.py --data_dir data/home_credit/

5. Run the API

uvicorn api.main:app --reload --port 8000

# Get a JWT token
curl -X POST http://localhost:8000/token \
     -d "username=demo&password=secret"

# Make a prediction (replace <token>)
curl -X POST http://localhost:8000/v1/predict \
     -H "Authorization: Bearer <token>" \
     -H "Content-Type: application/json" \
     -d '{"features": [0.5, 0.3, 0.8, ...], "applicant_id": "APP_001"}'

# Health check (no auth)
curl http://localhost:8000/health

The API returns label only (DEFAULT or NO_DEFAULT). Raw probabilities are never exposed.


API Defense Layers

Layer Mechanism Threat Addressed
1 JWT HS256 authentication Unauthorized access
2 Rate limiting (50 req/hr per IP) Model extraction (10K queries = 200+ hrs)
3 Label-only output Confidence score harvesting
4 DP-SGD training (Opacus) Membership inference
5 PII auto-redaction in logs Data leakage through access logs
6 Pydantic input validation Malformed / injection inputs
7 CORS middleware Cross-origin attacks

Implementation Notes

Why GroupNorm instead of BatchNorm? Opacus requires per-sample gradient computation. BatchNorm aggregates statistics across the entire batch, which conflicts with this. GroupNorm(num_groups=1) normalizes per sample, making the architecture fully DP-SGD compatible without architectural changes.

Why SMOTE to 25%, not 50%? The raw dataset has an 8.1% default rate. Oversampling to 25% balances the learning signal without generating excessive synthetic duplicates that would inflate MIA vulnerability through artificial memorization.

Why train-only imputation? Fitting the median imputer only on training data prevents information leakage from validation and test sets into preprocessing, which would inflate all downstream metrics.


Authors

Sirichandana Bikkasani · Lavanya Kovi · Sai Yaswanth Reddy Suram

MS Computer Science / MS Analytics · Georgia State University · Spring 2026

About

Privacy-preserving credit risk scoring API: DP-SGD + API hardening defending against membership inference and model extraction (307K records, <1% AUC drop at ε=2.0)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages