Aller au contenu

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=false

Le 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

TableCe qu’il stocke
cloud_accountscredentials du fournisseur (AES-256-GCM chiffrées), configuration de découverte
cloud_resourceschaque ressource découverte — VMs, stockage, réseau, services gérés
cloud_security_findingsrésultats des vérifications sans agent par ressource × check_id
cloud_cost_dailycoûts journaliers optionnels (Cost Explorer / Export de facturation)
cloud_discovery_runsjournal 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 + ciphertext

La 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/MonsysReadOnly avec 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/running etc.).

GCP (gcp)

  • Authentification : clé JSON de compte service. Requis roles/viewer sur 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éthodeChemin
GET /api/v1/cloud/accountsliste tous les comptes cloud
POST /api/v1/cloud/accountsnouveau compte (validation en direct des credentials + chiffrage)
DELETE /api/v1/cloud/accounts/:idsupprimer un compte (cascade vers les ressources)
POST /api/v1/cloud/accounts/:id/discoverdé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/:idressource unique avec trouvailles + données brutes
GET /api/v1/cloud/resources/:id/installcommandes d’installation de l’agent (curl / SSM / PowerShell)
GET /api/v1/cloud/summaryagré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

WorkerTickObjectif
CloudDiscoveryWorkertoutes les 15 minscanne 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).