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=falseDe 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
| Tabel | Wat het bewaart |
|---|---|
cloud_accounts | provider-credentials (AES-256-GCM versleuteld), discovery-config |
cloud_resources | elke ontdekte resource — VMs, storage, netwerk, managed services |
cloud_security_findings | resultaat van agentloze checks per resource × check_id |
cloud_cost_daily | optionele dagelijkse kosten-rollup (Cost Explorer / Billing Export) |
cloud_discovery_runs | append-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 tagDecrypt 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/MonsysReadOnlymet 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/runningetc.).
GCP (gcp)
- Auth: Service Account JSON key. Vereist
roles/viewerop 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-agentindien beschikbaar. - Security checks: publiek-routeerbare IPs (RFC1918-aware).
- SSL: optioneel (
verify_ssl=falsevoor 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_idgevuld,agent_missing_sincegewist. 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
| Methode | Pad |
|---|---|
GET /api/v1/cloud/accounts | lijst alle cloud-accounts |
POST /api/v1/cloud/accounts | nieuw account (live credential-validatie + AES encrypt) |
DELETE /api/v1/cloud/accounts/:id | account verwijderen (cascade naar resources) |
POST /api/v1/cloud/accounts/:id/discover | trigger directe discovery-run |
GET /api/v1/cloud/resources?account_id=&type=&has_agent=&is_public= | resources met filters |
GET /api/v1/cloud/resources/:id | single resource met findings + raw data |
GET /api/v1/cloud/resources/:id/install | agent install-commands (curl / SSM / PowerShell) |
GET /api/v1/cloud/summary | aggregaten 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
| Worker | Tick | Doel |
|---|---|---|
CloudDiscoveryWorker | elke 15 min | scant cloud_accounts waar last_sync_at + interval verstreken is, fork goroutine per account |
Failure-modes worden vastgelegd 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.