|
| 1 | +# My AWS Dashboards |
| 2 | + |
| 3 | +> A browser-based AWS cost and billing monitor with interactive charts, service breakdowns, and exportable reports — built as part of [vibe.j2team.org](https://vibe.j2team.org). |
| 4 | +
|
| 5 | + |
| 6 | + |
| 7 | +## Overview |
| 8 | + |
| 9 | +**My AWS Dashboards** is a self-contained, client-side tool for visualizing AWS account costs and billing data. It ships with a full-featured demo mode using realistic simulated data so you can explore the dashboard immediately — no AWS account required. |
| 10 | + |
| 11 | +When connected to a real AWS account, the app authenticates through **Amazon Cognito Identity Pools**, which issues short-lived STS credentials. No long-lived IAM access keys are ever entered or stored. |
| 12 | + |
| 13 | +> [!IMPORTANT] |
| 14 | +> AWS Cost Explorer does not support CORS for direct browser requests. When connected via Cognito, the app will attempt a live connection and gracefully fall back to demo mode if CORS blocks the request. See [Real AWS Data](#real-aws-data) for workarounds. |
| 15 | +
|
| 16 | +## Features |
| 17 | + |
| 18 | +- **Cost Explorer Dashboard** — visualize spending across all AWS services in a selected date range |
| 19 | +- **4 Chart Types** — grouped bar, stacked bar, line chart, and donut chart |
| 20 | +- **Date Range Filter** — pick any custom date range with daily or monthly granularity |
| 21 | +- **Service Filter** — show or hide individual AWS services from the chart |
| 22 | +- **Summary Cards** — total cost, top service, average per period, cost trend vs. previous period |
| 23 | +- **Sortable Breakdown Table** — sort services by name, cost, or percentage share |
| 24 | +- **Export Reports** — download the current dashboard data as **CSV** or **XLSX** |
| 25 | +- **Demo Mode** — instantly explore with 6 months of realistic simulated AWS data |
| 26 | +- **Cognito Authentication** — zero long-lived keys; temporary STS credentials only |
| 27 | +- **5-Minute Auto-Logout** — session expires automatically; countdown shown in the header |
| 28 | + |
| 29 | +## Authentication |
| 30 | + |
| 31 | +### Security Model |
| 32 | + |
| 33 | +The app follows AWS best practices for browser-based credential management: |
| 34 | + |
| 35 | +| Old approach (removed) | New approach | |
| 36 | +|---|---| |
| 37 | +| Long-lived IAM Access Key + Secret stored in `localStorage` | Temporary STS credentials from Cognito — **in memory only** | |
| 38 | +| Credentials persist indefinitely across sessions | Session expires after **5 minutes**, then auto-logout | |
| 39 | +| Secret key visible in browser storage | No secrets ever touch storage | |
| 40 | + |
| 41 | +### How It Works |
| 42 | + |
| 43 | +1. User provides their **Cognito Identity Pool ID** (a non-secret public identifier). |
| 44 | +2. The app calls the **Cognito Identity API** (`GetId` → `GetCredentialsForIdentity`) to obtain temporary STS credentials. |
| 45 | +3. Credentials are held **in memory only** — never written to `localStorage`, `sessionStorage`, or any cache. |
| 46 | +4. A **5-minute countdown timer** is displayed in the header. When it reaches zero the session is cleared and the user is logged out automatically. |
| 47 | +5. On the next visit (or page refresh), the Identity Pool ID is pre-filled; one click reconnects and issues fresh credentials. |
| 48 | + |
| 49 | +### Setting Up a Cognito Identity Pool |
| 50 | + |
| 51 | +1. Open **AWS Console → Cognito → Identity Pools** and click *Create identity pool*. |
| 52 | +2. Enable **Guest access (unauthenticated identities)**. |
| 53 | +3. On the IAM role step, attach a role with the minimum policy: |
| 54 | + |
| 55 | +```json |
| 56 | +{ |
| 57 | + "Version": "2012-10-17", |
| 58 | + "Statement": [ |
| 59 | + { |
| 60 | + "Effect": "Allow", |
| 61 | + "Action": ["ce:GetCostAndUsage"], |
| 62 | + "Resource": "*" |
| 63 | + } |
| 64 | + ] |
| 65 | +} |
| 66 | +``` |
| 67 | + |
| 68 | +4. Copy the **Identity Pool ID** (format: `us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`). |
| 69 | +5. Paste it into the app and click **Connect via Cognito**. |
| 70 | + |
| 71 | +> [!TIP] |
| 72 | +> The Identity Pool ID is a public identifier — it is safe to save in localStorage (which the app does for reconnect UX). Only the temporary STS credentials are sensitive, and those are never persisted. |
| 73 | +
|
| 74 | +## Architecture |
| 75 | + |
| 76 | +``` |
| 77 | +src/views/my-aws-dashboard/ |
| 78 | +├── index.vue # Page entry — orchestrates auth vs. dashboard state |
| 79 | +├── meta.ts # Page metadata for the launcher |
| 80 | +├── types.ts # Shared TypeScript interfaces (CognitoConfig, CognitoSession, …) |
| 81 | +├── components/ |
| 82 | +│ ├── AwsAuth.vue # Cognito Identity Pool credential form |
| 83 | +│ └── CostDashboard.vue # Full dashboard with charts, table, and export |
| 84 | +├── composables/ |
| 85 | +│ ├── useCognitoAuth.ts # Cognito auth flow, session timer, and auto-logout |
| 86 | +│ └── useAwsCost.ts # Data fetching — real or demo fallback |
| 87 | +└── utils/ |
| 88 | + ├── cognitoClient.ts # Cognito GetId + GetCredentialsForIdentity API calls |
| 89 | + ├── demoData.ts # Deterministic demo cost data generator |
| 90 | + ├── chartUtils.ts # Chart.js config builders for each chart type |
| 91 | + ├── exportUtils.ts # CSV and XLSX export logic |
| 92 | + └── sigv4.ts # AWS Signature Version 4 signing (Web Crypto API) |
| 93 | +``` |
| 94 | + |
| 95 | +## Getting Started |
| 96 | + |
| 97 | +This app is part of the vibe.j2team.org project. To run it locally: |
| 98 | + |
| 99 | +```sh |
| 100 | +pnpm install |
| 101 | +pnpm dev |
| 102 | +``` |
| 103 | + |
| 104 | +Visit `http://localhost:5173/my-aws-dashboard`. |
| 105 | + |
| 106 | +### Demo Mode |
| 107 | + |
| 108 | +On first visit the Cognito auth form is shown. Click **Try with Demo Data** to instantly load simulated data — no configuration needed. You can also click the **Demo** button in the page header at any time. |
| 109 | + |
| 110 | +### Real AWS Data |
| 111 | + |
| 112 | +To connect to your AWS account: |
| 113 | + |
| 114 | +1. [Set up a Cognito Identity Pool](#setting-up-a-cognito-identity-pool) as described above. |
| 115 | +2. Click **Connect AWS** in the page header (or use the auth form on first visit). |
| 116 | +3. Enter the **Identity Pool ID** and **Region**, then click **Connect via Cognito**. |
| 117 | + |
| 118 | +> [!WARNING] |
| 119 | +> Due to CORS restrictions on the AWS Cost Explorer API endpoint (`ce.us-east-1.amazonaws.com`), direct browser requests are blocked. The app will show an error and revert to demo data. |
| 120 | +
|
| 121 | +**Workarounds for real data:** |
| 122 | + |
| 123 | +- Use a browser extension that disables CORS (development only) |
| 124 | +- Set up a local CORS proxy and point requests through it |
| 125 | +- Run the equivalent AWS CLI command and paste the output: |
| 126 | + |
| 127 | +```sh |
| 128 | +aws ce get-cost-and-usage \ |
| 129 | + --time-period Start=2025-11-01,End=2026-04-30 \ |
| 130 | + --granularity MONTHLY \ |
| 131 | + --group-by Type=DIMENSION,Key=SERVICE \ |
| 132 | + --metrics BlendedCost |
| 133 | +``` |
| 134 | + |
| 135 | +## Security |
| 136 | + |
| 137 | +- **No long-lived keys** — the app never asks for or stores IAM Access Keys or Secret Access Keys. |
| 138 | +- **In-memory credentials only** — STS credentials from Cognito are held in a Vue reactive ref; they disappear on page refresh or tab close. |
| 139 | +- **5-minute session timeout** — auto-logout is enforced client-side via `setTimeout`; a countdown is visible in the header. |
| 140 | +- **Public config only in storage** — `localStorage` holds only the non-secret Identity Pool ID for reconnect UX. |
| 141 | +- **No third-party data transmission** — all API calls go directly to `*.amazonaws.com` and `cognito-identity.*.amazonaws.com`. |
| 142 | +- **Static deployment** — the app runs as a static site on Cloudflare Workers with no backend. |
| 143 | + |
| 144 | +## Tech Stack |
| 145 | + |
| 146 | +| Library | Purpose | |
| 147 | +|---------|---------| |
| 148 | +| Vue 3 + TypeScript | UI framework | |
| 149 | +| VueUse `useLocalStorage` | Non-secret config persistence (Identity Pool ID only) | |
| 150 | +| VueUse `useScriptTag` | Lazy-load Chart.js and SheetJS from CDN | |
| 151 | +| Amazon Cognito Identity | Federated identity and temporary STS credential issuance | |
| 152 | +| [Chart.js 4](https://www.chartjs.org/) | Interactive charts (loaded from CDN) | |
| 153 | +| [SheetJS (xlsx)](https://sheetjs.com/) | XLSX export (loaded from CDN on demand) | |
| 154 | +| Tailwind CSS v4 | Styling via project design system | |
| 155 | + |
| 156 | +## Author |
| 157 | + |
| 158 | +Built by **J2TEAM** as part of [vibe.j2team.org](https://vibe.j2team.org). |
0 commit comments