Le RGPD dès la conception, et chaque affirmation testée
Une adresse est une donnée personnelle. Cette page liste exactement ce qu’Addrova journalise, stocke et ne conserve jamais. Chaque affirmation porte un identifiant et est reliée à un test automatique exécuté à chaque modification du code.
Les affirmations zéro log
Dans ces tableaux, « adresse » désigne toute saisie client : texte libre, composants, coordonnées demandées, fichiers batch. Les affirmations sont reprises telles quelles de la spécification zéro log de l’API.
Version de la spécification du 2026-10-19
Ce qui est journalisé (liste exhaustive)
| Id | Affirmation | Test automatique |
|---|---|---|
| ZL-01 | Une ligne par requête HTTP, avec exactement : méthode, gabarit de route (/v1/geocode, jamais l'URL réelle ni la chaîne de requête), statut, durée, tenant pseudonymisé, identifiant de requête aléatoire. Pas d'adresse IP, pas d'user-agent, pas de clé API. | api/tests/test_zerolog.py::test_access_log_exact_fields |
| ZL-02 | Les seuls autres messages émis par le code d'Addrova sont ceux de l'inventaire ci-dessous ; leurs paramètres sont des identifiants de job, des compteurs, des statuts ou des noms de types d'exception. | api/tests/test_privacy_claims.py::test_log_inventory_matches_code |
| ZL-03 | Le tenant est pseudonymisé partout (journaux, traces) : 16 caractères hexadécimaux d'un SHA-256 salé de son identifiant ; l'identifiant en clair n'apparaît pas. | api/tests/test_observability.py::test_tenant_hash_is_stable_and_opaqueapi/tests/test_zerolog.py::test_access_log_exact_fields |
Ce qui n’est jamais journalisé ni tracé
| Id | Affirmation | Test automatique |
|---|---|---|
| ZL-10 | Aucune adresse, aucune coordonnée demandée, aucune clé API n'apparaît dans les journaux, sur toutes les routes (géocodage, reverse, autocomplétion, réparation, batch, compatibilité Google et Nominatim), y compris en erreur (moteur en panne, entrée refusée, paramètre invalide, clé fausse, route inconnue). | api/tests/test_zerolog.py::test_canary_never_logged |
| ZL-11 | Les messages des bibliothèques tierces sont neutralisés : paramètres masqués, chaîne de requête effacée, exception réduite à son type (sans message ni trace). | api/tests/test_zerolog.py::test_third_party_logger_args_and_query_redacted |
| ZL-12 | Les réponses d'erreur ne renvoient pas la valeur fautive ni le message interne du moteur. | api/tests/test_api.py::test_geocode_invalid_paramsapi/tests/test_api.py::test_engine_errors_do_not_echo_query |
| ZL-13 | Les traces OpenTelemetry ne portent que des attributs d'une liste blanche (méthode, gabarit de route, statut, tenant pseudonymisé, opération moteur, pays, nombre de résultats, précision du premier résultat), sans événements ; ni adresse, ni coordonnée, ni clé, ni identifiant de tenant en clair. | api/tests/test_observability.py::test_spans_carry_only_allowlisted_attributesapi/tests/test_observability.py::test_span_content |
| ZL-15 | Console : l'adresse e-mail, les jetons de lien magique et les jetons de session n'apparaissent dans aucun journal. | api/tests/test_console.py::test_email_and_tokens_never_logged |
| ZL-16 | Démo publique du site (/demo/v1) : ni l'adresse saisie ni l'adresse IP du visiteur n'apparaissent dans les journaux ; l'IP n'est jamais stockée, seule une empreinte HMAC à secret quotidien (inutilisable après rotation) sert à compter les requêtes. | api/tests/test_demo.py::test_demo_never_logs_address_or_ipapi/tests/test_demo.py::test_fingerprint_rotates_daily_and_hides_ipapi/tests/test_demo.py::test_redis_mode_shares_secret_and_counters |
| ZL-14 | Les métriques Prometheus n'ont que des étiquettes à valeurs bornées ; un chemin inconnu est compté sous <unmatched>. | api/tests/test_observability.py::test_metrics_labels_are_boundedapi/tests/test_observability.py::test_spans_carry_only_allowlisted_attributes |
Ce qui est stocké, et combien de temps
| Id | Affirmation | Test automatique |
|---|---|---|
| ZL-20 | Les clés API sont stockées uniquement sous forme d'empreinte SHA-256 (plus 12 caractères de préfixe pour l'affichage). | api/tests/test_tenancy_persistent.py::test_keys_are_hashed_and_revocable |
| ZL-21 | La base ne contient aucune requête ni aucun résultat : seulement tenants, clés (empreintes) et compteurs d'usage (tenant, jour, endpoint, nombre). | api/tests/test_privacy_claims.py::test_schema_has_no_content_columns |
| ZL-22 | Batch : le fichier d'entrée est supprimé dès la fin du traitement ; le résultat et les métadonnées du job sont supprimés à la fin de la rétention (1 h après la fin par défaut, configurable) ou immédiatement sur DELETE ; un job jamais traité est purgé après 24 h. | api/tests/test_batch.py::test_csv_roundtrip_usage_and_input_purgeapi/tests/test_batch.py::test_isolation_delete_and_expiryapi/tests/test_batch.py::test_result_purged_after_retention |
| ZL-23 | Les métadonnées d'un job batch ne contiennent aucune ligne du fichier (compteurs, dates, noms de colonnes, pays par défaut). | api/tests/test_privacy_claims.py::test_batch_metadata_has_no_row_content |
| ZL-25 | Console : la seule donnée personnelle stockée est l'adresse e-mail du compte (et celle d'un lien de connexion en cours, valable 15 min, à usage unique) ; jetons de lien et de session stockés uniquement par empreinte SHA-256. | api/tests/test_privacy_claims.py::test_schema_has_no_content_columnsapi/tests/test_console.py::test_link_is_single_use_and_logout |
| ZL-26 | Une organisation ne voit ni les clés, ni l'usage d'une autre ; une clé révoquée ou expirée (rotation) est refusée. | api/tests/test_console.py::test_org_isolationapi/tests/test_console.py::test_keys_lifecycle_and_plan_limit |
| ZL-27 | Webhook de fin de batch : la charge utile ne contient que l'identifiant, le statut, les compteurs et les liens du job — jamais une ligne du fichier ni une adresse ; l'URL et le secret du webhook ne sont jamais journalisés. | api/tests/test_batch_stream.py::test_webhook_delivery_signed_without_addresses_and_retried |
| ZL-28 | Idempotence (Idempotency-Key) : seule une empreinte SHA-256 de la requête (et, pour un batch, l'identifiant du job) est conservée 24 h — jamais l'adresse envoyée ni la réponse. | api/tests/test_idempotency_versioning.py::test_idempotency_never_stores_addressapi/tests/test_idempotency_versioning.py::test_in_progress_conflict_and_stores_keep_no_content |
| ZL-29 | Aucune sortie réseau non déclarée : refus par défaut dans le namespace ; le site n'a aucune sortie ; l'API ne sort que vers le DNS du cluster, ses bases (PostgreSQL, Redis), le collecteur OTel interne et, pour les webhooks, HTTPS vers Internet public (plages privées, locales et de métadonnées exclues). Aucun outil tiers d'analyse ne peut recevoir de requête. | api/tests/test_k8s_hardening.py::test_egress_is_limited_to_declared_flowsapi/tests/test_k8s_hardening.py::test_namespace_is_restricted_and_denies_by_default |
| ZL-24 | Le job batch d'un client est invisible pour les autres clients. | api/tests/test_batch.py::test_isolation_delete_and_expiry |
Ce qui n’existe pas (encore)
| Id | Affirmation | Test automatique |
|---|---|---|
| ZL-30 | Le repli asynchrone de /v1/repair (LLM) est désactivé : aucun appel externe, aucune adresse ne quitte le service. | api/tests/test_repair.py::test_repair_unrepairable_and_async_disabled |
| ZL-32 | Aucun e-mail n'est réellement envoyé en v0 (boîte d'envoi en mémoire) et aucun fournisseur de facturation réel n'est branché (fournisseur factice). | api/tests/test_privacy_claims.py::test_no_external_transport_by_default |
| ZL-31 | Aucun cache de résultats n'est en place en v0 (le cache HMAC à secret tournant de l'ADR 0005 n'est pas encore implémenté). | api/tests/test_privacy_claims.py::test_no_result_cache_in_v0 |
Inventaire des messages de journal
Ce sont les seuls messages émis par le code, dans leur format exact. Un test échoue si le code et cette liste divergent.
%s %s %d %.1fms tenant=%s rid=%s
job %s queued rows=%d
job %s %s rows=%d matched=%d
job %s failed: %s
engine loaded: %s
addrova_engine not installed, using the fake engine
usage flush failed: %s
index preloaded: %d bytes
webhook job %s attempt %d status %s
engine contract violation: candidate without source
engine failure: %sHors du périmètre de ces tests
Ces points se vérifient autrement, et nous le disons :
- Ingress / proxy : son journal d'accès doit être désactivé sur les routes de l'API (ADR 0004) ; configuration d'infrastructure, à vérifier dans infra/ et sur le cluster.
- Moteur (addrova_engine) : il s'engage à ne pas journaliser les requêtes (ADR 0002) ; ses propres tests le vérifient.
- Export des traces : seulement si ADDROVA_OTLP_ENDPOINT est défini, vers un collecteur hébergé dans l'UE ; sans ce réglage, aucune trace ne quitte le processus.
- Stockage des fichiers batch : v0 sur disque local du conteneur (permissions 0600) ; stockage objet UE chiffré prévu pour la production (ADR 0006, ADR 0009).
Parce que rien n’est conservé, rien n’est réutilisé
Addrova n’utilise pas vos requêtes pour entraîner des modèles, constituer des jeux de données ou enrichir son index, et le code le concrétise : requêtes et résultats ne sont jamais journalisés (ZL-10), la base ne contient ni requête ni résultat (ZL-21), les fichiers batch sont supprimés après traitement (ZL-22), il n’y a pas de cache de résultats (ZL-31) et aucune adresse n’est envoyée à un service externe (ZL-30).
Pas encore revendiqué
- Hébergement exclusivement dans l’UE : l’hébergeur et la région ne sont pas encore publiés. [À VÉRIFIER]
- Sous-traitants et accord de traitement de données (DPA) : à publier, avec signature en ligne, avant le lancement. [À VÉRIFIER]
- Certifications : aucune revendiquée. ISO 27001 est prévue dans une étape ultérieure.
Sources de données et licences
Nous nous appuyons sur des données ouvertes officielles sous licences ouvertes (pour la France, Licence Ouverte 2.0). Chaque réponse de l’API porte un tableau d’attribution qui nomme ses sources. Les données sous licence avec partage à l’identique, comme OpenStreetMap, restent dans un index séparé et ne sont jamais fusionnées avec l’index officiel.
Questions sur la conformité
Puis-je vérifier ces affirmations ?
Chaque affirmation nomme le test automatique qui la vérifie. Les tests s’exécutent à chaque modification ; l’un d’eux échoue si un test cité disparaît ou si l’inventaire des journaux ne correspond plus au code. L’accès à la suite de tests pour un audit reste à définir. [À VÉRIFIER]
Journalisez-vous mon adresse IP ?
L’application non : son journal d’accès ne contient ni adresse IP, ni user-agent, ni clé d’API (ZL-01). L’ingress placé devant doit aussi avoir son journal d’accès désactivé ; c’est un réglage d’infrastructure, listé plus haut comme hors du périmètre des tests.
Combien de temps les résultats d’un batch sont-ils conservés ?
Une heure après la fin du traitement par défaut, ou jusqu’à ce que vous supprimiez le job (ZL-22). Le fichier d’entrée est supprimé dès la fin du traitement.