Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

DriveAuth Edge

CI License Python Coverage Version

Trust/Risk-separated biometric authorization for in-vehicle payments and sensitive commands. Extracted from Nova AI pipeline_mp/driveauth/.

Requires Python 3.11+ · MVP 1.0.0

Fresh clone → run

python3.11 -m venv .venv && source .venv/bin/activate
make install
cp secrets.env.example secrets.env
# Set DRIVEAUTH_DASHBOARD_API_KEY=...  (or ALLOW_INSECURE for localhost only)
make bootstrap          # Stage-1 models + Stage-2 checklist (never silent)
make test
DRIVEAUTH_USE_MOCK=1 DRIVEAUTH_ALLOW_INSECURE_DASHBOARD=1 make demo
# → http://127.0.0.1:8765

OpenAPI: docs/openapi/openapi.json · Contributing: CONTRIBUTING.md · Security: SECURITY.md

Tech stack

Layer Stack
Core Python 3.11+, NumPy, PyYAML, cryptography · Hatchling
API / UI FastAPI, Uvicorn · demo capture: Pillow, Playwright
Voice PyTorch + SpeechBrain (ECAPA-TDNN / VoxCeleb)
Face OpenCV + ONNX Runtime (MobileFaceNet / ArcFace)
Finger / behavior ONNX (FingerNet-lite, behavioral LSTM)
Risk / fusion / PAD LightGBM → ONNX · scikit-learn / logreg → ONNX
Orchestrator PolicyMLP ONNX (static trust weights if absent)
Train / export LightGBM, scikit-learn, onnxmltools, skl2onnx, onnx
Dev pytest, ruff, pytest-cov

Policy is deterministic YAML rules (not another ML head). Extras: .[dashboard], .[voice,face,onnx], .[standalone], .[all].

Demo

Dashboard presets: Micro payment → ACCEPT, Low voice → Face ACCEPT, Low biometrics → REJECT (Voice → Face → Finger ladder).

DriveAuth dashboard: Voice → Face → Finger ladder → ACCEPT or REJECT

Regen: driveauth-dashboard + python scripts/capture_dashboard_demo_gif.py (needs pillow + playwright). Captures the three presets above with live staircase frames.

Design principle

Trust answers: "Is this the enrolled driver?" (voice + face + fingerprint only)

Risk answers: "How risky is this transaction?" (GPS, speed, amount, beneficiary novelty, driving behaviour)

Confidence answers: "Can we trust our own scores this time?" (quality, OOD, modality agreement)

These three scores feed a deterministic Policy Engine — not another ML head — so compliance teams can audit and change rules without retraining models. Architecture, policy bands, and the fraud ladder are shipping.

See architecture/trust-risk-separation.md for score definitions, policy bands, and transaction tiers.

Security: what we assume, enforce, and explicitly do not claim — including fail-closed probes, OOD-refresh gating, optional timing pad, and HW/synth limits — is in docs/security-assumptions.md.

Architecture

Overview (simple)

Sensors and transaction context feed three independent scores; a deterministic policy decides the outcome.

flowchart LR
  subgraph In["Inputs"]
    MIC[Mic / voice]
    CAM[Camera / face]
    FNG[Fingerprint]
    CTX[Amount · GPS · speed · CAN]
  end

  subgraph Ladder["Biometric ladder"]
    V[Voice]
    F[Face]
    G[Finger]
    V -->|high| A1[ACCEPT]
    V -->|low| F
    F -->|high| A2[ACCEPT]
    F -->|low| G
    G -->|match OK| A3[ACCEPT]
    G -->|fail| X[REJECT]
  end

  subgraph Side["Side scores"]
    R["Risk · fraud lock"]
  end

  MIC --> V
  CAM --> F
  FNG --> G
  CTX --> R
  R -->|hard ceiling / locked| X
Loading

System context

flowchart LR
  subgraph Vehicle
    STT[STT / mic]
    IR[IR / DMS camera]
    FP[Fingerprint sensor]
    CAN[CAN / GPS / speed]
  end

  subgraph Edge["DriveAuth Edge"]
    API["DriveAuth API\nauthenticate · intercept · require_auth"]
    ENG[DecisionEngine]
    POL[PolicyEngine]
    API --> ENG --> POL
  end

  subgraph Outcomes
    OK[ACCEPT → LLM / payment]
    NO[REJECT / deny]
    AUD[AuditLog]
  end

  STT --> API
  IR --> ENG
  FP --> ENG
  CAN --> ENG
  POL --> OK
  POL --> NO
  POL --> AUD
