4NK_vault/sdk-client/README.md

550 lines
15 KiB
Markdown

# SDK Client TypeScript pour l'API Vault 4NK
Un SDK TypeScript moderne et type-safe pour interagir avec l'API Vault 4NK, permettant de récupérer et déchiffrer des fichiers depuis un service de stockage sécurisé avec chiffrement quantique résistant.
## 🚀 Caractéristiques
- **Type-safe** : Entièrement écrit en TypeScript avec types stricts
- **Chiffrement quantique résistant** : Support de ChaCha20-Poly1305 avec @noble/ciphers
- **Gestion d'erreurs avancée** : Classes d'erreurs spécialisées
- **Requêtes parallèles** : Récupération de plusieurs fichiers simultanément
- **Configuration flexible** : Timeouts, SSL, etc.
- **Synchronisation locale** : Miroir automatique des fichiers déchiffrés
- **Variables d'environnement** : Résolution automatique des variables $VAR
- **Monitoring** : Endpoints de santé et d'information
- **Rotation automatique des clés** : Mise à jour transparente des clés
## 📦 Installation
```bash
npm install @4nk/vault-sdk
```
## ⚙️ Configuration rapide
Après avoir cloné le projet ou installé le SDK, **vous devez configurer les variables d'environnement** :
```bash
# 1. Copier le fichier d'exemple
cp .env.example .env
# 2. Modifier les valeurs dans .env selon vos besoins
# 3. Ou créer directement un fichier .env avec vos paramètres
```
## 🔧 Configuration
### Configuration automatique via .env
Le SDK peut être configuré automatiquement via un fichier `.env` :
```bash
# .env
VAULT_USER=<VAULT_USER_ID>
VAULT_KEY=<VAULT_KEY_BASE64>
VAULT_ENV=dev
VAULT_CONFS_DIR=../confs # Dossier de destination pour les fichiers synchronisés
```
#### Variables d'environnement disponibles
| Variable | Description | Requis | Défaut |
|----------|-------------|--------|--------|
| `VAULT_USER` | Identifiant utilisateur pour l'authentification | ✅ | - |
| `VAULT_KEY` | Clé de déchiffrement (gérée automatiquement) | ✅ | - |
| `VAULT_ENV` | Environnement par défaut | ✅ | - |
| `VAULT_CONFS_DIR` | Dossier de destination pour les fichiers synchronisés | ❌ | `../confs` |
| `VAULT_URL` | URL de l'API Vault | ❌ | `<VAULT_URL>` |
#### Chargement automatique des variables d'environnement
Le SDK charge automatiquement les variables d'environnement depuis plusieurs emplacements possibles :
1. **Répertoire courant** : `.env`
2. **Répertoire parent** : `../.env`
3. **Répertoire grand-parent** : `../../.env`
4. **Répertoire de travail** : `process.cwd()/.env`
5. **Variables système** : Variables d'environnement du système
Le SDK recherche ces fichiers dans l'ordre et utilise le premier trouvé. Cette approche garantit que le SDK fonctionne même si le fichier `.env` n'est pas dans le répertoire courant du projet qui l'utilise.
### Configuration manuelle
```typescript
import { SecureVaultClient } from '@4nk/vault-sdk';
// Configuration manuelle
const client = new SecureVaultClient({
baseUrl: process.env.VAULT_URL ?? '<VAULT_URL>',
userId: '<VAULT_USER_ID>',
vaultKey: '<VAULT_KEY_BASE64>',
environment: 'dev',
verifySsl: false // Pour les certificats auto-signés
});
```
## 📖 Utilisation
### Exemple basique
```typescript
import { SecureVaultClient } from '@4nk/vault-sdk';
// Création du client (charge automatiquement le .env)
const client = new SecureVaultClient();
// Récupération d'un fichier avec variables d'environnement résolues
try {
const file = await client.getFile('dev', 'bitcoin/bitcoin.conf');
console.log(`Contenu: ${file.content}`);
console.log(`Taille: ${file.size} caractères`);
console.log(`Variables résolues: ${file.content.includes('/home/debian/4NK_env/logs/bitcoin')}`);
} catch (error) {
console.error('Erreur:', error.message);
}
```
### Configuration avancée
```typescript
import { SecureVaultClient } from '@4nk/vault-sdk';
const client = new SecureVaultClient({
baseUrl: process.env.VAULT_URL ?? '<VAULT_URL>',
userId: '<VAULT_USER_ID>',
vaultKey: '<VAULT_KEY_BASE64>',
environment: 'dev',
verifySsl: false, // Pour les certificats auto-signés
timeout: 10000 // 10 secondes
});
```
### Récupération de plusieurs fichiers
```typescript
// Récupération parallèle avec variables d'environnement résolues
const files = await client.getFiles([
{ env: 'dev', filePath: 'bitcoin/bitcoin.conf' },
{ env: 'dev', filePath: 'tor/torrc' },
{ env: 'dev', filePath: 'grafana/grafana.ini' }
]);
files.forEach(file => {
console.log(`${file.filename}: ${file.size} caractères`);
// Variables d'environnement automatiquement résolues
console.log(`Variables résolues: ${!file.content.includes('$')}`);
});
```
### Monitoring et santé
```typescript
// Test de connectivité
const isConnected = await client.ping();
console.log(`Connecté: ${isConnected}`);
// Informations sur l'API
const info = await client.info();
console.log(`API: ${info.name} v${info.version}`);
// État de santé
const health = await client.health();
console.log(`Statut: ${health.status}`);
```
### Synchronisation locale
```typescript
// Récupération des routes disponibles
const routes = await client.getRoutes();
console.log(`Routes disponibles: ${routes.total_routes}`);
// Synchronisation des fichiers déchiffrés localement avec variables résolues
// Le dossier de destination peut être configuré via VAULT_CONFS_DIR dans .env
const syncResult = await client.syncLocalFiles({
environment: 'dev',
localDir: '../confs', // Optionnel: utilise VAULT_CONFS_DIR par défaut
verbose: true
});
console.log(`Synchronisés: ${syncResult.synced}`);
console.log(`Ignorés: ${syncResult.skipped}`);
console.log(`Erreurs: ${syncResult.errors}`);
```
**Mapping de synchronisation :**
- Route vault : `/<env>/<project>/<file_name>`
- Dossier local : `../confs/<project>/<file_name>`
- Exemple : `/dev/bitcoin/bitcoin.conf``../confs/bitcoin/bitcoin.conf`
- **Variables d'environnement** automatiquement résolues dans les fichiers synchronisés
## 🛡️ Gestion d'erreurs
Le SDK fournit des classes d'erreurs spécialisées :
```typescript
import { VaultApiError, VaultDecryptionError } from '@4nk/vault-sdk';
try {
await client.getFile('dev', 'fichier-inexistant.conf');
} catch (error) {
if (error instanceof VaultApiError) {
console.error(`Erreur API: ${error.message} (${error.statusCode})`);
console.error(`Endpoint: ${error.endpoint}`);
} else if (error instanceof VaultDecryptionError) {
console.error(`Erreur de déchiffrement: ${error.message}`);
} else {
console.error(`Erreur inconnue: ${error.message}`);
}
}
```
### Types d'erreurs
- **`VaultApiError`** : Erreurs HTTP de l'API
- `statusCode` : Code d'erreur HTTP
- `endpoint` : Endpoint qui a échoué
- **`VaultDecryptionError`** : Erreurs de déchiffrement
- Clé incorrecte
- Données corrompues
- Format invalide
## 🔐 Sécurité
### Chiffrement
- **Algorithme** : ChaCha20-Poly1305 avec @noble/ciphers
- **Nonce** : 12 bytes aléatoires par fichier
- **Clé** : 32 bytes (256 bits) en base64
- **Authentification** : Intégrée via Poly1305
- **Rotation automatique** : Mise à jour transparente des clés
- **Variables d'environnement** : Résolues avant chiffrement
### Bonnes pratiques
```typescript
// ✅ Configuration automatique via .env
const client = new SecureVaultClient(); // Charge automatiquement .env
// ✅ Gérer les erreurs de déchiffrement
try {
const file = await client.getFile('dev', 'config.conf');
} catch (error) {
if (error instanceof VaultDecryptionError) {
// Clé incorrecte ou données corrompues
console.error('Erreur de déchiffrement');
}
}
// ✅ Utiliser HTTPS en production
const client = new SecureVaultClient({
baseUrl: process.env.VAULT_URL ?? '<VAULT_URL>',
verifySsl: true, // Activer la validation SSL
userId: '<VAULT_USER_ID>',
vaultKey: '<VAULT_KEY_BASE64>',
environment: 'prod'
});
// ✅ Synchronisation locale pour les déploiements
const syncResult = await client.syncLocalFiles({
environment: 'dev',
localDir: '../confs'
});
```
## 🔧 Dépannage
### Problèmes courants avec les variables d'environnement
#### Le paramètre `VAULT_CONFS_DIR` n'est pas pris en compte
**Problème** : Le SDK utilise toujours `../confs` au lieu de votre dossier personnalisé.
**Solutions** :
1. **Vérifiez l'emplacement du fichier `.env`** :
```bash
# Le SDK recherche dans cet ordre :
ls -la .env # Répertoire courant
ls -la ../.env # Répertoire parent
ls -la ../../.env # Répertoire grand-parent
```
2. **Créez un fichier `.env` dans le bon répertoire** :
```bash
# Dans le répertoire de votre projet
echo "VAULT_CONFS_DIR=./mon-dossier-confs" >> .env
```
3. **Utilisez le paramètre direct** :
```typescript
const syncResult = await client.syncLocalFiles({
environment: 'dev',
localDir: './mon-dossier-confs', // Priorité sur VAULT_CONFS_DIR
verbose: true
});
```
#### Variables d'environnement non chargées
**Problème** : Le SDK ne trouve pas votre fichier `.env`.
**Solutions** :
1. **Vérifiez les logs** : Le SDK affiche quel fichier `.env` il a chargé
2. **Placez le fichier `.env` dans le bon répertoire** selon l'ordre de priorité
3. **Utilisez les variables système** :
```bash
export VAULT_CONFS_DIR=./mon-dossier-confs
```
#### Erreur "Variables d'environnement requises"
**Problème** : `VAULT_USER`, `VAULT_KEY`, ou `VAULT_ENV` manquants.
**Solutions** :
1. **Créez un fichier `.env`** dans le dossier `sdk-client/` :
```bash
cd sdk-client/
cp .env.example .env
# Modifiez les valeurs dans .env
```
2. **Ajoutez les variables manquantes** dans votre `.env`
3. **Vérifiez la syntaxe** du fichier `.env` (pas d'espaces autour du `=`)
4. **Utilisez la configuration manuelle** :
```typescript
const client = new SecureVaultClient({
baseUrl: 'https://vault.4nkweb.com:6666',
userId: '<VAULT_USER_ID>',
vaultKey: '<VAULT_KEY_BASE64>',
verifySsl: false
});
```
#### Dossiers créés mais vides (seulement des .gitkeep)
**Problème** : Le SDK se connecte à une API locale au lieu de l'API distante.
**Solutions** :
1. **Vérifiez l'URL dans votre `.env`** :
```bash
VAULT_URL=<VAULT_URL>
```
2. **Redémarrez l'API locale** si elle tourne en arrière-plan
3. **Testez la connectivité** :
```bash
curl -k "$VAULT_URL"/health
```
4. **Vérifiez les logs** du SDK pour voir quelle URL est utilisée
## 📚 API Reference
### Classes principales
#### `SecureVaultClient`
```typescript
class SecureVaultClient {
constructor(config?: SecureVaultConfig)
// Récupération de fichiers avec déchiffrement automatique
getFile(env: string, filePath: string): Promise<VaultFile>
getFiles(requests: FileRequest[]): Promise<VaultFile[]>
// Déchiffrement de contenu
decryptContent(encryptedData: string, nextKey?: string): Promise<string>
// Monitoring
health(): Promise<VaultHealth>
info(): Promise<VaultInfo>
ping(): Promise<boolean>
// Routes et synchronisation
getRoutes(): Promise<VaultRoutes>
syncLocalFiles(options: SyncOptions): Promise<SyncResult>
// Gestion des clés
updateNextKey(nextKey: string): void
updateEnvFile(newKey: string): void
// Utilitaires
searchFiles(env: string, pattern?: RegExp): Promise<string[]>
}
```
#### `VaultCrypto`
```typescript
class VaultCrypto {
// Génération de clés
static generateKey(): string
static hashToKey(password: string): string
static validateKey(key: string): boolean
// Déchiffrement ChaCha20-Poly1305
static decrypt(encryptedData: string, key: string): string
}
```
### Types
```typescript
interface VaultFile {
content: string; // Contenu déchiffré avec variables résolues
filename: string;
size: number;
encrypted: boolean;
algorithm?: string;
variablesResolved?: boolean; // Indique si les variables d'environnement ont été résolues
}
interface VaultHealth {
status: string;
service: string;
encryption: string;
algorithm: string;
}
interface VaultRoutes {
routes: VaultRoute[];
total_routes: number;
authentication: {
type: string;
header: string;
description: string;
};
user_id: string;
timestamp: string;
}
interface SyncOptions {
environment: string;
localDir?: string; // Par défaut: '../confs'
verbose?: boolean; // force option removed - always overwrites
}
interface SyncResult {
synced: number;
skipped: number;
errors: number;
details: Array<{
file: string;
status: 'synced' | 'skipped' | 'error';
message?: string;
}>;
}
interface SecureVaultConfig {
baseUrl: string;
userId: string;
vaultKey: string; // Clé de déchiffrement en base64
environment: string;
verifySsl?: boolean;
timeout?: number;
}
```
## 🧪 Tests et exemples
### Exemples fournis
- **`usage.ts`** : Scénario complet avec 5 étapes
1. Initialisation + Gestion des erreurs
2. Récupération des routes + Gestion des erreurs
3. Parcours des routes + Gestion des erreurs
4. Synchronisation locale + Gestion des erreurs
5. Déchiffrement des contenus + Gestion des erreurs
**Fonctionnalités démontrées :**
- Configuration automatique via `.env`
- Déchiffrement réel avec `@noble/ciphers`
- Variables d'environnement résolues automatiquement
- Synchronisation locale avec écrasement des fichiers
- Rotation automatique des clés
### Exécution des exemples
```bash
# Compilation
npm run build
# Scénario complet
node dist/examples/usage.js
```
### Tests unitaires
```bash
npm test
```
## 🔧 Développement
### Prérequis
- Node.js >= 16.0.0
- TypeScript >= 4.0.0
### Installation des dépendances
```bash
npm install
```
### Compilation
```bash
npm run build
```
### Linting
```bash
npm run lint
```
### Structure du projet
```
sdk-client/
├── src/
│ └── index.ts # Code principal du SDK
├── examples/
│ ├── basic-usage.ts # Exemple basique
│ ├── advanced-usage.ts # Exemple avancé
│ └── error-handling.ts # Gestion d'erreurs
├── dist/ # Code compilé
├── package.json
├── tsconfig.json
└── README.md
```
## 🌐 Compatibilité
- **Node.js** : >= 16.0.0
- **TypeScript** : >= 4.0.0
- **Navigateurs** : Support des APIs modernes (fetch, crypto)
## 📄 Licence
MIT License - Voir le fichier `LICENSE` pour plus de détails.
## 🤝 Contribution
1. Fork le projet
2. Créer une branche feature (`git checkout -b feature/nouvelle-fonctionnalite`)
3. Commit les changements (`git commit -am 'Ajouter nouvelle fonctionnalité'`)
4. Push vers la branche (`git push origin feature/nouvelle-fonctionnalite`)
5. Ouvrir une Pull Request
## 📞 Support
- **Issues** : [Git Issues](https://git.4nkweb.com/4nk/vault-sdk/issues)
- **Documentation** : [Wiki du projet](https://git.4nkweb.com/4nk/vault-sdk/wiki)
- **Email** : support@4nkweb.com
---
**Version** : 1.0.0
**API Vault** : <VAULT_URL>
**Chiffrement** : ChaCha20-Poly1305 (quantique résistant)