Embed Quick Sight visuals using Cognito user authentication

Learn how to embed individual Amazon Quick Sight visuals into a React application with per-user access control. This walkthrough uses Amazon Cognito authentication and a serverless AWS Lambda backend to generate scoped embed URLs, deployed with a single AWS CloudFormation stack.

Sep 3, 2026 - 18:00
 3
Embed Quick Sight visuals using Cognito user authentication

Embedding analytics into a React application introduces complexity when you need per-user authentication. Building the identity layer that bridges Amazon Cognito and Amazon Quick Sight so that each person sees only the data their role permits adds layers of complexity that most tutorials skip. With a dedicated identity layer, you can implement fine-grained access governance for every embedded visual.

Amazon Quick is the unified analytics service from AWS. It combines business intelligence, advanced analytics capabilities, and enterprise search into a single service. Amazon Quick Sight is the business intelligence engine within Amazon Quick that powers the embedded analytics experience in your application.

This post shows you how to embed individual Amazon Quick Sight visuals into React applications with registered user authentication through Amazon Cognito. Embedding at the visual level, rather than full dashboards, gives you granular control over layout and user experience. You integrate specific charts, graphs, and metrics directly into your application interface, reusing existing dashboard visuals without building standalone dashboards for each use case.

The solution is lightweight by design. The AWS Lambda function generates scoped embed URLs quickly, including first-time user provisioning. The solution can deploy rapidly using a single AWS CloudFormation stack. Each embed URL remains valid for an extended period, minimizing re-authentication friction during sessions. By the end of this post, you will have built the full pipeline from Cognito user creation through Lambda-based URL generation to a working React front end that renders individually embedded Quick Sight visuals with per-user access control.

Solution architecture

The solution follows a four-layer serverless architecture:

  1. Front-end layer consists of a React application served through Amazon CloudFront which serves the React application’s static files from an Amazon Simple Storage Service (Amazon S3) bucket. AWS WAF sits in front of CloudFront and filters malicious requests at the edge.
  2. Authentication layer uses Amazon Cognito User Pools to handle user sign-in and issue JSON Web Tokens (JWTs) that are validated at the API tier.
  3. Backend layer is an Amazon API Gateway endpoint protected by a Cognito Authorizer that routes authenticated requests to an AWS Lambda function. This function assumes a dedicated AWS Identity and Access Management (IAM) role and calls the Amazon Quick Sight GenerateEmbedUrlForRegisteredUser API to produce a time-scoped embed URL for the requested visual. Amazon CloudWatch captures logs and metrics from the Lambda function throughout this process.
  4. Analytics layer is Amazon Quick Sight itself, which renders the individual visual inside the React application through the Embedding SDK running entirely in the browser. The Quick Sight account must have the application’s CloudFront domain registered in the embedding allowlist. Without this entry, the browser blocks the embedded iframe because of cross-origin restrictions and the visual fails to render.

Figure 1: Architecture diagram showing the complete request flow

User synchronization and role-based access control

Each Amazon Cognito user who needs to view an embedded visual must also exist as a registered user inside Amazon Quick Sight. The Lambda function handles this synchronization on every embed URL request. When a user signs in through Cognito, the React application requests an embed URL. The Lambda function receives the user’s email address from the validated JWT and calls describe_user to check whether the user already exists in Amazon Quick Sight. If Amazon Quick Sight does not find the user, a ResourceNotFoundException is raised. The function then calls register_user to create the user as a READER, the least privileged role that supports visual embedding. This approach provisions each new Cognito user in Amazon Quick Sight on first access with no manual intervention.

Role-based access control (RBAC)

Access control in this solution operates at multiple levels to enforce least privilege. API Gateway validates the Cognito JWT token before any request reaches AWS Lambda, so only authenticated users can request embed URLs. The Lambda function then registers every new user in Amazon Quick Sight with UserRole='READER' to grant the minimum permissions required for embedded visual consumption. However, registration alone doesn’t grant access to any dashboard. You can handle this permission step in one of two ways. The first approach is to have an administrator share the target dashboard with the new user through the Quick Sight console and assign Viewer permissions before the user logs in. The second approach extends the Lambda function to also call update_dashboard_permissions after register_user to grant Viewer access at registration time. This way, the user sees the visual on first login without manual intervention. After the user has Viewer permissions, the embed URL further narrows access by scoping it to a specific DashboardId, SheetId, and VisualId. A user can only view visuals explicitly shared with them through Viewer permissions on the parent dashboard. For data-level restrictions, you can layer Quick Sight Row-Level Security to control which rows each user sees based on their username or group membership.

Prerequisites

Before you begin, confirm that you have the following:

  1. An AWS account with an active Amazon Quick Sight subscription configured with AWS IAM Identity Center as the authentication method.
  2. Node.js 16 or later, npm, and a React development environment.
  3. A published Amazon Quick Sight dashboard containing at least one visual.
  4. The Dashboard ID, Sheet ID, and Visual ID for the target visual (available from the Embed visual pane in the Quick Sight dashboard).
  5. Appropriate AWS Identity and Access Management (IAM) permissions to deploy CloudFormation stacks, create Lambda functions, and configure API Gateway.

Important:

This solution uses the registered user embedding method. You restrict access to dashboards and visuals that you explicitly share with your authenticated users.

Generating the embed URL with AWS Lambda

The Lambda function is the core of the backend. It receives the authenticated user’s email and the visual identifiers (dashboard_id, sheet_id, visual_id). It then confirms the user exists in Amazon Quick Sight and generates a scoped embed URL using the GenerateEmbedUrlForRegisteredUser API.

The following snippet highlights two key operations:

  1. The describe_user / register_user pattern automatically provisions any new Cognito user as a READER in Amazon Quick Sight. This sync happens on every request so that first-time users are registered without manual intervention.
  2. The ExperienceConfiguration uses DashboardVisual with access to a specific DashboardId, SheetId, and VisualId. This produces a visual embed URL, not a full dashboard embed URL.
# Step 1: Verify user exists in Amazon Quick (Cognito -> QS sync)
try:
    user_resp = quicksight_client.describe_user(
        AwsAccountId=aws_account_id, Namespace='default', UserName=email
    )
    user_arn = user_resp['User']['Arn']
except quicksight_client.exceptions.ResourceNotFoundException:
    user_resp = quicksight_client.register_user(
        IdentityType='IAM', Email=email, UserRole='READER',
        AwsAccountId=aws_account_id, Namespace='default', UserName=email
    )
    user_arn = user_resp['User']['Arn']

# Step 2: Generate embed URL scoped to a specific visual
response = quicksight_client.generate_embed_url_for_registered_user(
    AwsAccountId=aws_account_id,
    SessionLifetimeInMinutes=600,
    UserArn=user_arn,
    ExperienceConfiguration={
        'DashboardVisual': { 'InitialDashboardVisualId': {
            'DashboardId': dashboard_id,
            'SheetId': sheet_id,
            'VisualId': visual_id
        }}
    }
)

Rendering visuals in React with the embedding SDK

The React component fetches the embed URL from the Lambda backend and uses the amazon-quicksight-embedding-sdk to render the visual inside a container element. The two key SDK calls are createEmbeddingContext(), which initializes the embedding context, and embedVisual(), which renders a single visual (not a full dashboard) into the specified container.

// Fetch embed URL from Lambda backend
const res = await apiPOSTQS({ dashboard_id, sheet_id, visual_id });
const url = res.data.embedUrl;

// Initialize SDK and embed the visual
const embeddingContext = await QuickSightEmbedding.createEmbeddingContext();
const visual = await embeddingContext.embedVisual({
    url,
    container: `#${containerId}`,
    height: '600px',
    width: '100%',
    onChange: (event) => {
        if (event.eventName === 'FRAME_LOADED') setLoading(false);
    }
});
embeddedVisualRef.current = visual;

Custom filters from your UI

After visuals are embedded, you can connect your application’s existing filter controls directly to the Amazon Quick Sight visuals. The Quick Sight Embedding SDK exposes runtime methods to apply, update, remove, and query filter groups programmatically. A React menu or date picker in your UI can trigger a filter on the embedded visual without any page reload. Users interact with your branded components while Quick Sight handles the data processing and rendering behind the scenes. You can also chain multiple filter groups to create complex multi-dimension filter combinations from a single UI event. The result is an analytics experience that feels native to your application rather than a third-party widget dropped into the page.