Loading

End-to-end pipeline

Non-payment commands (open navigation, play music, …) bypass the payment path entirely in intercept() — no risk scoring, tiering, or OTP.

flowchart TD
  IN["Entry: intercept / authenticate / require_auth"] --> PAY{Payment utterance?}

  PAY -->|No| BYPASS["Forward to LLM\nbio_pass · non_payment"]
  PAY -->|Yes| INTENT["Intent parser\namount · beneficiary · action · currency · channel"]

  INTENT --> CTX["RiskContext + ProfileStore history"]
  CTX --> RISK["RiskModel\nGPS · CAN · amount · beneficiary · behaviour"]
  RISK --> TIER["classify_tier\nmicro · standard · high_value · guest"]
  TIER --> FRAUD["FraudStateMachine\nbootstrap · normal · elevated · heightened · locked"]

  FRAUD --> ESC["Ladder: Voice → Face → Finger"]
  ESC --> QV["1. QualityGate · VoiceMatcher"]
  QV -->|score ≥ ladder.accept_voice| ACC[ACCEPT]
  QV -->|low / no score| QF["2. QualityGate · FaceMatcher"]
  QF -->|score ≥ ladder.accept_face| ACC
  QF -->|low / no score| QG["3. QualityGate · FingerMatcher"]
  QG -->|score ≥ ladder.accept_finger| ACC
  QG -->|fail / unavailable| REJ[REJECT]

  RISK --> HARD{Risk ceiling / fraud lock?}
  HARD -->|Yes| REJ
  HARD -->|No| ESC

  ACC --> POST["AuditLog + profile update + decision cache"]
  REJ --> POST
Loading

Trust / Risk / Confidence separation

flowchart TB
  subgraph Trust["Trust — who is driving?"]
    V[Voice score]
    F[Face score]
    P[Finger score]
    V --> TF[TrustFusion]
    F --> TF
    P --> TF
  end

  subgraph Risk["Risk — how risky is this act?"]
    A[Amount / beneficiary]
    G[GPS / zone / speed]
    B[Behavioural monitor]
    A --> RM[RiskModel]
    G --> RM
    B --> RM
  end

  subgraph Confidence["Confidence — can we trust our scores?"]
    Q[QualityFlags]
    O[OOD flags / missing baselines]
    D[Modality disagreement]
    Q --> CS[ConfidenceScorer]
    O --> CS
    D --> CS
  end

  TF --> RPT[Reporting / audit]
  RM --> HARD[Hard reject gates]
  CS --> RPT
  HARD --> OUT["ACCEPT · REJECT\n(+ guest STEP_UP for PIN)"]
Loading

Behaviour and location never enter Trust — only Risk. Biometric Accept/Reject is decided only by the Voice → Face → Finger ladder.

Biometric ladder (Accept / Reject)

flowchart LR
  V[Voice] -->|conf low| F[Face] -->|still low| G[Finger]
  V -->|conf high| OK[ACCEPT]
  F -->|conf high| OK
  G -->|match OK| OK
  G -->|fail| X[REJECT]
Loading

Probe order is fixed: voice → face → finger.

  • High score (per-modality bar + fraud trust_margin) → ACCEPT immediately:
    • voice ≥ ladder.accept_voice (default 0.72)
    • face ≥ ladder.accept_face (default 0.70)
    • finger ≥ ladder.accept_finger (default 0.70, “match OK”)
  • Low / missing score → escalate to the next modality.
  • After fingerprint (last option) still fails → REJECT.
  • No OTP mid-ladder. Risk hard-ceiling and fraud-lock can still force REJECT. Guest mode may still request PIN (STEP_UP_REQUIRED).
  • Re-baseline with python scripts/calibrate_bio_thresholds.py --store ./driveauth_store_phase2a.
flowchart TD
  START[Payment auth] --> V2["1. Probe voice"]
  V2 --> VOK{score ≥ accept?}
  VOK -->|Yes| ACC[ACCEPT]
  VOK -->|No| F2["2. Probe face"]
  F2 --> FOK{score ≥ accept?}
  FOK -->|Yes| ACC
  FOK -->|No| G2["3. Probe finger"]
  G2 --> GOK{match OK?}
  GOK -->|Yes| ACC
  GOK -->|No| REJ[REJECT]
