Codeaza Technologies · Infrastructure

Rulebook — AWS Security & Infrastructure Audit

Read-only security audit, live remediation, cost analysis, and a prod-bucket structure review for the Rulebook production account.

Account058264491029
Regionus-east-1
Date30 Jun 2026
Prepared forLead Engineer
● Executive Summary

Where the account stands

A read-only audit surfaced several critical exposures. Most were remediated live; a few items are scoped for follow-up by the engineering team.

B−
Posture

Materially hardened, with clear follow-ups

The dangerous, internet-facing exposures (world-writable buckets, a public credential leak, no audit logging, no MFA) are closed. Human access is now centralised in IAM Identity Center (SSO) with MFA enforced — only one break-glass IAM admin remains. What's left is disciplined cleanup: a scoped service role for the app, a public RDS lockdown, and a prod-bucket restructure to fix the app's own data hygiene.

🔐
Access
SSO + MFA
📜
Audit Logging
Enabled
🪣
Public Write
Removed
💾
Backups
30d + Lock
🗄️
RDS Exposure
Open
🔑
App Credentials
Action req.
● Security

Findings & actions taken

Severity-ranked. "Done" items were remediated live during the audit window.

#FindingSeverityActionStatus
1Public credential leak*.env files (EMAIL + PASSWORD) anonymously downloadable from the public prod bucketCRITICALExplicit public-read Deny on *.env; password rotation requiredFIXED
2World-writable prod bucketsPrincipal:"*" s3:* (read/write/delete)CRITICALReduced to s3:GetObject onlyDONE
3Wide-open security group — all ports 0–65535 to 0.0.0.0/0CRITICALConfirmed unattached → deletedDONE
4Prod RDS publicly accessible — Postgres reachable from the internetCRITICALNeeds DB connection source identified before SG lockdownPENDING
5No audit logging — zero CloudTrail anywhereHIGHMulti-region org-audit-trail + encrypted/versioned log bucket; log validation onDONE
6No MFA on any IAM userHIGHEnforceMFA attached to all users (deny-until-enrolled)DONE
7No password policyHIGH14-char min, complexity, 90-day rotation, no reuse of last 5DONE
8Over-privileged users (S3FullAccess etc.)MEDIUMDenyDestructiveActions on all non-admins; scoped down devops & dev usersDONE
9App uses human admin keys as its service identity (leaked in chat)MEDIUMScoped service role planned; rotate keysPENDING
MFA enforcement is real. The EnforceMFA policy denies all actions without an MFA session — confirmed by it (correctly) blocking even an admin access-key call during the audit.
● Incident

Public credential leak — prod bucket

The single most urgent finding. Closed during the audit; one follow-up remains on the team.

What happened monthly_mail.env and weekly_mail.env sat at the root of stock-rulebook-prod, whose bucket policy grants Principal:"*" s3:GetObject on /*. Both files (containing EMAIL + PASSWORD) were anonymously downloadable — verified HTTP 200 — and had been since 2024/2025.

✅ Fixed

  • Added explicit Deny s3:GetObject on *.env for all principals except the account.
  • Verified: anonymous → 403; application (in-account) → still reads normally.
  • CDN serving of all other objects unaffected.

⚠️ Still required (team)

  • Rotate the leaked email password — treat as compromised regardless of the lock.
  • Move config/secrets out of the public bucket → private config bucket or AWS Secrets Manager.
  • Audit access logs for prior downloads of these keys.
Lesson for the codebase: secrets must never be written to a CDN-backed public bucket. This is a symptom of the bucket-hygiene problem below, not a one-off.
● FinOps

Cost analysis

Pulled live from AWS Cost Explorer. ~50% of the bill is recoverable, with a zero-risk subset to start.

MonthTotal (incl. tax)Note
Mar 2026$324.54
Apr 2026$300.84
May 2026$317.63
Jun 2026$376.07Breached $350 budget · ~$313 ex-tax
Jul (forecast)~$326Cost Explorer projection

June by service

ServiceJun $Driver
EC2 – Compute$118.453 always-on instances, 0% commitment
ECS (Fargate)$89.84prod backend workload
RDS$36.38db.t3.small, ~4% CPU
VPC$30.196 public IPv4 + data
EC2 – Other$18.19EBS 158 GB + snapshots
ELB$15.811 ALB

Right-sizing opportunities (~$190–200/mo)

ActionSaved/moRisk
Compute Savings Plan (EC2 + Fargate)~$701-yr commit
FileZilla_server t3.large → t3.micro (0.2% CPU)~$55none
Core-PSR t4g.xlarge → t4g.large (verify 86% bursts)~$49low
Drop unused public IPv4 (of 6)~$11–18none
RDS Reserved Instance~$111-yr commit
Monitoring t4g.small → t4g.micro~$6none
Start here: the zero-risk subset (FileZilla + Monitoring downsize, unused EIPs, gp2→gp3) ≈ $76/mo with no commitment or downtime.
● Data Hygiene

Prod bucket structure — stock-rulebook-prod

The app uses one public bucket as a junk drawer. This is a code/convention issue, not just housekeeping — and it's what hid the credential leak.

🧩 Mixed concerns in one public bucket

  • Operational data (50+ fee_* exchange schedules) sits beside logs/, api-logs/, assets/, demo/, evals/, feedback-tasks/.
  • FTP_users/, Testing_FTP/, and a stock-rulebook-staging/ prefix — test/FTP/staging data living inside public prod.

🔁 Duplicate prefixes (naming bug)

  • Same exchange written two ways by different code paths:
  • nasdaq_gemx/ + nasdaqgemx/, nasdaq_ise/ + nasdaqise/, nasdaq_mrx/ + nasdaqmrx/, nasdaq_phlx/ + nasdaqphlx/
  • → split data, double storage, queries silently miss half.

🐞 Path bugs & junk

  • Keys with a literal leading / → wrong path concatenation on write.
  • Casing chaos: FTP_users/, Testing_FTP/ vs lowercase-snake elsewhere.
  • Loose root objects: V_1 (62 KB, unclear), the .env files.

🌐 Everything public-read

  • Fine for CDN-served assets; reckless for data + logs + config dumped alongside.
  • Root cause of the credential leak.

Recommended restructure (engineering project)

  1. Done: block public read on *.env + rotate the leaked password.
  2. Split into purpose buckets: …-data (private), …-assets (only this is public, via CloudFront OAC), …-logs (private + lifecycle expiry). Evict test/demo/FTP/staging from prod.
  3. Standardize the key convention — one canonical exchange-name scheme — and migrate/backfill the duplicate prefixes.
  4. Fix the leading-slash path bug at the write site in the app.
  5. Make prod fully private behind CloudFront OAC once assets are separated.
● Next

Remediation roadmap

What's done, what's owned by the team, and the priority order.

PriorityItemOwnerStatus
NOWRotate the leaked email password (was world-readable)Lead EngTODO
DAY 1Scoped rulebook-annotation-svc role; swap app creds off admin keys; re-enable MFA on admin; rotate admin keysDevOpsTODO
DAY 1RDS public-access lockdown (identify connection source first)DevOpsTODO
WEEKProd bucket restructure + fix key convention & path bugApp teamTODO
WEEKCost: zero-risk right-sizing (~$76/mo), then Savings Plan + RDS RIDevOpsTODO
DONEIAM Identity Center (SSO) migration — Developer/DevOps permission sets, 4 users assigned, MFA-always-required; all redundant IAM users deleted (only muhamdasim break-glass admin remains)
DONERDS 30-day backups · S3 lifecycle + Object Lock on backups · CloudTrail · public-write removal · .env leak block · Developer read access broadened
Longer term: ✅ humans migrated to IAM Identity Center (SSO). Next — move CI to GitHub OIDC and the app to an ECS task role to eliminate the last long-lived credentials.
Codeaza Technologies · Rulebook AWS Audit · Account 058264491029 · Generated 30 Jun 2026 · Confidential — internal