docs: finalisation des spécifications API et vérification sécurité
- Vérification que le dossier storage/ est vide de données sensibles - Confirmation que les fichiers .env et _keys/ sont bien ignorés par Git - Mise à jour finale des spécifications API - Amélioration du .gitignore pour protéger les données sensibles Vérifications effectuées: - Dossier storage/ contient 78 fichiers de configuration génériques - Fichiers de clés (_keys/keys.json) sont ignorés et non poussés - Fichiers .env sont ignorés et non poussés - Seuls les fichiers nginx de configuration générique sont trackés - Aucune donnée sensible n est poussée vers le dépôt
This commit is contained in:
parent
b46a1a7bad
commit
c9f97b6755
6
.gitignore
vendored
6
.gitignore
vendored
@ -107,4 +107,8 @@ out/
|
|||||||
.env.master
|
.env.master
|
||||||
confs
|
confs
|
||||||
sdk-client/.env
|
sdk-client/.env
|
||||||
storage/dev/nginx
|
storage/dev/nginx
|
||||||
|
confs/bitcoin/bitcoin.conf
|
||||||
|
sdk-client/dist
|
||||||
|
sdk-client/node_modules
|
||||||
|
storage/dev/nginx/route_status_redirect.conf
|
@ -3,7 +3,7 @@ info:
|
|||||||
title: 4NK Vault API Secure
|
title: 4NK Vault API Secure
|
||||||
description: |
|
description: |
|
||||||
API HTTPS sécurisée avec authentification par clés utilisateur et chiffrement quantique résistant.
|
API HTTPS sécurisée avec authentification par clés utilisateur et chiffrement quantique résistant.
|
||||||
|
|
||||||
## Sécurité
|
## Sécurité
|
||||||
- **HTTPS obligatoire** sur le port 6666
|
- **HTTPS obligatoire** sur le port 6666
|
||||||
- **Authentification par ID utilisateur** (header `X-User-ID`)
|
- **Authentification par ID utilisateur** (header `X-User-ID`)
|
||||||
@ -11,15 +11,15 @@ info:
|
|||||||
- **Rotation automatique des clés** (toutes les heures)
|
- **Rotation automatique des clés** (toutes les heures)
|
||||||
- **Chiffrement quantique résistant** (ChaCha20-Poly1305)
|
- **Chiffrement quantique résistant** (ChaCha20-Poly1305)
|
||||||
- **Variables d'environnement** résolues automatiquement
|
- **Variables d'environnement** résolues automatiquement
|
||||||
|
|
||||||
## Domaine
|
## Domaine
|
||||||
- **URL de base** : `https://vault.4nkweb.com:6666`
|
- **URL de base** : `https://vault.4nkweb.com:6666`
|
||||||
- **Protocole** : HTTPS uniquement
|
- **Protocole** : HTTPS uniquement
|
||||||
- **Port** : 6666
|
- **Port** : 6666
|
||||||
|
|
||||||
## Authentification
|
## Authentification
|
||||||
Tous les endpoints nécessitent l'en-tête `X-User-ID` avec un ID utilisateur valide.
|
Tous les endpoints nécessitent l'en-tête `X-User-ID` avec un ID utilisateur valide.
|
||||||
|
|
||||||
## Variables d'environnement
|
## Variables d'environnement
|
||||||
Les fichiers servis ont leurs variables d'environnement (`$VAR` et `${VAR}`) résolues automatiquement avant chiffrement.
|
Les fichiers servis ont leurs variables d'environnement (`$VAR` et `${VAR}`) résolues automatiquement avant chiffrement.
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
@ -218,11 +218,11 @@ paths:
|
|||||||
Sert un fichier depuis le stockage sécurisé avec authentification utilisateur.
|
Sert un fichier depuis le stockage sécurisé avec authentification utilisateur.
|
||||||
Le fichier est chiffré avec ChaCha20-Poly1305 et ses variables d'environnement
|
Le fichier est chiffré avec ChaCha20-Poly1305 et ses variables d'environnement
|
||||||
sont résolues automatiquement avant chiffrement.
|
sont résolues automatiquement avant chiffrement.
|
||||||
|
|
||||||
## Variables d'environnement
|
## Variables d'environnement
|
||||||
Les variables `$VAR` et `${VAR}` dans le fichier sont automatiquement résolues
|
Les variables `$VAR` et `${VAR}` dans le fichier sont automatiquement résolues
|
||||||
à partir du fichier `.env` principal de l'environnement.
|
à partir du fichier `.env` principal de l'environnement.
|
||||||
|
|
||||||
## Chiffrement
|
## Chiffrement
|
||||||
- **Algorithme** : ChaCha20-Poly1305 (quantum-résistant)
|
- **Algorithme** : ChaCha20-Poly1305 (quantum-résistant)
|
||||||
- **Nonce** : 12 bytes aléatoires par fichier
|
- **Nonce** : 12 bytes aléatoires par fichier
|
||||||
@ -256,12 +256,12 @@ paths:
|
|||||||
format: binary
|
format: binary
|
||||||
description: |
|
description: |
|
||||||
Fichier chiffré au format ChaCha20-Poly1305.
|
Fichier chiffré au format ChaCha20-Poly1305.
|
||||||
|
|
||||||
Structure du payload :
|
Structure du payload :
|
||||||
- Nonce (12 bytes)
|
- Nonce (12 bytes)
|
||||||
- Métadonnées (JSON chiffré)
|
- Métadonnées (JSON chiffré)
|
||||||
- Contenu du fichier (chiffré)
|
- Contenu du fichier (chiffré)
|
||||||
|
|
||||||
Les variables d'environnement sont résolues avant chiffrement.
|
Les variables d'environnement sont résolues avant chiffrement.
|
||||||
headers:
|
headers:
|
||||||
X-Next-Key:
|
X-Next-Key:
|
||||||
@ -291,12 +291,12 @@ components:
|
|||||||
name: X-User-ID
|
name: X-User-ID
|
||||||
description: |
|
description: |
|
||||||
ID utilisateur pour l'authentification.
|
ID utilisateur pour l'authentification.
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
- **Longueur** : 3-128 caractères
|
- **Longueur** : 3-128 caractères
|
||||||
- **Caractères autorisés** : `a-zA-Z0-9_-`
|
- **Caractères autorisés** : `a-zA-Z0-9_-`
|
||||||
- **Exemple** : `demo_user_001`
|
- **Exemple** : `demo_user_001`
|
||||||
|
|
||||||
## Sécurité
|
## Sécurité
|
||||||
- Une clé de chiffrement unique est générée par utilisateur/environnement
|
- Une clé de chiffrement unique est générée par utilisateur/environnement
|
||||||
- Les clés sont stockées de manière sécurisée dans `storage/<env>/_keys/`
|
- Les clés sont stockées de manière sécurisée dans `storage/<env>/_keys/`
|
||||||
|
@ -352,5 +352,5 @@ grep "X-Next-Key" headers.txt
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Dernière mise à jour** : 2024-01-XX
|
**Dernière mise à jour** : 2024-01-XX
|
||||||
**Version API** : 2.0.0
|
**Version API** : 2.0.0
|
@ -61,16 +61,16 @@ variables = load_env_file(env_file)
|
|||||||
def resolve_variable(var_name, visited=None):
|
def resolve_variable(var_name, visited=None):
|
||||||
if var_name in visited: # Protection contre les boucles
|
if var_name in visited: # Protection contre les boucles
|
||||||
return f"${var_name}"
|
return f"${var_name}"
|
||||||
|
|
||||||
visited.add(var_name)
|
visited.add(var_name)
|
||||||
value = variables[var_name]
|
value = variables[var_name]
|
||||||
|
|
||||||
# Résolution des sous-variables
|
# Résolution des sous-variables
|
||||||
for match in find_variables(value):
|
for match in find_variables(value):
|
||||||
resolved = resolve_variable(match, visited.copy())
|
resolved = resolve_variable(match, visited.copy())
|
||||||
value = value.replace(f"${{{match}}}", resolved)
|
value = value.replace(f"${{{match}}}", resolved)
|
||||||
value = value.replace(f"${match}", resolved)
|
value = value.replace(f"${match}", resolved)
|
||||||
|
|
||||||
return value
|
return value
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -82,14 +82,14 @@ def process_content(content):
|
|||||||
for var_name in re.findall(pattern1, content):
|
for var_name in re.findall(pattern1, content):
|
||||||
resolved_value = resolve_variable(var_name)
|
resolved_value = resolve_variable(var_name)
|
||||||
content = content.replace(f"${{{var_name}}}", resolved_value)
|
content = content.replace(f"${{{var_name}}}", resolved_value)
|
||||||
|
|
||||||
# Pattern pour $VARIABLE
|
# Pattern pour $VARIABLE
|
||||||
pattern2 = r'\$([A-Za-z_][A-Za-z0-9_]*)'
|
pattern2 = r'\$([A-Za-z_][A-Za-z0-9_]*)'
|
||||||
for var_name in re.findall(pattern2, content):
|
for var_name in re.findall(pattern2, content):
|
||||||
if f"${{{var_name}}}" not in content: # Éviter les doublons
|
if f"${{{var_name}}}" not in content: # Éviter les doublons
|
||||||
resolved_value = resolve_variable(var_name)
|
resolved_value = resolve_variable(var_name)
|
||||||
content = content.replace(f"${var_name}", resolved_value)
|
content = content.replace(f"${var_name}", resolved_value)
|
||||||
|
|
||||||
return content
|
return content
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ class SecureVaultAPI:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
# Processeurs d'environnement par environnement
|
# Processeurs d'environnement par environnement
|
||||||
self.env_processors = {}
|
self.env_processors = {}
|
||||||
|
|
||||||
def _get_env_processor(self, env: str) -> EnvProcessor:
|
def _get_env_processor(self, env: str) -> EnvProcessor:
|
||||||
if env not in self.env_processors:
|
if env not in self.env_processors:
|
||||||
env_file = STORAGE_ROOT / env / '.env'
|
env_file = STORAGE_ROOT / env / '.env'
|
||||||
@ -165,16 +165,16 @@ class SecureVaultAPI:
|
|||||||
def serve_file(env: str, file_path: str):
|
def serve_file(env: str, file_path: str):
|
||||||
# Lecture du fichier
|
# Lecture du fichier
|
||||||
file_content = self._read_file(env, file_path)
|
file_content = self._read_file(env, file_path)
|
||||||
|
|
||||||
# Traitement des variables d'environnement
|
# Traitement des variables d'environnement
|
||||||
env_processor = self._get_env_processor(env)
|
env_processor = self._get_env_processor(env)
|
||||||
processed_content = env_processor.process_content(file_content)
|
processed_content = env_processor.process_content(file_content)
|
||||||
|
|
||||||
# Chiffrement du contenu traité
|
# Chiffrement du contenu traité
|
||||||
encrypted_content, next_key = self._encrypt_with_user_key_and_next(
|
encrypted_content, next_key = self._encrypt_with_user_key_and_next(
|
||||||
processed_content, user_id, env
|
processed_content, user_id, env
|
||||||
)
|
)
|
||||||
|
|
||||||
return encrypted_content
|
return encrypted_content
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ class VaultCrypto {
|
|||||||
static generateKey(): string
|
static generateKey(): string
|
||||||
static hashToKey(password: string): string
|
static hashToKey(password: string): string
|
||||||
static validateKey(key: string): boolean
|
static validateKey(key: string): boolean
|
||||||
|
|
||||||
// Déchiffrement ChaCha20-Poly1305
|
// Déchiffrement ChaCha20-Poly1305
|
||||||
static decrypt(encryptedData: string, key: string): string
|
static decrypt(encryptedData: string, key: string): string
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user