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 son propre fichier, par exemple secret/github.txt.

🔓 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]      0. [Generate Key (Obliged)]     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
  • 💾 Store each password in a dedicated file per website
  • 🔓 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)

Planned

  • 🗄️ SQLite database
  • 🔑 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"] GenerateKey["🔑 Generate Key
CURRENT"] AddPassword["🔐 Add Password
CURRENT"] ListPasswords["📋 List Passwords
CURRENT"] DecryptPassword["🔓 Decrypt Password
CURRENT"] Fernet["🔒 Fernet Encryption
CURRENT"] KeyFile["📄 key.txt
CURRENT"] SecretFolder["📁 secret/
CURRENT"] Search["🔎 Search Passwords
CURRENT"] Delete["🗑️ Delete Password
CURRENT"] Export["📤 Export Passwords
CURRENT"] Tests["🧪 Unit Tests
CURRENT"] Benchmark["📊 Benchmark
CURRENT"] MasterPassword["🔑 Master Password
PLANNED"] Vault["🔐 Vault System
PLANNED"] SQLite["🗄️ SQLite Database
PLANNED"] API["🌐 Local API
PLANNED"] FastAPI["⚡ FastAPI
PLANNED"] Web["🖥️ Web Interface
PLANNED"] User --> PyVault PyVault --> CLI CLI --> GenerateKey CLI --> AddPassword CLI --> ListPasswords CLI --> DecryptPassword GenerateKey --> Fernet GenerateKey --> KeyFile AddPassword --> Fernet Fernet --> SecretFolder DecryptPassword --> SecretFolder ListPasswords --> SecretFolder CLI --> Search CLI --> Delete CLI --> Export Search -.-> SQLite Delete -.-> SQLite MasterPassword -.-> Vault Vault -.-> SQLite 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
│
├── secret/               ← stores encrypted password files
│
├── tests/                ← unit tests
│
├── images/
│   └── benchmark.png     ← encryption/decryption benchmark
│
├── notebooks/
│   └── benchmark.ipynb   ← Jupyter benchmark
│
├── main.py
├── system_info.py
├── key.txt
├── .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 stored in a dedicated file inside the secret/ folder, one file per website:

secret/

└── github.txt
                    

Example content of secret/github.txt:

gAAAAAB...
                    

The password itself is not stored directly in the file.

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:

notebooks/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]      0. [Generate Key (Obliged)] Q. [Leave]

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

        Choices :
                    

Generate a key

Choose:

0
                    

PyVault will generate a Fernet key and save it to:

key.txt
                    

Add a password

PyVault will ask for:

Enter your key please thanks... :

Enter name your website Example (github) :

Enter your password :
                    

The password will be encrypted and stored in:

secret/<website>.txt
                    

List saved entries

Choose:

2
                    

PyVault will display all files stored in the secret/ folder, one per website.

Decrypt a password

PyVault will ask for:

Enter your key :
Enter the file name example (github.txt) :
                    

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:

notebooks/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
  • Save encrypted passwords (one file per website in secret/)
  • 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

  • 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
  • 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 2en attente

Charger la clé automatiquement

Aujourd'hui il faut taper la clé à chaque commande. Ce serait mieux que le programme retrouve tout seul key.txt au démarrage.

Phase 2en attente

Une vraie structure de données

Les fichiers par site, ça marche, mais ça ne tient pas la route longtemps. Il faut penser à un format plus propre avec des métadonné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 4en attente

Passer à SQLite

Une vraie base pour remplacer le système de fichiers : modèles, champs chiffrés, validation et 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.
  • Ajouter le support de macOS.
  • 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