Build Cloudcraft
KINDAback to the verdict
A diagramming tool that draws what is actually deployed by reading a cloud account read only, where the engineering is turning a flat list of resources into a readable topology and the discipline is knowing that a diagram is stale the moment it is drawn.
Before step 1
Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.
- installfree
Why Runs the scanner and the renderer.
Get it nodejs.org, or nvm install 22. open ↗
Verify
node --version prints v22 or higher - accountfree
Why The whole build depends on enumerating real infrastructure, and the read-only constraint has to be true of the credentials rather than of your intentions.
Get it Create a role or key with a read-only policy, scoped to the account you will scan, and verify a write is denied before scanning.
Verify
A write attempt with these credentials is denied - have readyfree to scan; the account itself costs what it costs
Why Layout, collapsing and readability are all uninteresting on a small account and become the entire problem on a real one.
Get it A real account you have permission to scan, ideally one with several regions and networks.
Verify
A scan returns at least a hundred resources across more than one region - decidefree
Why Secret-bearing fields are excluded at collection, which means deciding which they are before the first scan rather than after they are in the database.
Get it List the fields that can contain credentials, connection strings or keys for the resource types you will scan, and exclude them explicitly.
Verify
A written exclusion list exists and is applied in the collector - decidefree
Why An architecture diagram is a map of your estate for anyone attacking you, and the default matters more than the option.
Get it Decide what is redacted by default and who may produce an unredacted export.
Verify
A written note states the default redaction and who may override it
Data model
Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.
- scans(id, account_ref, regions_json, started_at, finished_at, resource_count, partial_reason) - resources(id, scan_id, kind, identifier, name, region, tags_json, config_summary_json, observed_at) - edges(from_resource_id, to_resource_id, kind, confidence, evidence) · kind is contains, connects, permits or infers - boundaries(id, scan_id, kind, identifier, parent_id) · accounts, networks and subnets as nesting - diagrams(id, scan_id, layout_json, redaction_level, generated_at) - drifts(id, from_scan_id, to_scan_id, resource_identifier, change_kind, detail) · what changed between scans - An edge records its evidence, because a connection read from a configuration and one inferred from a naming convention are different claims.
Environment variables
These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.
| Variable | Needed | Example | Where the value comes from |
|---|---|---|---|
DB_PATH | required | ./scans.db | Collected inventory. Sensitive, since it describes your entire estate. |
CLOUD_CREDENTIALSsecret | required | a read-only profile name | Read only. A write attempt must fail. |
SCAN_REGIONS | required | eu-west-1,eu-west-2 | Which regions to enumerate. Omissions are recorded rather than silent. |
STALE_AFTER_HOURS | required | 72 | Past this a diagram is visibly marked stale, including in exports. |
EXPORT_REDACTION_DEFAULT | required | full | A diagram is a map for an attacker. The default matters. |
EXCLUDED_FIELDS_PATH | required | ./config/excluded-fields.txt | Applied at collection so secrets are never stored rather than filtered later. |
The build, in order
Reading an account without being able to change it
A scan enumerates resources using credentials that cannot write.
Verify by attempting a write and expecting denial.
Files
src/credentials.tstests/readonly.test.tsAbsence must not look like emptiness.
Files
src/scan.tsEnumerating a large account will hit limits.
Files
src/scan.ts
done when · tick each as it passeswatch out- A scan that silently skips a region where permissions were missing produces a diagram with a whole part of the estate absent, and the person looking at it has no way to know. Record what could not be read and why, and mark the diagram partial rather than letting absence look like emptiness.
Relationships, and how sure you are
The graph distinguishes what you read from what you inferred.
The references that actually exist, not the ones that seem likely.
Files
src/topology.tsSo a reader can tell a fact from a guess.
Files
src/edges.tsA dashed line and a solid line are different claims.
Files
src/render.ts
done when · tick each as it passeswatch out- Inferring connections from naming conventions produces a diagram that looks complete and contains relationships that do not exist, which is worse than a sparse diagram because people make decisions from it. Record the evidence per edge, and draw inferred edges differently so a reader can weigh them.
Making four hundred resources legible
A real account produces a diagram someone can read.
Account, region, network. The nesting is the structure people think in.
Files
src/layout.tsTwenty identical instances is one shape and a number.
Files
src/collapse.tsFiltering hides things silently. Folding keeps the count visible.
Files
src/layout.ts
done when · tick each as it passeswatch out- Drawing every resource at once produces an unreadable mess at real scale, and the temptation is to filter down to a subset, which produces a diagram that omits something important without saying so. Collapse and nest rather than filtering, so nothing is hidden, only folded, and the counts remain visible.
Saying how old the picture is
Nobody mistakes a snapshot for the current state.
On the image, not in a menu. Exports get separated from their context.
Files
src/render.tsWhat appeared, disappeared and changed.
Files
src/drift.tsA permissions gap is not a deletion.
Files
src/drift.ts
done when · tick each as it passeswatch out- A diagram with no timestamp is used for six months as though it were current, and infrastructure changes weekly, so decisions get made from a picture of an estate that no longer exists. Put the observation time on the diagram itself, not in a menu, and visibly degrade it past a threshold.
Exporting a map of your estate carefullyproduct builder
A shared diagram does not hand an attacker your topology.
Not at export. Collected means stored, backed up and in crash reports.
Files
src/collect.tstests/no-secrets.test.tsA diagram is a map for whoever is attacking you.
Files
src/export.tsPossible, deliberate, and logged.
Files
src/export.ts
done when · tick each as it passeswatch out- Filtering secrets at export means they were collected and stored, so they are in the local database, in backups and in any crash report, and a single unredacted export path exposes them. Exclude the fields at collection, so there is nothing to filter.
That is the whole plan for Cloudcraft. What it deliberately does not cover is below · check the gaps before you call it a replacement.
- Cost estimation.
- Multi-cloud coverage.
- Any write access, including tagging.
- Security assessment.
- presentation and enterprise controls
- multiplayer cursors and comments
- large template libraries
- high-fidelity import and export
- Scheduled scans with drift alerting, which is where this becomes operationally useful
- Diagram diffs between two scans as a visual, since the list form is hard to read
- Annotation layers that survive rescanning, so human context is not lost each time
Need the files? The project pack on the verdict page hands your agent the whole brief · more diagrams.