Loading

Fraud ladder (separate from probe order — raises rigor over time):

stateDiagram-v2
  [*] --> Bootstrap: immature profile
  Bootstrap --> Normal: enough recent txns
  Normal --> Elevated: soft flag
  Elevated --> Heightened: 2nd soft flag / step-up exhaust
  Heightened --> Locked: confirmed fraud
  Elevated --> Normal: clean streak
  Heightened --> Elevated: clean streak
  Locked --> [*]: reset only

  note right of Bootstrap
    force_step_up · full modality set
    amount cap
  end note
Loading

Module map

Layer Module Role
API api.py DriveAuth, Nova intercept() / require_auth(), cache, step-up orchestration
Intent intent.py Deterministic amount / beneficiary / action / currency parse
Orchestration decision_engine.py Quality → staged probes → fusion → policy → fail-closed
Escalation escalation.py Probe plan + early-stop rules
Biometrics matchers/ Voice / face / finger / behavioural (+ mocks)
Quality quality_gate.py Pre-match SNR, blur, brightness, contact, frontal crop
Scores fusion.py, risk_model.py, ood_detector.py, geo.py Trust, Risk, Confidence + GPS → home distance
Policy policy_engine.py Deterministic tiered decisions
State fraud_state.py, profile_store.py Ladder rigor + driver maturity / amount / home
Step-up step_up_otp.py, step_up_fallback.py Cellular OTP → offline PIN + bio recheck
Audit audit_log.py Decision metadata (no raw biometrics)
Types types.py, config.py, policy.yaml Results, context, thresholds via ${ENV:default} placeholders
Manual HW stand-in matchers/score_provider.py ManualScores / DRIVEAUTH_MANUAL_SCORES until sensors

Model blocks

Every ML/DL (and mock) head in the repo. Color key (see diagram fill):

Color Meaning
Green Mock — wired placeholder; replace with a real model
Red Needs training — loader/export path exists, but weights must be trained (or fine-tuned) before use
Blue Pretrained / off-the-shelf — real model wired (Phase 2a); optional domain fine-tune later
Yellow Heuristic / static fallback — runs today without weights; target is a trained model
Gray dashed Planned — not in repo yet
flowchart TB
  classDef mock fill:#c8e6c9,stroke:#2e7d32,color:#1b5e20,stroke-width:2px
  classDef train fill:#ffcdd2,stroke:#c62828,color:#b71c1c,stroke-width:2px
  classDef pretrained fill:#bbdefb,stroke:#1565c0,color:#0d47a1,stroke-width:2px
  classDef heuristic fill:#fff9c4,stroke:#f9a825,color:#f57f17,stroke-width:2px
  classDef planned fill:#eeeeee,stroke:#757575,color:#424242,stroke-width:2px,stroke-dasharray: 6 4

  subgraph Bio["Biometric matchers → Trust"]
    VOICE_R["ECAPA-TDNN\nSpeechBrain · VoxCeleb\nmatchers/voice.py"]
    VOICE_M["MockVoiceMatcher\nmatchers/mock.py"]
    FACE_R["ArcFace-MobileFaceNet\nONNX · matchers/face.py"]
    FACE_M["MockFaceMatcher\nmatchers/mock.py"]
    FINGER_R["FingerNet-lite ONNX\nfingernet_lite_int8.onnx\nmatchers/finger.py"]
    FINGER_M["MockFingerMatcher\nmatchers/mock.py"]
  end

  subgraph RiskPath["Risk path"]
    BEH_R["Behavioral LSTM\nbehavioral_lstm_int8.onnx\nmatchers/behavioral.py"]
    BEH_M["MockBehavioralMonitor\nmatchers/mock.py"]
    RISK_H["RiskModel additive heuristic\nrisk_model.py · fallback"]
    RISK_GBT["risk_gbt.onnx\nLightGBM → ONNX\nrisk_model.py · default"]
  end

  subgraph Fuse["Trust fusion & orchestrator"]
    FUSE_S["TrustFusion static weights\nfusion.py · default today"]
    MLP["PolicyMLP\norchestrator_mlp.onnx\norchestrator.py"]
    LOGREG["Trust fusion logreg\nPhase 4 target"]
  end

  subgraph Conf["Confidence / liveness — planned"]
    OOD["OODDetector\nz-score / cosine stats\nood_detector.py · no NN"]
    AS["Voice anti-spoof"]
    PAD["Face PAD / liveness"]
    SMOL["SmolLM2\nmentioned · not implemented"]
  end

  VOICE_R --> FUSE_S
  VOICE_M --> FUSE_S
  FACE_R --> FUSE_S
  FACE_M --> FUSE_S
  FINGER_R --> FUSE_S
  FINGER_M --> FUSE_S
  FUSE_S -.-> MLP
  FUSE_S -.-> LOGREG
  BEH_R --> RISK_GBT
  BEH_M --> RISK_GBT
  RISK_GBT -.-> RISK_H
  VOICE_R --> OOD
  FACE_R --> OOD
  FINGER_R --> OOD
  VOICE_R -.-> AS
  FACE_R -.-> PAD
  MLP -.-> SMOL

  class VOICE_M,FACE_M,FINGER_M,BEH_M mock
  class FINGER_R,BEH_R,MLP train
  class VOICE_R,FACE_R,RISK_GBT pretrained
  class RISK_H,FUSE_S,OOD heuristic
  class LOGREG,AS,PAD,SMOL planned
Loading

Where each model sits

Block Algorithm Module / artifact Why this model Status today
Voice ECAPA-TDNN matchers/voice.py · SpeechBrain spkrec-ecapa-voxceleb Speaker embedding; cosine vs enrolled voiceprint Blue — Phase 2a pretrained + enrolled (DRIVEAUTH_USE_MOCK=0)
Face ArcFace-MobileFaceNet matchers/face.py · mobilefacenet*.onnx Face embedding match on IR/RGB crop Blue — Phase 2a pretrained + enrolled (own-face)
Finger FingerNet-lite matchers/finger.py · fingernet_lite_int8.onnx Fingerprint embedding / match Green mock / ManualScores until sensor HW + vendor SDK
Behavioral LSTM (or GRU / windowed GBM bake-off) matchers/behavioral.py · behavioral_lstm_int8.onnx Driving-style anomaly → Risk only, never Trust LSTM wired from synth bake-off — re-bake on real CAN before citing FAR/FRR
Risk LightGBM → ONNX risk_model.py · risk_gbt.onnx Tabular txn/GPS/CAN features; audit-friendly attributions Blue — trained on 50k txns (val AUC ≈ 0.9955); additive heuristic if ONNX missing
Trust weights PolicyMLP orchestrator.py · orchestrator_mlp.onnx Context-adaptive voice/face/finger weights + uncertainty Red — optional ONNX; yellow static weights if absent
Trust fusion Logistic regression fusion.py · trust_fusion.onnx Learned Trust from labeled multimodal scores; static weights if ONNX missing Blue — Stage 2 / Phase 4 trained
OOD Stats (z / cosine) ood_detector.py Fail-closed when baselines missing Yellow — no neural net; optional AE later
Anti-spoof / PAD Hand-crafted features → logreg matchers/face_pad_features.py · faces/{id}/face_pad.onnx Presentation-attack gate before face match Blue — Stage 2 (blur/side/screen)
SmolLM2 LLM helper docstring only in orchestrator.py Optional narrative / policy assist Gray — not implemented

Stage-2 bio heads are per-driver (faces/{id}/, voices/{id}/). Store-global: risk_gbt.onnx, trust_fusion.onnx. See docs/stage2-per-driver.md.

Stage 2 heads (wired; frozen ECAPA / MobileFaceNet)

Head Artifact Trainer
Voice calibrator voices/{id}/voice_calibrator.onnx scripts/train_voice_calibrator.py --driver-id
Face PAD faces/{id}/face_pad.onnx scripts/train_face_pad.py --driver-id
Face calibrator faces/{id}/face_calibrator.onnx scripts/train_face_calibrator.py --driver-id
Trust fusion logreg trust_fusion.onnx (store-global) scripts/train_trust_fusion.py
FAR/FRR eval phases/phase2b_bio_eval.json scripts/eval_bio_far_frr.py
Sprint 6 bench phases/phase6_sprint6.json · phase6.md scripts/phase6_benchmark.py
Per-driver migrate copies legacy → faces/{id}/ · voices/{id}/ scripts/migrate_stage2_per_driver.py

Phase 2a latency profiles: phases/phase2a-mac.txt · phases/phase2a-thor.txt (Thor: ECAPA+face CUDA, micro/high p95 ≈ 7.7 / 9.2 ms). Phase 1 mock edge profiles: phases/mac.txt · phases/thor.txt (phases/phase1.md).

Set DRIVEAUTH_STAGE2_RAW=1 to force frozen 2a cosine-only scoring (no PAD/calibrators).

Still planned / HW-gated

Planned model Intended role Replaces / extends
Voice anti-spoof (deep) Replay / synthetic speech gate QualityGate + score calibrator
Real-CAN behavioral re-bake Production FAR/FRR for driving style Current synth bake-off winner
SmolLM2 Optional orchestrator side-channel — (unused)
OOD autoencoder Embedding reconstruction anomaly Current z-score / cosine OOD

Default dashboard path uses mock biometrics + real risk ONNX when present. Hybrid Phase 2a:

python scripts/phase2a_setup.py --store ./driveauth_store_phase2a
python scripts/phase2a_enroll.py --store ./driveauth_store_phase2a --data ./data/driver1
python scripts/phase2a_demo.py --store ./driveauth_store_phase2a

Finger/behavioral: set scores via dashboard Manual stand-ins, DRIVEAUTH_MANUAL_SCORES=…, or apply_manual_scores() until HW modules emit the same ModalityResult(score∈[0,1]). See roadmap-2026-07.md.

Decision cache (second-layer gate)

require_auth() may reuse a fresh STT-layer ACCEPT within DRIVEAUTH_DECISION_CACHE_TTL_S when:

  • cached decision is ACCEPT
  • new transaction tier ≤ cached tier
  • fraud epoch unchanged
  • profile epoch unchanged

Otherwise it re-probes (voice optional at the LLM tool boundary).

Quick start

cd staged_driveauth-edge   # or your clone path
python3.11 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
bash scripts/demo_preflight.sh   # pytest + mock ACCEPT
driveauth-demo
# or: python demo/run_demo.py

Demo flags: --amount, --beneficiary-known, --high-value, --reject-voice.

Web dashboard (two pipelines)

Shared on both pages: Actions · Live security pipeline (Voice→Face→Finger staircase) · Result · Audit log.

Page URL Purpose
Manual / or /manual Slider stand-ins + presets (mock path)
Standalone /standalone OpenRouter STT/TTS · intent slots · Maps GPS · live ECAPA/face
Register /register Capture + enroll · registered-drivers list · Maps home pin
pip install -e ".[dashboard]"          # manual / mock dashboard
# or: pip install -e ".[standalone]"   # + voice/face/onnx for live path
cp secrets.env.example secrets.env     # OpenRouter + Google Maps (standalone)
driveauth-dashboard
# http://127.0.0.1:8765/manual
# http://127.0.0.1:8765/standalone
# http://127.0.0.1:8765/register

Optional: --store ./demo_store for a persistent store, --reload for dev auto-reload.

Register: open /register, pick or create a driver id, capture ≥5 face stills + ≥5 voice clips (data/<id>/{face,voice}/enroll/), mark home on Maps, then Enroll into store. The page lists every known driver with enrollment status. Needs Phase 2a models (python scripts/phase2a_setup.py). Paths: DRIVEAUTH_REGISTER_STORE / DRIVEAUTH_DATA_ROOT / secrets.env.

Standalone product (shipping): OpenRouter STT/TTS/intent, live ECAPA/face, Maps GPS, and the three pages above — details in docs/standalone.md.

Public demo: cloudflared tunnel --url http://127.0.0.1:8765 (Mac must stay awake). Always-on Railway /data volume is still open (see What's left).

Phase 2a real voice/face (hybrid)

pip install -e ".[voice,face,onnx,dev]"
python scripts/phase2a_setup.py --store ./driveauth_store_phase2a
python scripts/phase2a_enroll.py --store ./driveauth_store_phase2a --data ./data/driver1
python scripts/phase2a_demo.py --store ./driveauth_store_phase2a \
  --face-image data/driver1/face/enroll/enroll_01.jpg

Finger / behavioral scores for demos:

python scripts/phase3_synth_demo.py --store ./driveauth_store_phase2a --scenario happy
# or: export DRIVEAUTH_MANUAL_SCORES=phases/manual_scores_fail.json

Programmatic use

from driveauth import DriveAuth
import numpy as np

auth = DriveAuth.load(store_dir="./store", use_mock_matchers=True)
auth.update_vehicle_context(
    gps_lat=12.97, gps_lon=77.59, gps_accuracy_m=8.0,
    speed_kmh=0.0, ignition_on=True,
)
result = auth.authenticate(
    audio_np=np.zeros(16000, dtype=np.float32),
    amount=150.0,
    beneficiary="Starbucks",
    beneficiary_known=True,
)
print(result.decision, result.legacy_decision, result.trust_score, result.risk_score)

Decisions: ACCEPT, REJECT from the biometric ladder; STEP_UP_REQUIRED remains for guest PIN / OTP fallbacks only (Nova aliases: pass, step_up, deny).

Phase 3 data

Min sets are in place: voice · face (own-face) · synth finger/CAN/OOD · 50k txns. See data/README.md. Layout under data/driver1/:

Path Contents
voice/ enroll · genuine · noisy · attack_*
face/ enroll · genuine · attack_blur / side / replay_screen
finger/ · behavioral/ · ood/ Synth via scripts/generate_phase3_synth.py until HW
transaction/ 50k txn rows for the Risk head
python scripts/generate_phase3_synth.py
python scripts/calibrate_bio_thresholds.py --store ./driveauth_store_phase2a --apply

Examples

Script What it shows
examples/basic_auth.py Minimal mock-matcher authentication
examples/payment_step_up.py High-value payment + vehicle context → step-up
scripts/phase2a_demo.py Real ECAPA + MobileFaceNet hybrid auth
scripts/train_behavioral_bakeoff.py LSTM vs GRU vs windowed GBM → best → behavioral_model.onnx
scripts/train_trust_fusion.py Stage 2 trust logreg → trust_fusion.onnx
scripts/eval_bio_far_frr.py Voice/face FAR/FRR vs baseline (phase2b_bio_eval.json)
scripts/phase6_benchmark.py Sprint 6 table + ablations → phases/phase6.md

Testing

pip install -e ".[dev]"
pytest

160+ tests cover fail-closed paths, cache invalidation, geo/home learning, score provider, Sprint 1 security (constant-time pad + OOD-refresh gate), Phase 5 (threshold re-baseline + real-model timeout/crash), Phase 6 / Sprint 6 benchmarks (FAR/FRR/EER/ROC · PAD · risk · latency · vs OTP/MFA/staged), integration e2e, mid-disconnect recovery, fingerprint adapter selection, and perf telemetry — see phases/phase5.md · phases/phase6.md.

Documentation

Phase 7 docs are in place: this README, demo GIF, security assumptions, and LinkedIn/Medium drafts (docs/public-posts.md; publish URLs still open). Phase 8 drafts live under docs/paper/ — see What's left.

Doc Contents
architecture/overview.md Pipeline diagram and module map
architecture/trust-risk-separation.md Trust, Risk, Confidence scores and policy tiers
docs/security-assumptions.md Threat model, invariants, non-claims, integrator checklist
docs/install-guide.md Pi 5 / local install, extras map, Docker compose
docs/troubleshooting.md Sensor / BT / Hailo / fresh-clone failures (real log lines)
docs/api-reference.md DriveAuth methods + DriveAuthResult fields
docs/public-posts.md LinkedIn / Medium drafts (Phase 7)
phases/phase8.md · docs/paper/ White paper · IV 2027 draft · demo storyboard
roadmap-2026-07.md Current roadmap — phases, sprints, non-goals
TODO.txt Working checklist (deferred HW / Nova GPS / publish called out)
docs/standalone.md Standalone product: OpenRouter STT/TTS, Maps, Cloudflare tunnel, Railway
docs/pipeline-fixes-2026-07.md Risk-pipeline fix bundle details
docs/configuration.md policy.yaml placeholders and DRIVEAUTH_* overrides
docs/integration.md Nova ↔ DriveAuth I/O contract, STT intercept, GPS/CAN
data/README.md Phase 3 capture layout + synth generators
phases/phase6.md Sprint 6 FAR/FRR/EER · PAD · risk · latency · ablations

Repository layout

