Kiro User Activity Dashboard
Introduction
The Kiro User Activity Dashboard provides enterprise visibility into Kiro
Key capabilities include:
-
Credit consumption monitoring with tier-based utilization thresholds
-
Per-user and per-account usage breakdown across all Kiro-enabled regions
-
Model-level message tracking (Claude Opus, Sonnet, Haiku, and other models)
-
Subscription tier right-sizing recommendations (upgrade, downgrade, right-sized)
-
Overage detection and at-risk user identification (at or above 75% plan utilization)
-
New user adoption tracking
The following screenshot shows the Executive Summary tab of the Kiro User Activity Dashboard:
The dashboard has five tabs:
-
Executive Summary:
-
Active Users, Total Messages, Credits Used, Overage Credits, New Users KPIs
-
Daily Active Users by Client Type
-
Credits by Subscription Tier
-
Messages by Model
-
Daily Credits Consumed by Tier
-
-
User Engagement:
-
Top 50 Users by Message Count colored by Model
-
Monthly User Summary pivot table with tier recommendations
-
Utilization percentage and credits per message metrics
-
-
Credit & Overage Tracking:
-
Daily Credits Used vs Overage
-
Users at Risk KPI (at or above 75% plan utilization)
-
Users in Overage KPI
-
Monthly Credits and Overage pivot table
-
-
Model & Client Breakdown:
-
Daily Messages by Model
-
Monthly Model and Client pivot table with user counts and efficiency metrics
-
-
About:
-
Dashboard version and release information
-
Legal notice
-
All tabs include shared filter controls for lookback period, AWS Account, User, Model, and Client Type.
Architecture
The Kiro User Activity module uses a pull-based architecture. A central AWS Lambda function in the Data Collection account reads CSV reports from customer Kiro source buckets on a daily schedule. Customers only need to apply a bucket policy, because no AWS CloudFormation stack is deployed in their accounts.
The following diagram shows the pull-based data collection flow:
-
The Kiro service writes daily CSV user activity reports at 2 AM UTC to each customer’s designated S3 bucket, under the path
kiro/AWSLogs/<account-id>/KiroLogs/user_report/<region>/<year>/<month>/<day>/. -
A Lambda function (scheduled at 3 AM UTC) reconciles each source bucket against the central Data Collection bucket. It lists every Kiro report in the source and every file already imported to the destination. It then pulls only the reports that are missing. For each report it pivots the model-specific columns into normalized rows. It then writes Hive-partitioned output to the central Data Collection bucket, keyed by source account and region:
kiro-user-activity/account_id=<id>/region=<region>/year=<year>/month=<month>/day=<day>/. The destination is the source of truth for what has already been collected. This gives the reconcile both checkpointing (transient failures self-heal on the next run) and backfill (any missing history is filled). It also scales to accounts that manage many source buckets. -
An explicit AWS Glue table partitioned by
account_id,region,year,month, anddaymakes the source account and region first-class query dimensions. This partitioning also prevents cross-account filename collisions. The Lambda registers each partition it writes through the AWS Glue API. Amazon Athena can then query the data without an AWS Glue crawler orMSCK REPAIR TABLE, and newly onboarded accounts and regions become queryable automatically. -
Amazon Quick Suite ingests data from Amazon Athena (through a bounded two-year view over the table) into SPICE (Super-fast, Parallel, In-memory Calculation Engine) and applies calculated fields for utilization metrics, tier recommendations, and overage tracking.
Prerequisites
-
Deploy one or more of the foundational dashboards: CUDOS, Cost Intelligence, or KPI Dashboard. This deployment enables the required Amazon Athena and Amazon Quick Suite resources for this dashboard.
-
Deploy or Update the Data Collection Stack with the Kiro User Activity Data Collection Module enabled (see Step 1).
-
Kiro user activity reporting enabled — Each source account must have Kiro user activity reporting enabled and writing CSV reports to an Amazon S3 bucket. This is configured in each account through the Kiro console.
-
Amazon Quick Suite Enterprise Edition — Required for SPICE datasets and calculated fields.
Note
Unlike most Data Collection modules, the Kiro User Activity module is pull-based and does not require the Management Account Read Permissions stack or a Linked Account StackSet. The central collection Lambda reads directly from the source buckets you specify, and each source account grants access with a bucket policy (see Step 2).
Important
This module currently supports source buckets that are unencrypted or encrypted with Amazon S3-managed keys (SSE-S3). Source buckets encrypted with an AWS KMS key (SSE-KMS) are not supported: the bucket policy in Step 2 grants Amazon S3 read access only, so the collection Lambda cannot decrypt objects protected by a customer-managed KMS key and collection fails.
If your Kiro source buckets use SSE-KMS, either change the bucket’s default encryption to SSE-S3 (or ensure the objects written under kiro/* use SSE-S3), or track KMS support through Feedback and Support.
Deployment
Deployment consists of three steps: enabling the data collection module in the Data Collection Stack, granting read access from each source account, and deploying the Quick Suite dashboard.
Step 1: Enable the Kiro User Activity Module in the Data Collection Stack
The Kiro User Activity module is part of the Data Collection Stack. Enable it when you deploy or update the stack in your Data Collection account.
-
Sign in to your Data Collection account and open the AWS CloudFormation
console. -
Deploy the Data Collection Stack (first-time setup) or Update your existing Data Collection Stack.
-
In the Parameters section, set the following values for the Kiro User Activity Module Configuration:
Parameter Description Example Include Kiro User Activity Data Collection Module
Set to
yesto enable the moduleyesKiro Source Bucket Names (comma-separated)
Comma-separated list of S3 bucket names where Kiro writes user activity reports
my-kiro-bucket-111111111111,my-kiro-bucket-222222222222 -
Complete the stack deployment or update. After the stack reaches
CREATE_COMPLETEorUPDATE_COMPLETE, AWS CloudFormation creates the Kiro collection Lambda function, Amazon EventBridge Scheduler schedule, and AWS Glue table. -
In the AWS CloudFormation Outputs of the nested Kiro module stack, note the LambdaRoleArn value. You use this ARN in each source account’s bucket policy in Step 2.
Note
The collection Lambda runs daily at 3 AM UTC, after Kiro generates its reports at 2 AM UTC. On each run it reconciles every source bucket against what has already been imported and pulls any missing reports, regardless of date. This means the first run backfills all available history, and subsequent runs copy only new or previously-missed reports.
Step 2: Grant Read Access
Apply the following in each source account that produces Kiro user activity reports. Each account must apply a bucket policy granting read access to the collection Lambda role from Step 1. No CloudFormation stack is deployed in the source accounts — a bucket policy is all that is required.
Add the following two statements to the S3 bucket policy on each Kiro source bucket. Access is scoped to the kiro/* prefix so the collection Lambda can read only the Kiro user activity reports, not the rest of the bucket:
{ "Sid": "AllowCIDKiroDataCollectionRead", "Effect": "Allow", "Principal": { "AWS": "<LambdaRoleArn from Step 1 Outputs>" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::<kiro-source-bucket-name>/kiro/*" }, { "Sid": "AllowCIDKiroDataCollectionList", "Effect": "Allow", "Principal": { "AWS": "<LambdaRoleArn from Step 1 Outputs>" }, "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::<kiro-source-bucket-name>", "Condition": { "StringLike": { "s3:prefix": "kiro/*" } } }
Tip
The exact bucket policy statements, pre-populated with your Lambda role ARN, are also provided in the BucketPolicyExample CloudFormation stack output.
Important
When you specify a role ARN as a bucket policy Principal, Amazon S3 stores it internally as the role’s unique ID, not the ARN string. If you tear down and later re-enable the module (or otherwise delete and recreate the Lambda role), the new role has a different unique ID even though the ARN is unchanged. The existing bucket policy then still points at the deleted role, so the Lambda can no longer list or read the source bucket. Collection fails quietly — the run returns total_files_copied: 0, and any per-bucket access failures appear in the errors array of the Lambda response.
If you re-deploy the module, re-apply the bucket policy in each source account so it re-resolves to the new role. Use the current BucketPolicyExample stack output as the source of truth.
Step 3: Test the Lambda Collector
Invoke the Lambda manually to verify data flows correctly:
aws lambda invoke \ --region <region> \ --function-name CID-DC-kiro-user-activity-Lambda \ /tmp/kiro-output.json && cat /tmp/kiro-output.json
Expected response (a successful run returns statusCode: 200; total_files_copied, total_rows_written, and partitions_registered reflect how many reports were missing and therefore imported on this run — a run where everything is already collected returns zeros, which is normal):
{ "statusCode": 200, "total_files_copied": 3, "total_rows_written": 45, "partitions_registered": 3, "errors": [] }
Note
The collector imports only reports that are not already present in the destination. On a first run it backfills everything available; on later runs total_files_copied is often 0 because there is nothing new to copy — this is expected and not an error.
If a first run (or a run against a brand-new source bucket) reports total_files_copied: 0, verify the following:
-
The bucket policy in the source account is applied, and — if you have re-deployed the module — that it points at the current Lambda role (see the IMPORTANT note in Step 2).
-
The Kiro Source Bucket Names parameter is correct.
-
The Kiro service has written reports to the source bucket under the expected
kiro/AWSLogs/<account-id>/KiroLogs/user_report/…path.
The collector reads the source account, region, and date from the S3 object path (kiro/AWSLogs/<account-id>/KiroLogs/user_report/<region>/<year>/<month>/<day>/…) rather than from columns inside the CSV. Reports that do not match this path layout (for example the legacy by_user_analytic report) are skipped.
Step 4: Verify Data in Athena
Run a test query to confirm data is accessible:
SELECT * FROM optimization_data.kiro_user_activity LIMIT 10;
Step 5: Deploy the Quick Suite Dashboard
Example
Step 6: Trigger Initial SPICE Refresh
After deploying the dashboard, trigger a SPICE ingestion to load data:
cid-cmd refresh --dashboard-id kiro-user-activity
Adding New Source Accounts
To start collecting data from additional Kiro-enabled accounts:
-
Update the Data Collection Stack, adding the new bucket name(s) to the Kiro Source Bucket Names parameter.
-
Apply the bucket policy from Step 2: Grant Read Access in the new source account.
-
Invoke the Lambda manually, as described in Step 3: Test the Lambda Collector, to verify the new source is discovered.
You do not need to redeploy the dashboard. New accounts automatically appear as filter values after the next SPICE refresh.
Usage Guide
Example
Calculated Fields Reference
The following calculated fields are created in the Quick Suite dataset:
| Field | Logic | Purpose |
|---|---|---|
|
|
|
Date type for time-series |
|
|
Email if available, cleaned userid otherwise |
Human-readable display |
|
|
Pro=1000, ProPlus=2000, ProMax=5000, Power=10000, Free=50 |
Monthly plan allocation |
|
|
|
Per-day utilization (not used directly by the pivots; see |
|
|
1 if overage_credits > 0 |
Overage counter |
|
|
|
Efficiency metric |
|
|
1 if new_user = true |
Adoption counter |
|
|
Cumulative monthly credits per user / plan_credits (analysis-level, aggregated over the calendar month) |
Monthly utilization — the basis for utilization %, at-risk, and tier recommendations |
|
|
Sum of a user’s overage credits over the calendar month (analysis-level) |
Monthly overage total |
|
|
1 if monthly utilization >= 75% |
Risk threshold |
|
|
Any monthly overage → Upgrade Candidate (or Review Overage Settings if already on Power, the top tier); else monthly utilization <30% on a tier above Pro → Downgrade Candidate; else Right-Sized |
Tier optimization (evaluated on monthly, not per-day, usage) |
Note
Utilization, at-risk, and tier-recommendation logic all evaluate usage over the calendar month, because Kiro plan credits are allocated and reset per calendar month. Set the dashboard’s lookback period to a full calendar month when reviewing these metrics.
Update
When a new version of the dashboard template is released, update your dashboard by running the following command:
cid-cmd update --dashboard-id kiro-user-activity
Teardown
To remove the Kiro User Activity module:
-
Delete the Quick Suite dashboard and dataset via the Quick Suite console or
cid-cmd delete --dashboard-id kiro-user-activity. -
Update the Data Collection Stack and set Include Kiro User Activity Data Collection Module back to
no. This removes the collection Lambda, EventBridge Scheduler schedule, and Glue table. -
(Optional) Remove the bucket policy statements from source accounts.
-
(Optional) Delete collected data from
s3://<dest-bucket>/kiro-user-activity/.Note
If you migrated from an earlier, replication-based version of this module, the destination bucket might also contain a legacy
s3://<dest-bucket>/kiro/prefix (the raw replication landing zone) and an AWS Glue crawler. These are not used by the current pull-based architecture. After confirming no Glue table still references thekiro/prefix, you can delete that data and remove the crawler.
Authors
-
Darius Seroka, Senior Technical Account Manager
Contributors
-
Yuriy Prykhodko, Principal Technical Account Manager
-
Eric Christensen, Senior Technical Account Manager
Feedback & Support
For feedback and support, see the Feedback and Support guide.
Note
These dashboards and their content: (a) are for informational purposes only, (b) represent current AWS product offerings and practices, which are subject to change without notice, and (c) does not create any commitments or assurances from AWS and its affiliates, suppliers or licensors. AWS content, products or services are provided "as is" without warranties, representations, or conditions of any kind, whether express or implied. The responsibilities and liabilities of AWS to its customers are controlled by AWS agreements, and this document is not part of, nor does it modify, any agreement between AWS and its customers.