cloud_enum: multi-cloud OSINT enumeration for exposed storage and apps
Multi-cloud OSINT tool. Enumerate public resources in AWS, Azure, and Google Cloud.
At a glance
- What is it?
- A Python tool that mutates keywords into cloud resource names and checks AWS, Azure and Google Cloud for anything left publicly reachable. Its author now recommends migrating the logic to Nuclei.
- Who is it for?
- cloud_enum is at its most useful for the two services that need per-region guessing: Azure blob containers and Google Cloud Functions, because the name mutation list is doing work you would otherwise have to write yourself. The AWS, S3 and Firebase checks are closer to pattern scanning and can be replaced by templates more easily.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 92 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A tool the author built for one pentest and now wants folded into Nuclei
The README opens with a status note rather than a feature list, and that framing is the most important thing on the page. The tool was written in 2019 for a penetration test involving Azure, back when nothing else supported that provider. It grew through contributions, and release 0.8 records a wide mix of them: added Firebase response handling, a switch to the MIT license, payload length capped at 63 characters, an expanded fuzzing list, and a change of default DNS resolver to Cloudflare.
What the author says now is that maintaining tools is hard, that they have not actively used it for a while, and that it makes sense to consolidate this functionality into a well maintained project that handles the groundwork. Nuclei is named as that project, and a link to the first migration pull request against the Nuclei template repository is included. The author asks others to contribute templates there instead, and says they will still try to review pull requests for bugs as time permits but likely will not have time for major changes.
The last push on the default branch was 2026-07-09, so commits are still landing, and there is only one open issue. That is worth weighing carefully rather than reading as contradiction: recent commits here look like maintenance and small fixes rather than new capability, which is exactly what the README says to expect.
Installing with uv instead of pip
Dependency management moved to uv, and the setup step is one command. The project declares itself as a console script named `cloud_enum`, and requires Python 3.10 or newer.
uv syncThe `pyproject.toml` is small enough to read in full, which is unusual for a tool that grew through years of contributions. Runtime dependencies are `dnspython`, `requests` and `requests-futures`, with `pytest` in the dev group. The packaging block is minimal: one top level module named `cloud_enum` and one package named `enum_tools`.
[project]
name = "cloud_enum"
version = "0.8"
description = "Multi-cloud OSINT tool. Enumerate public resources in AWS, Azure, and Google Cloud."
requires-python = ">=3.10"
dependencies = [
"dnspython>=2.8.0",
"requests>=2.34.2",
"requests-futures>=1.0.2",
]Only three runtime dependencies is a genuinely pleasant property for a security tool, because the supply chain surface stays small and the install is fast. The version in the file matches the 0.8 tag published in May 2026.
Keyword mutation is the actual engine
The tool takes keywords and expands them into candidate resource names. The README's example imagines a company called somecompany with the domain somecompany.io and a product named blockchaindoohickey:
uv run cloud_enum -k somecompany -k somecompany.io -k blockchaindoohickeyThe keyword argument repeats as many times as needed, and the README warns that the built in fuzzing strings give worse results than supplying your own through the mutation flag or the brute force flag. Mutations come from `enum_tools/fuzz.txt` by default. The same list is reused for the services that need a second level of brute forcing, namely Azure containers and Google Cloud Functions, unless a separate file is passed to the brute flag.
So there are two distinct name generation strategies in play. Mutation is combinatorial expansion of what you already know, which finds names that follow company naming conventions. Brute forcing against a word list is the older approach that works when a name is not derived from anything you can guess. Both read from the same file by default, which keeps configuration down to one thing to edit.
The README also credits GCPBucketBrute for some of the permutations in the list, so the mutation data is borrowed rather than invented. That matters for judging coverage: the list is as good as its sources, and improving it is the most obvious way to contribute.
Reading the two region files before you scan
The single most consequential thing in the repository is a caveat in the README about speed. Azure containers and Google Cloud Functions are discovered per region, so a full sweep across every region is slow enough to be impractical. Rather than deal with that at runtime, the project hard codes the region lists in two Python modules, and both default to a single region.
The README spells this out as important and tells you to open `cloudenum/azure_regions.py` and `cloudenum/gcp_regions.py` and edit them to match your own work. Note that the path in the README is misspelled, which is a small thing but the kind of detail worth knowing before you go looking for the file and conclude it is missing. The naming convention is consistent with a package that was renamed from the full name at some point without every reference following.
In practice this means a scan is not a global search by default. If you are assessing an organisation with a known Azure footprint, narrowing the list to the regions they actually use turns a slow scan into a fast one, and widening it is a deliberate cost you decide to pay rather than a default you inherit.
Logging formats added in 0.7 and what a finding looks like
Release 0.7, from April 2022, is the last one with a hand written description rather than an automated change list. It added selectable log output in text, json or csv, and specifically added tagging of findings based on how public or accessible they are. That distinction matters more than it sounds: an open bucket and a bucket that answers but denies anonymous writes are different findings for a report, and machine readable output lets you carry that distinction into a tracker instead of retyping it.
The usage block in the README shows the full flag surface and is worth reading as the real documentation. Beyond the keyword, keyfile, mutation and brute force options, there is a thread count for HTTP brute forcing defaulting to 5, an overridable DNS server, an append mode logfile with the same three format choices, and per provider disable switches for AWS, Azure and GCP.
uv run cloud_enum -k keyword -t 10That thread flag is the example given for raising concurrency. The README pairs it with a plain warning that you can increase it but the providers will eventually rate limit you, which is a reminder that this whole category of tool operates in someone else's infrastructure and the constraint is theirs, not yours.
Repository layout and what is missing
The tree is short: `cloud_enum.py` at the root as the entry module, `enum_tools/` for the fuzzing data, `tests/`, a `manpage/` directory, and the usual `.github/` and `LICENSE`. Having a `manpage/` is a small touch that most comparable tools skip.
What is not there is documentation of the individual check functions. The README tells you which services are enumerated, but nothing describes what response pattern counts as a hit for each one, and there are no tagged releases between 0.6 in October 2020, 0.7 in April 2022 and 0.8 in May 2026. The repository has 2,142 stars, 308 forks and a single open issue, so interest is real while the conversation volume is not.
For a tool in this position, the honest reading is that it works, it does a specific job nobody else did for Azure in 2019, and the maintainer has told you plainly where the future lives. Running it now for a one off assessment is reasonable. Building a new workflow on top of it is a bet against the author's own stated direction, and the mitigation the repository itself offers is to port what you need into Nuclei templates.
Editorial conclusion
cloud_enum is at its most useful for the two services that need per-region guessing: Azure blob containers and Google Cloud Functions, because the name mutation list is doing work you would otherwise have to write yourself. The AWS, S3 and Firebase checks are closer to pattern scanning and can be replaced by templates more easily. The repository itself points at that future, since the first release notes page already links the migration pull request and the author states plainly that major changes are unlikely. For a one-off engagement, install it with uv, read the two region files before scanning, and treat the mutation list as the part worth contributing back.
Frequently asked questions
What does cloud_enum actually enumerate?
Publicly reachable resources across three clouds. For AWS it checks open and protected S3 buckets plus the awsapps subdomains used by services such as WorkMail, WorkDocs and Connect. For Azure it covers storage accounts, open blob containers, hosted databases, virtual machines and web apps. For Google Cloud it covers buckets, Firebase realtime databases and apps, App Engine sites and Cloud Functions.
Is cloud_enum still maintained?
The author says plainly that they have not actively used it for a while, will try to review pull requests as time permits, and are unlikely to take major changes. The last push was 2026-07-09 and release 0.8 shipped in May 2026, so fixes still land. The README recommends contributing detection templates to Nuclei instead.
How do I get better results than the built in word list?
Supply your own. The README says the built in fuzzing strings give worse results than passing your own, and the built in list is credited partly to GCPBucketBrute. The mutation flag controls the list used for expanding keywords, and the brute force flag sets the list used for Azure containers and Google Cloud Functions.
Why does my Azure or Google scan take so long?
Because those two services are enumerated per region, and the region lists in `cloudenum/azure_regions.py` and `cloudenum/gcp_regions.py` default to a single region to keep scans fast. The README tells you to open those files and edit them to match your target, which turns the scan from a global sweep into a focused one.
Should I use cloud_enum or Nuclei templates?
For anything ongoing, the author points at Nuclei as the destination, since Nuclei already handles the request, DNS, threading, I/O and logging groundwork and a migration pull request has been opened. cloud_enum still makes sense for a one off engagement, or when you specifically need the Azure container and Cloud Function name brute forcing that the migration may not cover identically.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/initstring-cloud-enum)