Ga naar inhoud

Cloud Asset Discovery

/cloud ontdekt je infrastructuur bij elke cloud provider waar je een account toevoegt. Per discovery-run normaliseert de hub elke resource naar één universeel datamodel — zo werken alle features (topology, security findings, agent-koppeling, kosten-estimate) provider-agnostisch.

9 providers ondersteund: AWS, Azure, GCP, Hetzner, Proxmox, DigitalOcean, Scaleway, OVH, IONOS.

Pijplijn

Provider API ──► CloudResource (genormaliseerd)
▼ upsert in cloud_resources (UNIQUE per account+resource_id)
▼ agent matching op private_ip / public_ip → has_agent flag
▼ agentloze SecurityChecks per resource_type
▼ optioneel: auto-create topology_node voor VMs
▼ resources die niet in deze run zaten → is_active=false

De pijplijn loopt elke uur (worker-tick), maar elke cloud_account heeft een eigen discovery_interval_mins — default 240 min (4 uur). Een handmatige POST /accounts/:id/discover triggert een onmiddellijke run binnen seconden.

Datamodel

TabelWat het bewaart
cloud_accountsprovider-credentials (AES-256-GCM versleuteld), discovery-config
cloud_resourceselke ontdekte resource — VMs, storage, netwerk, managed services
cloud_security_findingsresultaat van agentloze checks per resource × check_id
cloud_cost_dailyoptionele dagelijkse kosten-rollup (Cost Explorer / Billing Export)
cloud_discovery_runsappend-only log van elke run met stats + provider-fouten

Alle tabellen hebben Postgres RLS aan met de tenant_isolation policy — per tenant geïsoleerd, ook bij directe DB-queries.

Credentials encryption

Elke provider-secret (AWS secret key, Hetzner API token, Stripe-style service-account JSON, OVH consumer key, …) wordt AES-256-GCM versleuteld opgeslagen in BYTEA kolommen. De master-sleutel staat in de env var CLOUD_ENCRYPTION_KEY (32 bytes hex). Zonder die var werkt de Cloud Discovery worker niet — handlers retourneren 503 zodat we nooit per ongeluk plaintext opslaan.

Versleuteld formaat op disk:

12-byte nonce ‖ ciphertext + 16-byte GCM tag

Decrypt gebeurt per discovery-run, in-memory; de plaintext raakt nooit een log of een DB-rij.

Providers per provider

AWS (aws)

  • Auth: IAM Role (aanbevolen, arn:aws:iam::…:role/MonsysReadOnly met optionele External ID) of IAM User access key.
  • Discovery: EC2 Instances, VPCs, Subnets, Security Groups, Load Balancers, RDS Instances, S3 Buckets.
  • Security checks: S3 Public Access Block, S3 encryption, RDS encryption, RDS public access, RDS backup retention, RDS deletion protection, SG open SSH/RDP/All-traffic, EC2 IMDSv2-required, EC2 publiek IP.
  • Multi-region: ja, lijst van AWS regio’s per account.
  • Vereiste IAM permissions: ec2:Describe*, rds:Describe*, s3:List* + s3:GetBucketPublicAccessBlock + s3:GetBucketEncryption, elasticloadbalancing:Describe*.

Azure (azure)

  • Auth: Service Principal — subscription_id, tenant_id, client_id, client_secret. Reader-rol op de subscription.
  • Discovery: Virtual Machines, VNets + Subnets, Network Security Groups (NSGs), SQL Servers, Storage Accounts.
  • Security checks: NSG open SSH/RDP, NSG allow-all, SQL Public Network Access, Storage AllowBlobPublicAccess, Storage HTTPS-only.
  • VM-state: gelezen uit InstanceView.Statuses (PowerState/running etc.).

GCP (gcp)

  • Auth: Service Account JSON key. Vereist roles/viewer op het project (of fijnmaziger: compute.viewer + storage.objectViewer + cloudsql.viewer).
  • Discovery: GCE Instances (cross-zone via AggregatedList), VPCs, Subnetworks, Firewalls (globaal), Cloud SQL, GCS Buckets.
  • Security checks: Firewall open SSH/RDP/all-traffic vanaf 0.0.0.0/0, GCS Public Access Prevention niet enforced, GCS geen Uniform Bucket-Level Access, Cloud SQL met Ipv4Enabled=true.

Hetzner Cloud (hetzner)

  • Auth: read-only API token uit Project → Security → API Tokens.
  • Discovery: Servers (paginated), Networks, Firewalls, Volumes.
  • Security checks: open SSH/RDP firewall-regels, publieke IPv4 op servers.
  • Geen officiële Go-SDK — hand-rolled REST client tegen api.hetzner.cloud.

Proxmox VE (proxmox)

  • Auth: PVEAPIToken in formaat user@realm!tokenid=secret. PVEAuditor rol op / is voldoende.
  • Discovery: Qemu VMs, LXC containers, nodes, storage. Guest-IP via qemu-guest-agent indien beschikbaar.
  • Security checks: publiek-routeerbare IPs (RFC1918-aware).
  • SSL: optioneel (verify_ssl=false voor self-signed clusters).