Drive_auth_edge/
├── README.md · TODO.txt · roadmap-2026-07.md
├── secrets.env.example    # copy → secrets.env (gitignored)
├── Dockerfile · Dockerfile.edge · docker-compose.yml · railway.toml
├── pyproject.toml
├── architecture/          # Design docs + diagrams
├── dashboard/             # /manual · /standalone · /register · /fleet
├── demo/                  # CLI demo (mock matchers)
├── hardware/              # finger daemon · BT OTP · CAN · Hailo · actuation
├── data/                  # Phase 3 datasets (biometrics gitignored)
├── scripts/               # install.sh · setup_pi.sh · phase2a_* · calibrate_*
├── phases/                # calibration JSON, timing notes, Sprint 6
├── driveauth/
│   ├── api.py             # Public DriveAuth API (+ Nova intercept())
│   ├── perf_telemetry.py  # Always-on latency / CPU-RAM CSV
│   ├── secrets.py · openrouter_client.py · standalone_session.py
│   ├── audio_io.py · enrollment.py · geo.py · intent.py
│   ├── config.py · policy.yaml
│   ├── decision_engine.py · escalation.py · fusion.py
│   ├── matchers/          # voice · face · finger · behavioral · score_provider
│   ├── risk_model.py · fraud_state.py · profile_store.py
│   ├── quality_gate.py · ood_detector.py · orchestrator.py
│   ├── step_up_otp.py · step_up_fallback.py · audit_log.py
│   └── types.py
├── tests/
├── examples/
└── docs/                  # install · troubleshooting · api-reference · security

Nova AI integration

Replace:

from driveauth.gate import DriveAuthGate

With:

from driveauth import DriveAuth as DriveAuthGate

Or install editable: pip install -e . (from this repo root)

Set DRIVEAUTH_STORE_DIR and DRIVEAUTH_ENROLL_DIR. Env vars use DRIVEAUTH_* (NOVA_* aliases supported).

Inputs / outputs (payment path): see the dashboard contract panel and docs/integration.md. Nova live GPS is deferred — Maps / dashboard GPS until Nova telematics calls update_vehicle_context each auth:

auth.update_vehicle_context(gps_lat=…, gps_lon=…, gps_accuracy_m=…, speed_kmh=…, ignition_on=…)

Optional dependencies

Extra Purpose
voice ECAPA-TDNN via SpeechBrain
face MobileFaceNet ONNX + OpenCV
onnx Risk model + orchestrator MLP
orchestrator Dynamic trust weights (PolicyMLP)
dashboard FastAPI web UI + pipeline API
finger R307/AS608 UART via pyfingerprint
bluetooth BlueZ MAP / BLE GATT ladder OTP
gpio RPi.GPIO actuation relay
can python-can logger
hardware finger + bluetooth + gpio + face + can
perf psutil for always-on latency/CPU CSV
dev pytest + ruff + psutil
all All of the above

Install helpers: scripts/install.sh · Pi first-boot: scripts/setup_pi.sh · guide: docs/install-guide.md.

What's left

Code-side MVP (this repo)

Item Status
R307/AS608 UART adapter + daemon auto-detect Shipped (hardware/finger_uart.py)
Full-pipeline Docker + compose Shipped (Dockerfile.edge, docker-compose.yml)
One-command install / Pi setup scripts Shipped (scripts/install.sh, setup_pi.sh)
Always-on inference latency + CPU/RAM telemetry Shipped (driveauth/perf_telemetry.py, /fleet panel)
End-to-end + mid-disconnect recovery tests Shipped (tests/test_integration_e2e.py, test_phase6_failure_recovery.py)
Install / troubleshooting / API docs Shipped under docs/

Still needs hardware / people (not faked here)

Gap Required to complete
Deploy + validate on a real Pi 5 Flash OS, run setup_pi.sh, wire sensors
Real Hailo .hef convert + benchmark Device + vendor SDK
Real CAN-HAT validation HAT + vehicle bus
Bluetooth MAP vs real head unit Paired phone + BlueZ MAP agent
5–20 user behavioral dataset Capture under data/*/behavioral/
24–48h stress test Live vehicle / bench soak
Demo video + IV 2027 slides Record / author (phases/phase8.md)
Nova live GPS Wire telematics → update_vehicle_context each auth
Policy bar refresh Re-check after Stage 2; do not apply phases/phase2b_suggested.env until face overlap is acceptable
Phase 7 publish Post LinkedIn/Medium from docs/public-posts.md

Full checklist: TODO.txt · plan: roadmap-2026-07.md.

License

Apache License 2.0 — see LICENSE for the full text.

About

Offline secure Transaction pipeline for in car payments

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages