Uptime, latency and cloud spend, watched for you.

What the two AWS scans actually catch: sample security & waste findings

These are the exact kinds of findings the NimbusWatch AWS security scan and cost-waste detection report: public storage, open firewall ports, logins without a second factor, and the unused or oversized AWS resources quietly billing you every month, each with the one fix.

This page is sample data. It is a realistic example of what a scan can find, not a scan of your AWS account. Nothing here has looked at your account, and the bucket names, server IDs and resource IDs are made up. The dollar figures are illustrative examples computed from AWS list prices, not figures from your account.

AWS security scan

Read-only checks, plain-English findings, ordered by how much damage they allow. Five of the fourteen checks it runs:

  • Public storageUrgentSample

    Anyone on the internet can read the files in “customer-data-backup”

    Your S3 bucket “customer-data-backup” is open to the public: its bucket policy opens it up.

    Anybody who knows or guesses the bucket's name can download everything in it with no AWS account needed, no login, and nothing in your bill or your logs that would look unusual. If you have ever put a database export, customer uploads, a .env file or an API key in here, treat all of it as public now and rotate anything secret.

    Some buckets are meant to be public: the images and CSS for a website, for example. If that is what this one is, nothing is wrong and you can ignore this. If it is not, this is the first thing to fix on this page.

    The fix: In the AWS console open S3 → “customer-data-backup” → Permissions and turn on “Block all public access”, then save. That switch overrides both the policy and the ACL, so it closes the bucket whichever one opened it. If some of the files genuinely need to be public, leave Block Public Access on and serve those files through CloudFront instead of opening the whole bucket.

  • Open to the internetUrgentSample

    “web-prod-sg” accepts connections from anywhere on port 22 (SSH — remote login to the server)

    The firewall rule set “web-prod-sg” (sg-0a1b2c3d) in us-west-2 allows any address on the internet to connect on port 22 (SSH — remote login to the server).

    That is not just your traffic; it is every scanner on the internet, and they find a new server within minutes of it going up. Anything behind these ports is protected only by whatever password or key it has, with unlimited attempts to guess it.

    A security group is AWS's firewall: whatever it lets through reaches your server directly, whether or not your app is listening on that port today.

    The fix: In the AWS console open EC2 → Security Groups → sg-0a1b2c3d → Inbound rules → Edit. Change the source from “Anywhere (0.0.0.0/0)” to your own IP address (the console offers “My IP”), or to the security group of the machines that genuinely need to connect. Keep 0.0.0.0/0 only on the ports the public is meant to use: 80 and 443 for a website. For a server you administer yourself, AWS Systems Manager Session Manager gives you a shell with no open port at all.

  • Logins without a second factorUrgentSample

    “deploy” can sign in with only a password

    The AWS user “deploy” can sign in to the AWS console with a password, but has no multi-factor authentication (MFA) device.

    That means one password is the only thing between a stranger and your whole AWS account. Passwords leak: reused on another site, typed into a fake login page, or pulled off a laptop. MFA is the single change that stops a leaked password from being enough, and it takes about two minutes to set up with a phone app.

    The fix: In the AWS console open IAM → Users → deploy → Security credentials → “Assign MFA device”, and use an authenticator app on your phone (Authy, 1Password, Google Authenticator, any of them). If this user is a machine rather than a person and only ever uses its keys, the better fix is to delete the console password so it cannot be signed into at all.

  • Root account keysUrgentSample

    Your root account has permanent access keys

    The root user of AWS account 123456789012 has 2 access keys that never expire.

    Root is the one login that can do absolutely anything (close the account, delete every backup, change the billing details). Nothing you set up inside this account can restrict root later — and if this account sits inside an AWS Organization, only a policy set at the organization level can. A root access key turns that unlimited power into a short string of text that can sit in a config file, a git history, or a CI log, and anyone who copies it owns your account outright.

    AWS's own guidance is blunt about this one: the root account should have no access keys at all, ever. Day-to-day work belongs to an IAM user or role, which you can limit and switch off.

    The fix: Sign in as root, open “My Security Credentials” → Access keys, and check the “Last used” column for each key. If a key has not been used, delete it now. If something is using one, create an IAM user with only the permissions that thing needs, move it onto the new key, then come back and delete the root key. While you are there, turn on MFA for the root login if it is not on already.

  • Unencrypted disksWorth fixingSample

    Disk vol-0c4d5e6f is stored without encryption

    The 200 GB EBS disk vol-0c4d5e6f in us-west-2 is attached to server i-0a1b2c3d4e5f60718, and its contents are stored unencrypted.

    This is a quieter problem than an open port. Nobody can read this disk over the internet. It matters when something else goes wrong: a snapshot shared or made public by mistake, a disk attached to the wrong instance, or an auditor, customer or insurer asking whether data at rest is encrypted. Encryption itself is free on AWS and costs no measurable performance — only a customer-managed KMS key (its monthly key charge and its API calls) adds cost, and the default AWS-managed key does not — so there is no real reason to leave it off.

    AWS cannot encrypt a disk in place, so this is a swap rather than a switch. Plan a few minutes of downtime for the server that uses it.

    The fix: In the AWS console open EC2 → Volumes → vol-0c4d5e6f → Actions → “Create snapshot”. Then open the new snapshot → Actions → “Copy snapshot” and tick “Encrypt this snapshot”. Create a volume from the encrypted copy, stop the server, detach the old disk, attach the new one, and start the server again. Finally turn on EC2 → “EBS encryption by default” for the region so every disk you create from now on is encrypted without you thinking about it.

AWS cost-waste detection

Read-only scans of the resources that bill 24/7 whether or not they do anything, each with the one fix and, where AWS reports the data needed to price it, an estimated monthly saving. Some checks are advisory and carry no figure rather than a made-up one. A sample of the checks it runs:

  • Silent NAT gatewaysWorth fixing$32.85/mo est.Sample

    NAT gateway nat-0a1b2c3d has carried no traffic for 14 days

    The NAT gateway in us-west-2 has not moved a single byte in the last 14 days, and it is billed at $0.045/hour (us-east-1 list price; about $32.85/month) whether or not anything uses it. A NAT gateway is the piece that lets servers in a private subnet reach the internet; if no server needs that any more, it is a monthly charge on the bill for zero work.

    The fix: First confirm nothing uses it: in the EC2 console open NAT Gateways → nat-0a1b2c3d and check its “Route table associations”. Then in VPC → Route Tables remove the 0.0.0.0/0 route (the “any address” catch-all) that points at it. Once no route references it, NAT Gateways → Actions → “Delete NAT gateway”.

  • Idle serversWorth fixing$30.37/mo est.Sample

    Server i-0c1d2e3f has been idle for 14 days

    The t3.medium server in us-east-1 has averaged under 1% CPU over the last 14 days, effectively doing nothing. It bills at AWS's on-demand list price of 0.0416/hour for a t3.medium (about $30.37/month). Stopping a server ends its compute billing, but any EBS volumes left attached to it keep billing at full size while it is stopped.

    The fix: In EC2 → Instances → i-0c1d2e3f → Instance state → “Stop instance” (or “Terminate” if the job is finished).

  • Unused IP addressesInfo$3.65/mo est.Sample

    Elastic IP 203.0.113.14 is not attached to anything

    The address has no server attached and bills at AWS's public IPv4 price of $0.005/hour (us-east-1 list price; about $3.65/month). AWS bills every public IPv4 address at that rate, whether it is attached to a running instance or not, so this one is pure overhead: an address in use is not a free one.

    The fix: In EC2 → Elastic IPs → select 203.0.113.14 → Actions → “Release Elastic IP address”. Releasing it is what stops the charge — attaching it to a server does not.

  • Orphaned disksInfo$8.00/mo est.Sample

    Disk vol-0e8f9a0b is not attached to any server

    The gp3 disk vol-0e8f9a0b in us-east-1 is 100 GB and sitting “available”, not attached to any server. It still bills $0.08 per GB-month (gp3 at us-east-1 list price), which works out to roughly $8.00/month for doing nothing.

    The fix: Snapshot it first if it holds data you want, then delete the volume.

  • Oversized serversWorth fixing$70.08/mo est.Sample

    Server i-0f1a2b3c barely uses its m5.xlarge size

    It peaked at 18% CPU over 14 days, a small fraction of its capacity. A m5.large ($0.096/hour) would cover that peak with room to spare and save about $70.08/month at on-demand list prices. This is a suggestion, not a verdict: the smaller size has less memory, so only resize if the server's memory use fits.

    The fix: During a maintenance window: EC2 → Instances → i-0f1a2b3c → Actions → “Instance settings” → “Change instance type” → m5.large, then start it again.

  • Over-provisioned functionsInfo$9.20/mo est.Sample

    Function "resize-image" is set to more memory than it uses

    Configured for 1024 MB but peaked at 240 MB over 14 days. Dropping it to 512 MB would save roughly $9.20/month at Lambda's on-demand price of $0.0000166667 per GB-second (us-east-1 list price). One caution: Lambda gives a function CPU in proportion to its memory, so less memory also means less CPU — watch the duration after the change.

    The fix: In Lambda → Functions → "resize-image" → General configuration → set Memory to 512 MB and save.

  • Over-provisioned tablesWorth fixing$22.02/mo est.Sample

    Table "sessions" is provisioned far above what it consumes

    Provisioned for 50 reads and 50 writes but consuming an average of 4 reads and 6 writes. Dropping to 8 reads and 12 writes would keep the same traffic and save about $22.02/month at DynamoDB's provisioned list prices (us-east-1: $0.00013 per read-capacity-unit-hour, $0.00065 per write-capacity-unit-hour).

    The fix: In DynamoDB → Tables → "sessions" → Read/write capacity → set 8 read and 12 write capacity units.

  • Over-provisioned disksWorth fixing$30.00/mo est.Sample

    Disk vol-0a2b3c4d is provisioned at 300 GB but has been idle for 14 days

    The 300 GB gp2 disk is attached to a running server but sat idle 99.7% of the last two weeks and moved almost no data. AWS bills it at its full provisioned size — $0.10 per GB-month (gp2 at us-east-1 list price) — which works out to about $30.00/month whether the disk is touched or not.

    The fix: EBS volumes cannot be shrunk in place: snapshot it, restore to a smaller volume, attach that in its place, then delete the old disk once the data is verified.

  • Logs kept foreverInfoNo dollar figure: AWS didn’t report stored bytesSample

    Log group "/aws/lambda/resize-image" never deletes its logs

    No retention is set, so logs are kept forever and never deleted. AWS did not report how much data this group stores, so there is no dollar figure on this one: the amount depends on accumulated logs.

    The fix: Decide how long you genuinely need these logs, then set a retention (or export to S3 first if you must keep them long-term).

Across just these samples, the cost-waste findings add up to roughly $206.17/month in potential savings. Every dollar figure is an estimate (AWS bills in fractions of a month and prices change), but it is accurate enough to tell you what a resource is costing you. That total counts only the findings with a figure. The advisory ones — like log retention — are listed without a made-up number when AWS does not report the data needed to price them.

See what your account is hiding

These real scans run about once a day, and you can run one yourself any time. A run you start yourself counts as that account's scan, so the next scheduled pass can find nothing due. They are read-only, opt-in, and every finding comes with the one thing to do about it: the security scan on the Starter plan ($9/month) and above, and cost-waste detection on the Pro plan ($29/month) and above.

Free and Starter include uptime, latency and (on Starter) AWS spend tracking. Of the scans shown above, the security scan is included from Starter and cost-waste detection from Pro.

Wondering what connecting costs you in effort? The read-only AWS setup takes about 15 minutes.