PyVault
GitHub

Projet en cours de développement  ·  v0.2.0-dev

▄▄▄▄▄▄     ▄▄▄                 ▄▄     
█▀██▀▀▀█▄  █▀██  ██▀▀           ██ █▄ 
  ██▄▄▄█▀    ██  ██             ██▄██▄
  ██▀▀▀██ ██ ██  ██ ▄▀▀█▄ ██ ██ ██ ██ 
▄ ██   ██▄██ ██▄ ██ ▄█▀██ ██ ██ ██ ██ 
▀██▀  ▄▄▀██▀  ▀███▀▄▀█▄██▄▀██▀█▄██▄██ 
        ██                           
        ▀▀▀

Un gestionnaire de mots de passe qui tourne en local, écrit en Python.

PyVault vient d'abord d'une envie toute simple : arrêter de me tromper sur les mêmes mots de passe partout. Au lieu de prendre un outil tout fait, je me suis dit que ce serait plus intéressant d'en construire un — et d'apprendre au passage comment marchent vraiment le chiffrement, les bases de données et tout le reste.

Ce qu'il sait faire aujourd'hui

La base est là. Chaque fonction correspond à un vrai menu dans la CLI, donc tout ce qui est listé ici se teste en deux minutes.

🔑 Générer une clé

Une clé Fernet est créée et écrite dans key.txt. C'est elle qui chiffre et déchiffre tout le reste.

🔐 Ajouter un mot de passe

Le mot de passe est chiffré puis rangé dans la base SQLite (secret/passwords.db), associé à son site.

🔓 Déchiffrer

En donnant la clé et le nom du fichier, PyVault renvoie le mot de passe en clair.

📋 Lister & rechercher

Une liste de tous les fichiers enregistrés, et une recherche par nom quand on en a beaucoup.

🗑️ Supprimer & exporter

Supprimer une entrée, ou tout exporter dans une archive zip d'un coup.

📊 Benchmark

Un notebook Jupyter mesure le temps de chiffrement / déchiffrement selon la taille des données.

python main.py
S. [Stars Project]       Q. [Leave]

        1. [Add Password]   4. [Export (Zipfiles)]
        2. [List Pswd]      5. [Delete Passwd]
        3. [Decrypt Pswd]   6. [Search Website]

        Choices : ▌

Pourquoi je l'ai fait

Je n'aime pas suivre des tutos sans rien retenir. Construire PyVault, c'est une façon de m'obliger à répondre moi-même à des questions du genre :

01

Comment on stocke un secret sans le laisser en clair sur le disque ?

02

Pourquoi une clé d'abord, puis un mot de passe maître ensuite ?

03

Comment passer d'une pile de fichiers à une vraie base de données ?

04

Et si un jour ça devient une interface web, par où on commence ?

Documentation du dépôt

README.md

Le contenu du fichier README, tel qu'il apparaît sur la page GitHub du projet.

🔐 PyVault

PyVault is a local password and secrets manager written in Python.

The goal of this project is to build a simple, private and secure way to store sensitive information locally while learning how encryption, databases and application architecture work.

⚠️ PyVault is currently under development.

✨ Features

Currently available

  • 🔑 Generate Fernet encryption keys
  • 🔐 Encrypt and store passwords using Fernet
  • 💾 Encrypt passwords with Fernet and store them in a SQLite database (secret/passwords.db)
  • 🔓 Decrypt and retrieve stored passwords
  • 📋 List all saved entries
  • 🔎 Search stored passwords
  • 🗑️ Delete passwords
  • 📤 Export passwords
  • 🖥️ Simple CLI interface
  • 🧪 Unit tests
  • 📊 Encryption / decryption benchmark
  • 🖥️ Static website in docs/ (GitHub Pages)
  • 🔐 Interactive browser terminal reproducing the CLI
  • 🔒 Fernet re-implemented in JavaScript (Web Crypto API)
  • 🌍 Bilingual FR / JA website (i18n)
  • 🛡️ On Windows, protect the key on-disk with DPAPI instead of storing it in plain text

Planned

  • 🔑 Master password
  • 🔒 Vault locking
  • 🌐 Local API
  • 🖥️ Web interface

🧠 Why PyVault?

I wanted to create a project that was more than a simple Python script.

PyVault is also a way for me to learn how different parts of a real application work together:

  • Python
  • Cryptography
  • Databases
  • APIs
  • Authentication
  • Security
  • Software architecture
  • Performance testing

Instead of only following tutorials, I want to build the project myself, encounter problems, research solutions and document the entire process.


🏗️ Architecture

The architecture below shows both the current project and the features planned for the future.

flowchart TD

    User["👤 User"]

    PyVault["🔐 PyVault"]

    CLI["🖥️ CLI
CURRENT"] WebTool["🖥️ Web Tool (docs/)
CURRENT"] GenerateKey["🔑 Generate Key
CURRENT"] AddPassword["🔐 Add Password
CURRENT"] ListPasswords["📋 List Passwords
CURRENT"] DecryptPassword["🔓 Decrypt Password
CURRENT"] Fernet["🔒 Fernet Encryption
CURRENT"] JsFernet["🔒 Fernet in JS (fernet.js)
CURRENT"] KeyFile["📄 key.txt (DPAPI on Windows)
CURRENT"] Database["🗄️ SQLite (secret/passwords.db)
CURRENT"] DPAPI["🛡️ DPAPI Key Protection (win32)
CURRENT"] Search["🔎 Search Passwords
CURRENT"] Delete["🗑️ Delete Password
CURRENT"] Export["📤 Export Passwords
CURRENT"] Tests["🧪 Unit Tests
CURRENT"] Benchmark["📊 Benchmark
CURRENT"] I18n["🌍 FR / JA i18n
CURRENT"] MasterPassword["🔑 Master Password
PLANNED"] Vault["🔐 Vault System
PLANNED"] API["🌐 Local API
PLANNED"] FastAPI["⚡ FastAPI
PLANNED"] Web["🖥️ Web Interface
PLANNED"] User --> PyVault PyVault --> CLI PyVault --> WebTool CLI --> GenerateKey CLI --> AddPassword CLI --> ListPasswords CLI --> DecryptPassword GenerateKey --> Fernet GenerateKey --> KeyFile GenerateKey --> DPAPI AddPassword --> Fernet Fernet --> Database DecryptPassword --> Database ListPasswords --> Database CLI --> Search CLI --> Delete CLI --> Export WebTool --> GenerateKey WebTool --> AddPassword WebTool --> ListPasswords WebTool --> DecryptPassword WebTool --> JsFernet JsFernet --> I18n MasterPassword -.-> Vault Vault -.-> Database API -.-> FastAPI FastAPI -.-> Vault Web -.-> API Tests -.-> PyVault Benchmark -.-> Fernet

CURRENT = already implemented
PLANNED = planned for a future version


📁 Current Project Structure

PyVault/

│
├── commands/
│   ├── add.py
│   ├── decrypt.py
│   ├── delete.py
│   ├── export.py
│   ├── generate_key.py
│   ├── list.py
│   └── search.py
│
├── docs/                 ← static website (GitHub Pages)
│   └── static/js/
│       ├── fernet.js
│       ├── tool.js
│       ├── main.js
│       └── i18n.js
│
├── secret/
│   └── passwords.db      ← SQLite database
│
├── tests/
│   ├── benchmark.ipynb   ← Jupyter benchmark
│   └── test_system_info.py
│
├── images/
│   └── new_benchmark.png ← encryption/decryption benchmark
│
├── dpapi_utils.py
├── main.py
├── system_info.py
├── key.txt               ← protected Fernet key
├── SECURITY.md
├── .gitignore
├── LICENSE
└── README.md
                    

🔐 Current Encryption System

PyVault currently uses Fernet from the cryptography library.

A key is generated with:

key = Fernet.generate_key()
                    

The key is currently stored locally in:

key.txt
                    

When adding a password, PyVault encrypts it before storing it:

fernet = Fernet(key.encode())

encrypted = fernet.encrypt(passwd.encode())
                    

The encrypted password is then inserted into the passwords table of the SQLite database:

secret/passwords.db
                    

Example of the SQLite database used for storage:

passwords (id, website, password)
                    

The password itself is not stored in plain text.

The browser-side terminal re-implements the same Fernet scheme in JavaScript (docs/static/js/fernet.js) using the Web Crypto API (AES-CBC + HMAC-SHA256). Because it follows the Fernet token format, tokens created in the browser are compatible with the Python CLI and the other way around.

⚠️ This is an early prototype. The current key management system is not considered secure enough for production use.

📊 Benchmark

PyVault includes a benchmark using Jupyter Notebook to measure the performance of Fernet encryption and decryption.

The benchmark tests multiple data sizes, from a few bytes up to 1 MB, and performs multiple iterations for each size.

The results are visualized in the following graph:

Graphique du benchmark de chiffrement et déchiffrement PyVault
PyVault Encryption / Decryption Benchmark

The benchmark helps measure how encryption and decryption performance changes as the amount of data increases.

The benchmark notebook is located at:

tests/benchmark.ipynb
                    

It can be used to experiment with PyVault's encryption system and compare future implementations.


🌍 Website

PyVault has a static website in the docs/ folder, automatically deployed to GitHub Pages on every push to main.

It includes:

  • An interactive browser terminal reproducing the CLI
  • The README, ideas, tests and about pages
  • A Français / 日本語 language switch

🚀 Installation

Clone the repository:

git clone https://github.com/KirobotDev/PyVault.git

cd PyVault
                    

Create a virtual environment:

Windows

python -m venv .venv

.venv\Scripts\activate
                    

Linux / macOS

python3 -m venv .venv

source .venv/bin/activate
                    

Install dependencies:

pip install -r requirements.txt
                    

▶️ Usage

Start PyVault:

python main.py
                    

You will see:

S. [Stars Project]       Q. [Leave]

        1. [Add Password]   4. [Export (Zipfiles)]
        2. [List Pswd]      5. [Delete Passwd]
        3. [Decrypt Pswd]   6. [Search Website]

        Choices :
                    

Generate a key

On startup, PyVault automatically creates a Fernet key (if key.txt doesn't exist yet) and saves it to:

key.txt
                    

Add a password

PyVault will ask for:

Enter the name of your website (e.g. github):

Enter your password:
                    

The password will be encrypted and stored in the SQLite database:

secret/passwords.db
                    

List saved entries

Choose:

2
                    

PyVault will display every website stored in the SQLite database (secret/passwords.db).

Decrypt a password

PyVault will ask for:

Enter the name of the website:
                    

It will then display:

Your Password is [ your_password_here ]
                    

Web tool (browser)

An interactive terminal is available on the site's Test page (or by opening docs/index.html locally). It behaves exactly like the CLI but runs entirely in the browser:

0  Generate a key
1  Add a password
2  List entries
3  Decrypt a password
4  Export (zip)
5  Delete an entry
6  Search a site
s  Open the GitHub repo
q  Quit
help / clear
                    

Entries are saved in the browser's localStorage. Toggle the interface between Français and 日本語 with the language button.


🧪 Running Tests

Unit tests are available in the tests/ folder.

Run them with:

python -m unittest discover tests
                    

📊 Running the Benchmark

The benchmark is available as a Jupyter Notebook.

Install Jupyter if necessary:

pip install jupyter
                    

Start Jupyter:

jupyter notebook
                    

Then open:

tests/benchmark.ipynb
                    

The benchmark measures:

  • Encryption speed
  • Decryption speed
  • Different data sizes
  • Average execution time
  • Performance scaling

🛠️ Roadmap

Phase 1 — Prototype

  • Generate Fernet key
  • Save key locally
  • Encrypt passwords
  • Store encrypted passwords in the database (secret/passwords.db)
  • Store website information
  • Basic CLI
  • Decrypt passwords
  • List saved entries

Phase 2 — Vault

  • Search passwords
  • Delete passwords
  • Export passwords
  • Web tool in the browser (docs/)
  • Fernet re-implemented in JavaScript (Web Crypto)
  • Bilingual FR / JA website (i18n)
  • Load existing key automatically
  • Better data structure

Phase 3 — Security

  • DPAPI key protection on Windows
  • Master password
  • Better key management
  • Vault locking
  • Failed attempt protection
  • Security tests
  • Security policy (SECURITY.md)
  • Threat model

Phase 4 — Database

  • SQLite
  • Database models
  • Encrypted database fields
  • Data validation
  • Migrate search and delete to the database
  • Database migrations

Phase 5 — API

  • Local API
  • FastAPI
  • Authentication
  • API documentation

Phase 6 — Interface

  • Web interface
  • Vault dashboard
  • Password manager UI
  • API integration

Phase 7 — Open Source

  • Complete documentation
  • Automated tests
  • GitHub Pages deployment (CI/CD)
  • Security review
  • PyPI package

🔒 Security

PyVault is an experimental learning project and is not intended for production use.

See SECURITY.md for the supported versions and how to responsibly report a vulnerability.


📚 Development Story

PyVault isn't only a software project.

I also want to document the process of building it.

The documentation will cover:

Idea

  ↓

First prototype

  ↓

Encryption

  ↓

Problems

  ↓

Research

  ↓

Solutions

  ↓

Security

  ↓

Testing

  ↓

Benchmarking

  ↓

Final application
                    

The objective is to show what I learned, what went wrong and how the project evolved over time.


🧪 Status

Current version: 0.2.0-dev

PyVault is currently an experimental project.

The project is actively being developed and its architecture may change significantly.


🤝 Contributing

Contributions, suggestions and bug reports are welcome.

If you find a problem, feel free to open an issue.

For larger changes, please open an issue first to discuss the idea.


📄 License

PyVault is released under the MIT License.

See LICENSE for more information.


👤 Author

xql

GitHub: https://github.com/KirobotDev


Built with Python 🐍
Learning by building.

Bac à sable interactif

PyVault en CLI — en direct

Une vraie console, comme python main.py, qui tourne dans ton navigateur. Tape les mêmes commandes. Le chiffrement est le vrai Fernet — ce que tu produis ici peut être déchiffré par le PyVault en Python, et l'inverse. Les entrées sont enregistrées dans ce navigateur, comme le dossier secret/.

python main.py
Choices :

Commandes

  • 0 Générer une clé
  • 1 Ajouter un mot de passe
  • 2 Lister les entrées
  • 3 Déchiffrer un mot de passe
  • 4 Exporter (zip)
  • 5 Supprimer une entrée
  • 6 Rechercher un site
  • s Ouvrir le dépôt GitHub
  • q Quitter
  • help help Aide · clear Nettoyer

La suite pour PyVault

Idées & choses à ajouter

Tout ce qui traîne dans ma tête ou dans le cahier d'idées du dépôt, classé par ordre à peu près chronologique. Rien n'est garanti, c'est une liste vivante.

Phase 2fait ✓

Charger la clé automatiquement

✔️ Terminé : au démarrage, PyVault charge key.txt tout seul (et le crée s'il n'existe pas). Tu n'as plus jamais à taper la clé à la main.

Phase 2fait ✓

Une vraie structure de données

✔️ Terminé : les fichiers par site ont laissé la place à une base SQLite (secret/passwords.db), avec des entrées identifiées et dédupliquées.

Phase 3à réfléchir

Le mot de passe maître

Le gros morceau : protéger le coffre avec un mot de passe maître, au lieu d'une clé posée en clair sur le disque.

Phase 3à réfléchir

Verrouiller le coffre

Un verrouillage après inactivité, et une protection contre les tentatives de mot de passe échouées.

Phase 3à réfléchir

Mieux gérer la clé

Utiliser un vrai dérivé de clé (KDF) au lieu du simple key.txt qui traîne en clair.

Phase 3à réfléchir

Modèle de menaces

Poser noir sur blanc contre quoi on protège, et comment. Ça m'aidera à faire les bons choix pour la suite.

Phase 4fait ✓

Passer à SQLite

✔️ Terminé : la base secret/passwords.db a remplacé le système de fichiers. Ajout, liste, déchiffrement, recherche et suppression passent tous par SQLite. Il reste les migrations.

Phase 5en attente

Une petite API locale

Exposer PyVault via une API locale en FastAPI, avec authentification, histoire de pouvoir l'utiliser depuis d'autres outils.

Phase 6en attente

Une interface web

Un tableau de bord pour tout gérer au lieu de la ligne de commande. Le grand projet à la fin.

Phase 7en attente

Rendre ça solide

CI/CD, revue de sécurité, documentation complète, et pourquoi pas un package sur le PyPI un jour.

Carnet d'idées — idea/idea.md

Le vrai fichier d'idées du dépôt ne contient pour l'instant que trois lignes. Je les garde ici telles quelles :

  • Ajouter une version japonaise du code dans un dossier japanese. — fait ✓
  • Ajouter le support de macOS. — fait ✓
  • Créer son propre algorithme de chiffrement.

Une idée qui traîne ?

Les suggestions et les bug reports sont les bienvenus. La meilleure façon de m'en parler, c'est d'ouvrir une issue sur le dépôt.

Ouvrir une issue

Derrière le projet

À propos

PyVault, c'est mon projet d'apprentissage. Je m'appelle xql et je vois ce dépôt comme un terrain de jeu où je peux me planter sans conséquence — et justement, apprendre de mes erreurs.

L'idée de départ est bête : je voulais un endroit pour ranger mes mots de passe qui ne soit pas chez quelqu'un d'autre. Le chemin pour y arriver me fait toucher à pas mal de sujets (chiffrement, stockage, API, sécurité) que je n'aurais jamais abordés avec un simple tuto.

Le projet est en développement actif et l'architecture peut encore beaucoup bouger. Si ça t'intéresse, le mieux c'est de suivre la roadmap dans le README, ou de jeter un œil aux idées pour voir où je vais.

Version actuelle
0.2.0-dev
Licence
MIT
Écrit en
Python
Chiffrement
Fernet