This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Cloudlist is a multi-cloud asset discovery tool written in Go that enumerates resources (IPs, DNS names) from various cloud providers using their APIs. It's designed for blue team security operations to maintain centralized cloud asset inventories.
# Build the binary
make build
# or
go build -v -o cloudlist cmd/cloudlist/main.go# Run all tests
make test
# or
go test -v ./...
# Run tests for specific package
go test -v ./pkg/providers/aws/# Run golangci-lint (same as CI)
golangci-lint run --timeout 5m
# Auto-fix issues
golangci-lint run --fix --timeout 5m# Basic usage
./cloudlist -pc ~/.config/cloudlist/provider-config.yaml
# Filter by provider
./cloudlist -pc provider-config.yaml -p aws,gcp
# Filter by service
./cloudlist -pc provider-config.yaml -s compute,dns
# Output formats
./cloudlist -pc provider-config.yaml -json > output.json
./cloudlist -pc provider-config.yaml -host # DNS names only
./cloudlist -pc provider-config.yaml -ip # IPs only-
Provider Interface (
pkg/schema/schema.go:18-28)- All providers implement the
schema.Providerinterface - Key methods:
Name(),ID(),Resources(ctx),Services() - Returns
*schema.Resourcescontaining[]*schema.Resource
- All providers implement the
-
Provider Registration (
pkg/inventory/inventory.go:92-137)nameToProvider()function maps provider names to implementations- Add new providers here as a case statement
-
Resource Model (
pkg/schema/schema.go:142-163)- Each resource represents a cloud asset with IP/DNS information
- Fields:
Public,Provider,Service,ID,PublicIPv4/v6,PrivateIpv4/v6,DNSName,Metadata - Resources are automatically deduplicated by IP/DNS values
-
Provider Structure Pattern
- Providers in
pkg/providers/<provider>/ - Main file:
<provider>.gowithNew()constructor andResources()implementation - Service-specific files:
instances.go,dns.go, etc. for complex providers (see AWS) - Each provider has a
Servicesslice listing supported service types
- Providers in
When implementing providers, follow this structure:
-
Main provider file (
<provider>.go):- Struct with provider-specific client and configuration
New(block schema.OptionBlock)constructor that validates configResources(ctx context.Context) (*schema.Resources, error)that orchestrates resource gathering- Service-specific helper methods
-
Service-specific files (for complex providers):
- AWS example:
instances.go,route53.go,s3.go,eks.go, etc. - Each file handles one service type's resource enumeration
- Returns
*schema.Resourcesthat mainResources()method merges
- AWS example:
-
Configuration Parsing:
- Use
block.GetMetadata(key)to read config values - Environment variables supported via
$VAR_NAMEsyntax (auto-resolved) - Return
&schema.ErrNoSuchKey{Name: key}for missing required config
- Use
- Resource Deduplication: Resources are automatically deduplicated by the
ResourceDeduplicatorin schema - Service Filtering: Users can filter by service via
-sflag; providers check this inServices()method - Metadata: Extended metadata can be added to resources via the
Metadatamap[string]string field - Context Handling: All provider
Resources()methods receive context for cancellation support
Required steps:
-
Create provider directory:
pkg/providers/<provider-name>/ -
Implement provider struct with these methods:
func New(block schema.OptionBlock) (schema.Provider, error) func (p *Provider) Name() string func (p *Provider) ID() string func (p *Provider) Resources(ctx context.Context) (*schema.Resources, error) func (p *Provider) Services() []string
-
Register in inventory: Add case to
nameToProvider()inpkg/inventory/inventory.go -
Add to services map: Add provider and its services to
Providersmap inpkg/inventory/inventory.go -
Document configuration: Add provider config documentation to
PROVIDERS.md
See reference implementations:
- Simple:
pkg/providers/digitalocean/(single service) - Complex:
pkg/providers/aws/(multiple services, sub-files) - With special auth:
pkg/providers/gcp/(JSON service account keys)
cmd/cloudlist/main.go- CLI entry pointinternal/runner/runner.go- Main enumeration orchestratorinternal/runner/options.go- CLI flag definitionspkg/schema/schema.go- Core interfaces and data structurespkg/inventory/inventory.go- Provider registration and factorypkg/providers/*/- Individual cloud provider implementations
GCP provider supports two discovery modes:
- Individual Service APIs (default): Project-level discovery using service-specific APIs
- Organization-Level Asset API: Org-wide discovery when
organization_idis specified
Key distinction in code:
- Check for
organization_idin config to determine mode - Asset API mode uses
cloud.google.com/go/assetpackage - Individual APIs mode uses service-specific clients (compute, dns, etc.)
See docs/GCP_ASSET_API.md for detailed implementation guide.
- Integration tests require cloud provider credentials (usually skipped in CI)
- Unit tests should mock cloud provider clients
- Use table-driven tests for resource parsing logic
- Test error handling for missing/invalid credentials
- lint-test.yml: Runs
golangci-linton Go code changes - build-test.yml: Tests builds on Ubuntu, Windows, macOS with Go 1.22.x
- release-binary.yml: Creates releases with GoReleaser
- Resource fields: Either IP or DNS must be populated; empty resources are invalid
- Provider IDs: The
idfield in config is user-defined for filtering, not a cloud resource ID - Service names: Must match entries in provider's
Servicesslice and inventory'sProvidersmap - Credential handling: Use environment variables (
$VAR) in config rather than hardcoding - Context cancellation: Always respect context in long-running API calls
- Deduplication: Don't manually deduplicate; use
Resources.Append()which handles it automatically
- Go version: 1.24+ (see
go.mod) - Module path:
github.com/projectdiscovery/cloudlist - Key dependencies:
- Provider SDKs:
aws-sdk-go,azure-sdk-for-go,google.golang.org/api, etc. - ProjectDiscovery libs:
goflags,gologger,utils - Concurrency:
github.com/alitto/pond/v2for worker pools
- Provider SDKs: