Share an Amazon QuickSight dashboard without an AWS account
QuickSight's sharing model assumes the reader is an AWS identity. To show somebody a dashboard you provision them in IAM Identity Center or QuickSight's directory, attach the right permissions, and pay for a reader — all of it durable infrastructure, for a person who wants one number every Monday.
The escape hatches are real but heavy. Anonymous embedding
(GenerateEmbedUrlForAnonymousUser) is genuinely the right tool if you are
building embedded analytics into a product. As a way to email the ops lead this
week's figures, it means running a web application whose only job is minting
short-lived URLs.
So most teams screenshot the dashboard.
Publish a snapshot
QuickSight has a first-party export API:
aws quicksight start-dashboard-snapshot-job \
--aws-account-id "$ACCOUNT_ID" \
--dashboard-id weekly-ops \
--snapshot-job-id "run-$(date +%s)" \
--user-configuration '{"AnonymousUsers":[{"RowLevelPermissionTags":[]}]}' \
--snapshot-configuration '{
"FileGroups":[{"Files":[{"SheetSelections":[{"SheetId":"sheet1","SelectionScope":"ALL_VISUALS"}],
"FormatType":"CSV"}]}],
"DestinationConfiguration":{"S3Destinations":[{"BucketConfiguration":{
"BucketName":"'"$BUCKET"'","BucketPrefix":"snapshots/","BucketRegion":"'"$REGION"'"}}]}}'
Poll describe-dashboard-snapshot-job-result until it completes, pull the CSV
from S3, render it, and publish:
aws s3 cp "s3://$BUCKET/snapshots/weekly-ops.csv" - \
| python3 render_table.py > report.html
curl -fsS -X POST "https://commareports.com/api/v1/reports" \
-H "Authorization: Bearer $COMMA_API_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --rawfile html report.html \
--arg t "Weekly ops — $(date +%F)" '{title: $t, html: $html}')"
FormatType also accepts PDF, which is right when the visual layout is the
point. CSV is right when the reader will want to check or reuse the numbers —
and you can attach it as an asset alongside a rendered table so they get both.
Always put the snapshot date in the title. An undated dashboard export is how a stale figure ends up in a decision.
Keep it current
# EventBridge → Lambda, or any scheduled CI job
# …run the snapshot job, fetch the CSV, render report.html…
curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
-H "Authorization: Bearer $COMMA_API_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --rawfile html report.html \
--arg t "Weekly ops — $(date +%F)" '{title: $t, html: $html}')"
One report id, PATCHed weekly. The link you sent in March still shows current numbers in November, and the revision list is a history QuickSight itself does not keep — the dashboard shows today's data and nothing else.
Access, and what you are not granting
Reports are private by default:
- Domain-gated — anyone at
partner.com. The usual right answer for an external stakeholder: no AWS identity, no seat, revoked when they leave. - Named reviewers — for a narrow, sensitive distribution.
- Team — for internal readers who are not QuickSight users.
See the sharing model.
The important property: a snapshot grants no access to the underlying dataset, the SPICE capacity, or the data source. The reader gets results. Adding a QuickSight reader grants access to a live query surface, which is a much larger thing to hand out.
What review adds
- Anchored threads on a figure, so "does this include the EU region?" is answered on the number — see commenting on HTML.
- Revisions, so a restated number has a visible history.
- No per-reader charge, and no identity to deprovision later.
Limits
- Entry HTML: 5 MB. Assets: 25 MB per file, 250 MB and 500 files total.
- 60 requests/minute per token.
Try it
Comma is free — unlimited reports, unlimited commenters, unlimited revision history.