# Bonnes pratiques de sécurité
Source: https://docs.lomi.africa/build/reliability/security-best-practices

Signaler une vulnérabilité, puis sécuriser les clés API, le TLS et la vérification des webhooks pour votre intégration lomi.

***

title: 'Bonnes pratiques de sécurité'
description: 'Signaler une vulnérabilité, puis sécuriser les clés API, le TLS et la vérification des webhooks pour votre intégration lomi.'
-------------------------------------------------------------------------------------------------------------------------------------------

## Signaler une vulnérabilité

Si vous pensez avoir trouvé une vulnérabilité de sécurité dans lomi., signalez-la en privé. N’ouvrez pas d’issue GitHub publique pour un rapport de sécurité.

**Canal privilégié :** [GitHub Security Advisory](https://github.com/lomiafrica/lomi./security/advisories/new) (privé), ou le formulaire ci-dessous.

Incluez :

* Description et impact
* Étapes de reproduction
* URLs ou composants concernés (par exemple `api.lomi.africa`, checkout, tableau de bord)
* Preuve de concept si possible (aucune donnée de paiement réelle)

Nous visons à accuser réception sous **3 jours ouvrés** et à indiquer un délai de correction selon la gravité.

<DocsSecurityForm />

Vous pouvez aussi écrire à [security@lomi.africa](mailto:security@lomi.africa). Le fichier [/.well-known/security.txt](/.well-known/security.txt) décrit le contact pour les agents et les scanners.

### Périmètre

Dans le périmètre : les services opérés par lomi. (API, checkout, tableau de bord, admin, MCP, Postgres/Auth/Storage Supabase, portail client, documentation, site).

Hors périmètre sauf accord écrit :

* Consoles et infrastructures de prestataires tiers
* Déploiements de plugins personnalisés sur l’infrastructure du marchand
* Ingénierie sociale et attaques physiques
* Déni de service sans autorisation écrite préalable

### Safe harbor

Nous soutenons la recherche de bonne foi qui suit cette politique. N’accédez pas, ne modifiez pas et ne supprimez pas de données appartenant à d’autres utilisateurs. Utilisez le sandbox et des comptes de test autant que possible.

### Gravité et délais

| Gravité  | Exemples                                                                   | Objectif                                              |
| -------- | -------------------------------------------------------------------------- | ----------------------------------------------------- |
| Critique | Contournement d’auth admin/provisioning, exposition de données de paiement | Mitigation dès que possible, mise à jour sous 7 jours |
| Haute    | Isolation locataire, contournement de signature webhook                    | Correction sous 30 jours                              |
| Moyenne  | XSS à impact limité, mauvaise configuration                                | Correction sous 90 jours                              |
| Basse    | Informatif                                                                 | Backlog au mieux                                      |

### Reconnaissance

Merci aux chercheurs qui aident à protéger lomi. et nos marchands. Une divulgation coordonnée peut être mentionnée dans les notes de version avec votre accord.

## Authentification API

### Sécurité des clés API

1. **Stockage sécurisé :** **ne jamais** coder en dur les clés API (`LOMI_SECRET_KEY`) ni les commiter dans le dépôt. Utilisez des variables d’environnement ou un gestionnaire de secrets.

   ```typescript filename="Utiliser une variable d’environnement pour la clé API"
   import { LomiSDK } from '@lomi./sdk';

   // Ne pas coder la clé en dur
   const lomi = new LomiSDK({
     apiKey: process.env.LOMI_SECRET_KEY, // Chargée depuis l’environnement
   });
   ```

2. **Rotation des clés :** faites tourner vos clés API régulièrement via le Dashboard lomi. En cas de compromission, révoquez-la immédiatement et régénérez-en une nouvelle.

3. **Séparation des environnements :** utilisez strictement les clés Test (`lomi_sk_test_...`) pour le développement et les tests, et les clés Live (`lomi_sk_live_...`) uniquement en production.

4. **Contrôle d’accès :** limitez l’accès aux clés API au sein de votre organisation et de votre infra aux seuls systèmes et personnes qui en ont besoin.

## Sécurité des requêtes

### Exigences TLS

Toute communication avec l’API lomi. **doit** passer par HTTPS (TLS 1.2 ou supérieur) pour chiffrer les données en transit. Vérifiez que vos clients HTTP imposent TLS.

```typescript filename="S’assurer d’une URL de base HTTPS"
import axios from 'axios';

const LOMI_API_URL = 'https://api.lomi.africa'; // Toujours HTTPS

const apiClient = axios.create({
  baseURL: LOMI_API_URL,
  headers: {
    Authorization: `Bearer ${process.env.LOMI_SECRET_KEY}`,
    'Content-Type': 'application/json',
  },
});
```

### Validation des requêtes

Validez les données côté serveur **avant** de les envoyer à l’API lomi.

1. **Assainissement des entrées :** nettoyez les entrées utilisateur pour limiter les risques d’injection (lomi. valide aussi côté API ; la défense en profondeur reste recommandée).

   ```typescript filename="Exemples simples d’assainissement"
   function sanitizeAmount(input: any): number | null {
     const num = Number(input);
     // Entier positif (adapter si décimales nécessaires)
     return Number.isInteger(num) && num > 0 ? num : null;
   }

   function sanitizePhoneNumber(phone: string | undefined): string | null {
     // Exemple : retirer les non-chiffres, vérifier la longueur (adapter au format)
     const digits = phone?.replace(/\D/g, '');
     return digits && digits.length >= 8 ? digits : null; // Ajuster le seuil
   }
   ```

2. **Validation par schéma :** utilisez Zod, Joi ou équivalent pour valider structure et types avant l’appel API.

   ```typescript filename="Validation de schéma avec Zod"
   import { z } from 'zod';

   const CheckoutSessionInputSchema = z.object({
     amount: z.number().positive('Amount must be positive'),
     currency_code: z.enum(['XOF']), // Ajuster les devises autorisées
     merchant_id: z.string().uuid('Invalid merchant ID'),
     success_url: z.string().url('Invalid success URL'),
     cancel_url: z.string().url('Invalid cancel URL'),
     // Autres champs...
   });

   function validateCheckoutRequest(data: unknown) {
     return CheckoutSessionInputSchema.safeParse(data);
   }
   ```

## Sécurité des webhooks

Voir [Configurer les webhooks](/build/reliability) et [Traiter les webhooks](/build/reliability/handling-webhooks) pour le détail.

### Vérification de signature

**Vérifiez toujours** l’en-tête `X-Lomi-Signature` des requêtes entrantes avec le `Signing Secret` (`LOMI_WEBHOOK_SECRET`) propre à votre URL. Cela empêche l’envoi d’événements malveillants ou falsifiés.

```typescript filename="Vérification de signature webhook (Node.js/Express)"
import crypto from 'crypto';
import express from 'express';

const LOMI_WEBHOOK_SECRET = process.env.LOMI_WEBHOOK_SECRET;

// Utiliser express.raw() sur la route webhook
// app.post('/your-webhook-endpoint', express.raw({ type: 'application/json' }), (req, res) => { ... });

function verifyWebhookSignature(
  rawBody: Buffer,
  signatureHeader: string | undefined,
  secret: string,
): boolean {
  if (!rawBody || !signatureHeader || !secret) {
    return false;
  }
  try {
    const hmac = crypto
      .createHmac('sha256', secret)
      .update(rawBody)
      .digest('hex');

    return crypto.timingSafeEqual(
      Buffer.from(signatureHeader),
      Buffer.from(hmac),
    );
  } catch (error) {
    console.error('Signature verification error:', error);
    return false;
  }
}
```

### Bonnes pratiques pour l’URL webhook

1. **HTTPS :** uniquement des URLs HTTPS pour recevoir les webhooks.
2. **Contrôle d’accès :** si possible, restreignez l’accès (par ex. liste d’IPs ; note : les IPs lomi. peuvent évoluer).
3. **Réponse rapide et traitement asynchrone :** répondez tout de suite avec `200 OK` et traitez l’événement en arrière-plan pour éviter les timeouts.
4. **Limite de débit :** appliquez du rate limiting sur l’URL webhook.
5. **Gestion d’erreurs :** en cas d’échec interne du traitement, journalisez, mais renvoyez toujours `200 OK` à lomi. si la signature était valide.

## Sécurité des données

### Données sensibles

1. **Minimalisation :** ne collectez et n’envoyez que les données nécessaires via l’API lomi. Évitez les informations client sensibles superflues.

   ```typescript filename="Réduire les données dans metadata"
   // Recommandé : identifiants internes
   const metadata = { order_id: 'internal-order-123' };

   // À éviter : PII sauf nécessité avérée et traitement conforme
   // const badMetadata = { user_password: '...', full_address: '...' };

   const session = await lomi.checkoutSessions.createCheckoutSession({
     // ... autres paramètres
     metadata: metadata,
   });
   ```

2. **Stockage sécurisé :** évitez de stocker des détails de paiement sensibles sauf nécessité et conformité (PCI DSS ; lomi. couvre le cœur du traitement conforme). Chiffrez les données au repos et contrôlez strictement les accès.

### Journalisation des erreurs

Soyez prudent dans les journaux : ne tracez pas clés API, secrets webhook ou données clients complètes.

```typescript filename="Journalisation assainie"
// Éviter les données sensibles dans les logs
function logError(error: Error, context?: Record<string, any>) {
  const sanitizedContext = { ...context };
  if (sanitizedContext?.apiKey) sanitizedContext.apiKey = '[REDACTED]';
  if (sanitizedContext?.customerPhone)
    sanitizedContext.customerPhone = '[REDACTED]';
  if (sanitizedContext?.rawBody) sanitizedContext.rawBody = '[REDACTED]';

  console.error('Error occurred:', {
    message: error.message,
    stack: error.stack, // Prudence avec les piles en production
    context: sanitizedContext,
  });
}
```

## Sécurité réseau

### Limitation du débit

Mettez en place du rate limiting sur vos propres endpoints qui appellent lomi. pour limiter les abus et les coûts.

```typescript filename="Rate limiting sur des routes Express"
import rateLimit from 'express-rate-limit';

const apiLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // 100 requêtes par IP et par fenêtre
  standardHeaders: true,
  legacyHeaders: false,
});

app.use('/api/', apiLimiter);
```

### Délais d’attente

Définissez des timeouts raisonnables pour les appels à l’API lomi. afin d’éviter des blocages infinis.

```typescript filename="Timeouts avec Axios"
import axios from 'axios';

const apiClient = axios.create({
  baseURL: 'https://api.lomi.africa',
  timeout: 15000,
  headers: { Authorization: `Bearer ${process.env.LOMI_SECRET_KEY}` },
});
```

## Surveillance et alertes

1. **Suivi d’activité :** surveillez l’usage de l’API, les taux de succès des paiements et les erreurs (Datadog, Sentry, Prometheus/Grafana, etc.).
2. **Alertes sur comportements suspects :**
   * Forte proportion d’échecs d’appels API ;
   * Échecs répétés de vérification de signature webhook ;
   * Pics ou chutes inattendus du volume de transactions ;
   * Tentatives avec des clés API révoquées.

## Pratiques de développement

1. **Sécurité du code :**
   * Maintenez SDKs et bibliothèques (notamment crypto) à jour ;
   * Utilisez des linters sécurité (plugins ESLint, etc.) ;
   * Réalisez des revues de code orientées sécurité ;
   * Assainissez toutes les entrées externes.
2. **Séparation des environnements :** configurations distinctes (clés API, secrets webhook) pour développement, préproduction et production.

   ```typescript filename="Configuration par environnement"
   const config = {
     development: {
       apiUrl: 'https://sandbox.api.lomi.africa',
       apiKey: process.env.LOMI_TEST_SECRET_KEY,
       webhookSecret: process.env.LOMI_TEST_WEBHOOK_SECRET,
     },
     production: {
       apiUrl: 'https://api.lomi.africa',
       apiKey: process.env.LOMI_PROD_SECRET_KEY,
       webhookSecret: process.env.LOMI_PROD_WEBHOOK_SECRET,
     },
   }[process.env.NODE_ENV || 'development'];

   const lomi = new LomiSDK({ apiKey: config.apiKey, baseUrl: config.apiUrl });
   const webhookSecret = config.webhookSecret;
   ```

<DocsNextSteps>
  <DocsNextStep href="/build/reliability/error-handling" hint="Réessais et échecs">
    Gestion des erreurs
  </DocsNextStep>

  <DocsNextStep href="/build/reliability/idempotency-keys" hint="Réessais sûrs">
    Clés d’idempotence
  </DocsNextStep>

  <DocsNextStep href="/api" hint="Requêtes et réponses exactes">
    Référence API
  </DocsNextStep>
</DocsNextSteps>