DigitalOcean (digitalocean)

  • Auth: Personal Access Token (read scope volstaat).
  • Discovery: Droplets, Volumes, VPCs, Firewalls, Managed Databases, Load Balancers.
  • Security checks: Firewall open SSH/RDP, DB zonder Trusted Sources, DB SSL-optioneel, Droplet publiek IP.

Scaleway (scaleway)

  • Auth: Access Key + Secret Key + Organization/Project ID + default zone (default fr-par-1).
  • Discovery: Instances, Volumes, Security Groups (met regels), RDB databases.
  • Security checks: SG default-policy=accept, SG open SSH/RDP, RDB publiek endpoint, RDB encryption uit.

OVH Public Cloud (ovh)

  • Auth: 3-key flow — application_key + application_secret + consumer_key. Endpoint configureerbaar (ovh-eu / ovh-ca / ovh-us / kimsufi-eu / soyoustart-eu).
  • Discovery: Public Cloud instances, volumes, private networks, failover IPs. Vereist een service_name (Public Cloud project ID).
  • Security checks: publieke IPs op instances.
  • Bijzonderheid: elke request wordt HMAC-SHA1 gesigneerd; we sync’en eerst de servertijd via /auth/time.

IONOS Cloud (ionos)

  • Auth: bearer token uit dcd.ionos.com → Token Manager.
  • Discovery: data centers (top-level), servers (cross-DC), LANs, volumes.
  • Security checks: LAN gemarkeerd als public, server met publiek-routeerbaar IP.

Agent-matching

Wanneer een resource een private of public IP heeft, zoekt de worker een bestaande Monsys-agent met dezelfde agents.ip_address. Match → has_agent=true

  • agent_id gevuld, agent_missing_since gewist. Geen match op een running resource → agent_missing_since = NOW() (idempotent — eerste sighting blijft behouden).

In de UI verschijnt voor elke unmatched resource een Installeer agent knop die via de bestaande create_agent_token() SQL-functie een verse tenant-token mint en Linux- (curl), Windows- (PowerShell) en AWS-SSM-commando’s terugstuurt.

Auto-create topology nodes

Wanneer auto_create_nodes=true op het cloud_account staat, krijgen alle VM-class resources (ec2_instance, azure_vm, gcp_instance, hetzner_server, proxmox_vm, proxmox_container, do_droplet, ovh_instance, scaleway_instance, ionos_server) automatisch een rij in topology_nodes met managed_by_monsys=false en de cloud-IPs voorgevuld. Het architectuurdiagram groeit dus mee met je infrastructuur.

API

MethodePad
GET /api/v1/cloud/accountslijst alle cloud-accounts
POST /api/v1/cloud/accountsnieuw account (live credential-validatie + AES encrypt)
DELETE /api/v1/cloud/accounts/:idaccount verwijderen (cascade naar resources)
POST /api/v1/cloud/accounts/:id/discovertrigger directe discovery-run
GET /api/v1/cloud/resources?account_id=&type=&has_agent=&is_public=resources met filters
GET /api/v1/cloud/resources/:idsingle resource met findings + raw data
GET /api/v1/cloud/resources/:id/installagent install-commands (curl / SSM / PowerShell)
GET /api/v1/cloud/summaryaggregaten per account
GET /api/v1/cloud/findings?severity=&status=alle security findings tenant-breed
GET /api/v1/cloud/runs?account_id=discovery-run geschiedenis

Worker-cadence

WorkerTickDoel
CloudDiscoveryWorkerelke 15 minscant cloud_accounts waar last_sync_at + interval verstreken is, fork goroutine per account

Failure-modes worden vast­gelegd in cloud_discovery_runs.provider_errors (JSON array). Een run waar 2 van 3 passes slagen krijgt status partial — zo zie je in de UI het verschil tussen “geen toegang tot RDS” en “complete catastrofe”.

Beperkingen

  • Geen real-time kosten — geschatte uurprijs per instance type, niet via Cost Explorer / Cost Management / Billing Export. Voor exacte facturatie: enable de provider’s eigen billing-export pijplijn.
  • Kubernetes nodes: AKS / EKS / GKE worker-nodes worden ontdekt als generieke VMs maar niet als Kubernetes-resources. Pod-discovery komt later.
  • Object Storage diepgang: we tonen buckets en hun publieke flag — niet de individuele objects of hun ACLs (te duur op echte buckets).
  • Geen automatic agent install — we tonen install-commando’s, je voert ze zelf uit. Een toekomstige versie van de hub kan via SSM / Azure Run Command / GCP Startup Scripts de agent direct uitrollen.

Gerelateerd

  • Topology — auto-created cloud nodes verschijnen hier.
  • Diagrammen — gebruik de topology-graph als basis voor PNG/SVG/PDF export.
  • Security findings dragen framework_refs (CIS, ISO 27001, GDPR) en feeden de compliance-evidence pijplijn.