Découverte d'actifs cloud
/cloud découvre votre infrastructure chez chaque fournisseur de services cloud où vous avez ajouté un compte. Pour chaque run de découverte, la hub normalise chaque ressource à un modèle de données universel — ainsi toutes les fonctionnalités (topologie, trouvailles de sécurité, liaison d’agent, estimation de coûts) sont indépendantes du fournisseur.
9 fournisseurs pris en charge : AWS, Azure, GCP, Hetzner, Proxmox, DigitalOcean, Scaleway, OVH, IONOS.
Flux
API du fournisseur ──► CloudResource (normalisé) │ ▼ insertion dans cloud_resources (UNIQUE par compte+resource_id) │ ▼ correspondance d'agent sur private_ip / public_ip → has_agent flag │ ▼ vérifications de sécurité sans agent par type de ressource │ ▼ optionnel : création automatique de topology_node pour les VMs │ ▼ ressources qui n'étaient pas présentes dans cette run → is_active=falseLe flux s’exécute toutes les heures (tick du worker), mais chaque cloud_account a son propre intervalle de découverte en minutes — par défaut 240 min (4 heures). Une requête POST /accounts/:id/discover déclenche une run immédiate dans quelques secondes.
Modèle de données
| Table | Ce qu’il stocke |
|---|---|
cloud_accounts | credentials du fournisseur (AES-256-GCM chiffrées), configuration de découverte |
cloud_resources | chaque ressource découverte — VMs, stockage, réseau, services gérés |
cloud_security_findings | résultats des vérifications sans agent par ressource × check_id |
cloud_cost_daily | coûts journaliers optionnels (Cost Explorer / Export de facturation) |
cloud_discovery_runs | journal d’appel de chaque run avec stats + erreurs du fournisseur |
Toutes les tables ont RLS Postgres avec la politique tenant_isolation — isolées par tenant, même pour les requêtes directes sur la base.
Chiffrement des credentials
Chaque secret du fournisseur (clé secrète AWS, token API Hetzner, JSON de compte service Stripe-style, clé consommatrice OVH, …) est chiffré avec AES-256-GCM et stocké dans des colonnes BYTEA. La clé maître est dans la variable d’environnement CLOUD_ENCRYPTION_KEY (32 octets hex). Sans cette variable, le worker de découverte cloud ne fonctionne pas — les handlers renvoient 503 pour éviter l’écriture de texte en clair.
Format chiffré sur disque :
nonce de 12 octets ‖ tag GCM de 16 octets + ciphertextLa déchiffrement se fait par run de découverte, en mémoire ; le texte clair ne passe jamais dans un journal ou une ligne de base.
Fournisseurs par fournisseur
AWS (aws)
- Authentification : rôle IAM (recommandé,
arn:aws:iam::…:role/MonsysReadOnlyavec optionnel External ID) ou clés d’accès utilisateur IAM. - Découverte : instances EC2, VPCs, sous-réseaux, groupes de sécurité, chargeurs de balance, instances RDS, compartiments S3.
- Vérifications de sécurité : blocage d’accès public S3, chiffrement S3, chiffrement RDS, accès public RDS, rétention des sauvegardes RDS, protection contre la suppression RDS, groupes de sécurité ouverts SSH/RDP/Tout le trafic, IMDSv2 requis EC2, IP publique EC2.
- Multi-région : oui, liste des régions AWS par compte.
- Permissions IAM requises :
ec2:Describe*,rds:Describe*,s3:List*+s3:GetBucketPublicAccessBlock+s3:GetBucketEncryption,elasticloadbalancing:Describe*.
Azure (azure)
- Authentification : principal de service —
subscription_id,tenant_id,client_id,client_secret. Rôle lecteur sur la souscription. - Découverte : machines virtuelles, réseaux virtuels + sous-réseaux, groupes de sécurité réseau (NSG), serveurs SQL, comptes de stockage.
- Vérifications de sécurité : NSG ouvert SSH/RDP, NSG autoriser tout le trafic, accès public SQL, stockage autoriser BlobPublicAccess, stockage HTTPS uniquement.
- État de la VM : lu dans
InstanceView.Statuses(PowerState/runningetc.).
GCP (gcp)
- Authentification : clé JSON de compte service. Requis
roles/viewersur le projet (ou plus fin :compute.viewer+storage.objectViewer+cloudsql.viewer). - Découverte : instances GCE (par zone via AggregatedList), réseaux, sous-réseaux, pare-feu globaux, serveurs SQL, compartiments GCS.
- Vérifications de sécurité : pare-feu ouvert SSH/RDP/tout le trafic depuis 0.0.0.0/0, GCS Public Access Prevention non appliqué, GCS sans Uniform Bucket-Level Access, serveur SQL avec
Ipv4Enabled=true.
Hetzner (hetzner)
- Authentification : token API.
- Découverte : serveurs, disques, réseaux, groupes de sécurité.
- Vérifications de sécurité : blocage d’accès public, chiffrement.
Proxmox (proxmox)
- Authentification : clé API.
- Découverte : machines virtuelles, conteneurs, disques, réseaux, groupes de sécurité.
- Vérifications de sécurité : blocage d’accès public.
DigitalOcean (do)
- Authentification : token API.
- Découverte : droplets, disques, réseaux, groupes de sécurité.
- Vérifications de sécurité : blocage d’accès public.
Scaleway (scaleway)
- Authentification : clé API.
- Découverte : instances, disques, réseaux, groupes de sécurité.
- Vérifications de sécurité : blocage d’accès public.
OVH (ovh)
- Authentification : clé API.
- Découverte : instances, disques, réseaux, groupes de sécurité.
- Vérifications de sécurité : blocage d’accès public.
IONOS (ionos)
- Authentification : clé API.
- Découverte : serveurs, disques, réseaux, groupes de sécurité.
- Vérifications de sécurité : blocage d’accès public.
API
| Méthode | Chemin |
|---|---|
GET /api/v1/cloud/accounts | liste tous les comptes cloud |
POST /api/v1/cloud/accounts | nouveau compte (validation en direct des credentials + chiffrage) |
DELETE /api/v1/cloud/accounts/:id | supprimer un compte (cascade vers les ressources) |
POST /api/v1/cloud/accounts/:id/discover | déclencher une run de découverte directe |
GET /api/v1/cloud/resources?account_id=&type=&has_agent=&is_public= | ressources avec filtres |
GET /api/v1/cloud/resources/:id | ressource unique avec trouvailles + données brutes |
GET /api/v1/cloud/resources/:id/install | commandes d’installation de l’agent (curl / SSM / PowerShell) |
GET /api/v1/cloud/summary | agrégats par compte |
GET /api/v1/cloud/findings?severity=&status= | toutes les trouvailles de sécurité tenant-breed |
GET /api/v1/cloud/runs?account_id= | historique des runs de découverte |
Cadence du worker
| Worker | Tick | Objectif |
|---|---|---|
CloudDiscoveryWorker | toutes les 15 min | scanne les comptes cloud où last_sync_at + interval est dépassé, fork goroutine par compte |
Les modes de panne sont fixés dans cloud_discovery_runs.provider_errors (tableau JSON). Une run avec 2 des 3 passes réussies a un statut partial — ainsi vous voyez dans l’interface utilisateur la différence entre “pas d’accès à RDS” et “catastrophe complète”.
Limites
- Pas de coûts en temps réel : estimation de coût par heure par type d’instance, pas via Cost Explorer / Cost Management / Export de facturation. Pour la facturation exacte : activez la pipeline d’export de facturation du fournisseur.
- Nœuds Kubernetes : les nœuds AKS / EKS / GKE sont découverts comme des VM génériques mais pas comme des ressources Kubernetes. La découverte de pods arrive plus tard.
- Profondeur des compartiments de stockage : nous montrons les compartiments et leur drapeau public — pas les objets individuels ou leurs ACLs (trop coûteux sur les vrais compartiments).
- Pas d’installation automatique de l’agent : nous montrons les commandes d’installation, vous les exécutez vous-même. Une future version de la hub peut via SSM / Azure Run Command / GCP Startup Scripts déployer directement l’agent.
Liens
- Topologie — les nœuds cloud automatiquement créés apparaissent ici.
- Diagrammes — utilisez la graphique de topologie comme base pour PNG/SVG/PDF export.
- Conformité — les trouvailles de sécurité contribuent aux framework_refs (CIS, ISO 27001, GDPR).