The Amazon Quick Sight Embedding SDK (v2.5.0+) exposes the following runtime filtering methods on the embedded visual object:

  1. addFilterGroups(filterGroups) – Apply one or more filter groups to the visual.
  2. updateFilterGroups(filterGroups) – Update existing filters by FilterGroupId.
  3. removeFilterGroups(filterGroupsOrIds) – Remove filters by group ID.
  4. getFilterGroups() – Query the current filter state on the visual.

The following snippet shows how a React menu’s change handler applies a category filter to the embedded visual:

// Apply a custom filter from your UI to the embedded visual
const applyRegionFilter = async (selectedRegion) => {
    const filterGroup = {
        FilterGroupId: 'custom-region-filter',
        Filters: [{
            CategoryFilter: {
                FilterId: 'region-filter-1',
                Column: {
                    DataSetIdentifier: 'your-dataset',
                    ColumnName: 'Region'
                },
                Configuration: {
                    FilterListConfiguration: {
                        MatchOperator: 'CONTAINS',
                        CategoryValues: [selectedRegion]
                    }
                }
            }
        }],
        ScopeConfiguration: { AllSheets: {} },
        CrossDataset: 'ALL_DATASETS'
    };
    await embeddedVisualRef.current.addFilterGroups([filterGroup]);
};

This pattern gives your application control over the filtering UX. Users interact with your branded components while Amazon Quick Sight handles all the data processing and rendering behind the scenes. You can chain multiple filter groups to create complex, multi-dimension filter combinations, all triggered from your own UI events.

Implementation steps

Follow these steps to deploy and configure the solution in your AWS environment. You will start by deploying the backend infrastructure through AWS CloudFormation. Then you will configure the React front end and create your first Cognito user. Each step builds on the previous one, so that by the final step your application renders a live Quick Sight visual scoped to an authenticated user.

Step 1: Deploy the backend infrastructure

Deploy the AWS CloudFormation stack to provision all backend resources. This approach verifies all resources are provisioned with correct IAM permissions and cross-service references from the start, helping to reduce manual wiring errors.

  1. Run the following command to clone the GitHub repository and navigate to the project directory:
git clone https://github.com/aws-samples/sample-quicksight-visual-embedding.git
cd sample-quicksight-visual-embedding
  1. Create a new AWS CloudFormation stack and upload the template.yaml file from your local GitHub repository.
CloudFormation console create-stack page with the template.yaml file uploaded

Figure 2: Create a new CloudFormation stack and upload the template file

  1. When deployment is complete, choose the Outputs tab. Copy the values for ApiGatewayUrl, UserPoolId, UserPoolClientId, CloudFrontDomainName, and S3BucketName. You use this information in subsequent steps.

Step 2: Configure the front-end environment

Retrieve Amazon Quick Sight visual identifiers

  1. Open your published Amazon Quick Sight dashboard.
  2. Choose the visual that you want to display in your front-end application. Open the three-dot menu (⋮) in the top-right corner of the visual and choose Embed visual from the context menu.
Quick Sight visual context menu with the Embed visual option highlighted

Figure 3: Context menu showing embed options for the selected visual

  1. In the Embed visual panel that opens on the right, note the following IDs listed under IDs for developers: Dashboard ID, Sheet ID, Visual ID.
Embed visual panel showing the Dashboard ID, Sheet ID, and Visual ID under IDs for developers

Figure 4: Embed visual panel displaying IDs for developers

Configure your local React environment

To set up your local React environment and link it to AWS resources, create an .env file in the my-app/ folder of your local GitHub repository. Populate the file with:

  1. Your AWS Region.
  2. Amazon Cognito pool information (User Pool ID and App Client ID from the CloudFormation stack Outputs tab in Step 1).
  3. Amazon API Gateway endpoint (from the CloudFormation stack Outputs tab in Step 1).
  4. Amazon Quick visual IDs (the DashboardId, SheetId, and VisualId you retrieved from the Embed visual pane earlier in this step).

The following example shows the required contents of the .env file:

VITE_AWS_REGION=us-east-1
# Amazon Cognito Configuration (from AWS CloudFormation outputs)
VITE_USER_POOL_ID=us-east-1_xxxxxxxxx
VITE_USER_POOL_WEB_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxx
# API Configuration (from AWS CloudFormation outputs)
VITE_API_URL=https://your-api-id.execute-api.us-east-1.amazonaws.com/prod
# Amazon Quick Visual Configuration
VITE_DASHBOARD_ID=your-dashboard-id
VITE_SHEET_ID=your-sheet-id
VITE_VISUAL_ID=your-visual-id

Step 3: Set up user authentication

To get authenticated user access to embedded Amazon Quick visuals, first create users in Amazon Cognito:

  1. On the Amazon Cognito console, navigate to User pools, and then choose the pool that matches UserPoolId (from AWS CloudFormation outputs).
  2. Add users to the pool. You have two options:
    • In Amazon Cognito, create users manually with email addresses and temporary passwords.
    • Turn on self-signup in the UI by setting hideSignUp={false} in the my-app/src/auth/AuthWrapper.jsx file.

Step 4: Build and deploy the React front end

Install dependencies and build the project

Run the following commands from the React application directory to generate optimized production files:

cd my-app
npm install
npm run build

Upload the build files to Amazon S3

Upload all the files from the my-app/dist/ directory to the Amazon S3 bucket provisioned by AWS CloudFormation. Do not upload the directory itself.

Create an Amazon CloudFront invalidation

Open the CloudFront console and select your distribution. Choose the Invalidations tab and then choose Create invalidation. Enter /* as the object path and submit the request. This clears all cached content so that CloudFront serves the latest version of your React application from S3.

Step 5: Configure the Amazon Quick allowlist

Add the Amazon CloudFront domain to the Amazon Quick allowlist:

  1. In the Amazon Quick console, choose your account name in the top-right corner and open Manage account from the menu.
Manage account option in the Amazon Quick console account menu

Figure 5: Manage account from the Amazon Quick console

  1. In the left navigation panel, under Security, choose Manage domains.
  2. In the Domain field, enter your Amazon CloudFront domain.
  3. Choose Add.
Manage domains page with the CloudFront domain added to the embedding allowlist

Figure 6: Manage domains page with the CloudFront domain added to the allowlist

Step 6: Access the application and complete user registration

With the front end deployed and the allowlist configured, open the React application using your CloudFront domain URL and sign in with your Cognito credentials. On this first login, the embedded visuals will not render. The newly registered user doesn’t yet have Viewer permissions on the target dashboard. This is expected behavior. Behind the scenes, the initial API call triggers the Lambda function’s register_user logic to automatically provision your Cognito-authenticated identity as a READER in Amazon Quick Sight. You can confirm the registration succeeded by checking Manage users in the Quick Sight console. The following steps grant the necessary dashboard-level access so the visuals load on subsequent logins.

Manage users page in the Amazon Quick console showing the auto-registered reader user

Figure 7: Manage users in the Amazon Quick console, verifying the auto-registered user

After the user exists in Quick Sight, you must grant them access to the specific dashboard containing your target visuals.

  1. On the Amazon Quick Sight console, choose Dashboards.
  2. Select the dashboard that you want to share by choosing its name.
  3. In the upper-right corner of the dashboard page, choose Share.
Share dashboard dialog for granting access to authenticated users

Figure 8: Share dashboard with authenticated users

  1. In the Invite users and groups to dashboard section, enter the recipient’s complete email address in the search field (this email should match the user’s Amazon Cognito login exactly).
  2. From the Permission menu next to the email field, choose Viewer.
  3. To send the invitation and grant access, choose Share.
Dashboard permissions with Viewer access granted to the authenticated user

Figure 9: Manage permissions: Viewer permission granted to the authenticated user

  1. Each user receives an email with a link to the dashboard. You can modify permissions at any time through the Share menu.
  2. Refresh the application in your browser (or sign out and back in).
  3. The embedded Quick Sight visual should now render within your React application, respecting the user-specific access permissions you configured. If the visual loads successfully, your end-to-end integration is complete.

The embedded visual should render within your React application as follows:

Amazon Quick Sight visual embedded in the React web application

Figure 10: Amazon Quick visual embedded in the React web application

Cleanup

To avoid incurring ongoing charges, remove the resources created by this solution after you have finished experimenting.

  1. In the CloudFormation console, choose the quicksight-embedding-stack stack and choose Delete.
  2. Wait for the stack to reach DELETE_COMPLETE status. This removes API Gateway, Lambda, Cognito User Pool, S3 bucket, and CloudFront distribution.
  3. In the Amazon Quick Sight console, navigate to Manage users and remove any test users that the Lambda function automatically provisioned.
  4. Remove the CloudFront domain from the Amazon Quick Sight embedding allowlist under Domains and embedding.
  5. If you turned on self-signup and test users created accounts, verify that the stack successfully deleted the Cognito User Pool. If it was not removed, delete it manually.

Review your AWS account for any remaining resources and delete them manually if needed. Common resources that survive stack deletion include: CloudWatch log groups, IAM roles and policies, S3 buckets (CloudFormation can’t delete non-empty buckets), Lambda-created network interfaces, AWS Key Management Service (AWS KMS) keys (scheduled for deletion on a waiting period rather than removed immediately), and any Quick Sight resources (registered users, datasets, dashboards) that were created outside the stack.

Conclusion

In this post, you learned how to embed individual Amazon Quick Sight visuals using Cognito-based registered user authentication, READER-role RBAC, and a serverless embed URL generation backend. With this approach, embedded visuals appear as part of your application rather than a separate BI tool. Embedding individual visuals instead of full dashboards gives you precise layout control, context-aware analytics placement, and a streamlined user journey without separate BI tool navigation.

After your embedded visuals are rendering successfully, consider exploring the optional custom filters pattern described earlier in the Custom filters from your UI section. With the runtime filtering API in the Quick Sight Embedding SDK, you can replace the built-in Quick Sight filter controls with your own branded React components, connecting dropdowns, date pickers, and search fields directly to the embedded visual. This is an independent enhancement that you can add at any time without modifying the core embedding architecture you have just built.

Start by embedding one visual to validate the workflow end-to-end. After it’s confirmed, add more visuals and build a complete analytics interface within your existing application.

For detailed guidance on embedding configurations, authentication patterns, and SDK capabilities, consult the Amazon Quick Sight Embedding SDK Documentation and the Amazon Cognito Developer Guide.


About the authors

Ishita Gupta

Ishita Gupta

Ishita Gupta works at Professional Services GCC, where she has been helping enterprises build and deliver cloud-native applications. With expertise spanning both frontend and backend development, she is passionate about building innovative solutions and bringing applications to life through code.

Aayush Gupta

Aayush Gupta

Aayush Gupta works at Professional Services GCC, where he builds high-throughput backend systems and real-time data platforms on AWS. He focuses on event-driven architectures and serverless automation for enterprise telecom workloads and enjoys picking up new technologies to solve customer problems end-to-end.

Saurabh Singh

Saurabh Singh

Saurabh Singh works at Professional Services GCC as a Senior Delivery Consultant, guiding teams in building robust, production-grade cloud architectures on AWS. He brings deep expertise in cloud infrastructure and distributed systems and is passionate about mentoring teams and delivering solutions that balance performance, security, and cost efficiency.

Srishti Wadhwa

Srishti Wadhwa

Srishti Wadhwa works at Professional Services GCC, working across serverless application development, large-scale data analytics and infrastructure automation. She has built enterprise-scale data ingestion and validation pipelines, developed event-driven serverless platforms and actively contributes reusable reference architectures to the AWS open-source community. A TFC Gold Member recognized for sustained contribution to technical enablement and knowledge sharing.

Jat AI Stay informed with the latest in artificial intelligence. Jat AI News Portal is your go-to source for AI trends, breakthroughs, and industry analysis. Connect with the community of technologists and business professionals shaping the future.