Making authenticated Amazon Q Business API calls using IAM federation
Amazon Q Business can securely handle data with integrated authentication and authorization. During data ingestion, Amazon Q Business preserves the authorization information—access control lists (ACLs)—from the data source so users can only request answers from the data they already have access to. Through IAM Federation, Amazon Q Business uses trusted identity propagation to ensure that an end user is authenticated and receives fine-grained authorization to their user ID and group-based resources.
In order to achieve this, a subset of the Amazon Q Business APIs (Chat, ChatSync, ListConversations, ListMessages, DeleteConversation, PutFeedback) require identity-aware AWS Sig V4 credentials for the authenticated user on whose behalf the API call is being made.
This page provides an overview of the workflows needed to obtain AWS Sig V4 credentials for a user authenticated using an identity provider (IdP), such as Okta. While we use Okta as an example, the same principles and steps apply to any other identity provider synced with your IAM instance.
Important
Amazon Q Business doesn't support OIDC for Google and Microsoft Entra ID.
Note
Federated groups aren't supported through IAM Federation. If you want to ingest federated groups, use the PutGroup API.
Prerequisites
Before you begin setting up for making Sig V4 authenticated API calls, make sure you've done the following:
-
Created an Okta IdP instance and configured users and groups within it. While we use Okta as an example, the same principles and steps apply to any other identity provider connected to your IAM instance.
-
Created an IAM instance for your Amazon Q Business application and connected Okta as your identity source.
-
Configured access to the AWS CLI.
One-time setup
The following section outlines the steps to set up the Amazon Q Business control plane. You only need to perform these steps once.
-
Create an OIDC app integration
in Okta. -
Create the IAM identity provider using the following command:
aws iam \ create-open-id-connect-provider \ --url
issuer-url
Then, copy the
OpenIDConnectProviderArn
from the output. -
Next, create the IAM role. To do so, perform the following steps:
-
Create a directory named
policies
. -
In that directory, create and save a file named
trustpolicyforfederation.json
with the following JSON included:{ "Version": "2012-10-17", "Statement": { "Sid": "RoleForOkta", "Effect": "Allow", "Principal": { "Federated": "
OpenIdConnectProviderArn
" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "issuer-url
:aud": "client-id
" } } } }
-
-
Next, create the IAM policy for your web experience. To do so, perform the following steps:
-
In the
policies
directory, create and save a new file namedpermspolicyforfederation.json
with the following JSON included:{ "Version": "2012-10-17", "Statement": [{ "Sid": "QBusinessConversationPermissions", "Effect": "Allow", "Action": [ "qbusiness:Chat", "qbusiness:ChatSync", "qbusiness:ListMessages", "qbusiness:ListConversations", "qbusiness:PutFeedback", "qbusiness:DeleteConversation", "qbusiness:GetWebExperience", "qbusiness:GetApplication", "qbusiness:ListPlugins", "qbusiness:GetChatControlsConfiguration", "qbusiness:ListRetrievers", "qbusiness:GetMedia" ], "Resource": "arn:aws:qbusiness:{{
region
}}:{{source_account
}}:application/{{application_id
}}" }, { "Sid": "QBusinessRetrieverPermission", "Effect": "Allow", "Action": [ "qbusiness:GetRetriever" ], "Resource": [ "arn:aws:qbusiness:{{region
}}:{{source_account
}}:application/{{application_id
}}", "arn:aws:qbusiness:{{region
}}:{{source_account
}}:application/{{application_id
}}/retriever/*" ] }, { "Sid": "QBusinessAutoSubscriptionPermission", "Effect": "Allow", "Action": [ "user-subscriptions:CreateClaim" ], "Condition": { "Bool": { "user-subscriptions:CreateForSelf": "true" }, "StringEquals": { "aws:CalledViaLast": "qbusiness.amazonaws.com" } }, "Resource": [ "*" ] }, { "Sid": "QBusinessKMSDecryptPermissions", "Effect": "Allow", "Action": [ "kms:Decrypt" ], "Resource": [ "arn:aws:kms:{{region
}}:{{account_id
}}:key/[[key_id
]]" ], "Condition": { "StringLike": { "kms:ViaService": [ "qbusiness.{{region
}}.amazonaws.com", "qapps.{{region
}}.amazonaws.com" ] } } }, { "Sid": "QAppsResourceAgnosticPermissions", "Effect": "Allow", "Action": [ "qapps:CreateQApp", "qapps:PredictQApp", "qapps:PredictProblemStatementFromConversation", "qapps:PredictQAppFromProblemStatement", "qapps:ListQApps", "qapps:ListLibraryItems", "qapps:CreateSubscriptionToken" ], "Resource": "arn:aws:qbusiness:{{region
}}:{{source_account
}}:application/{{application_id
}}" }, { "Sid": "QAppsAppUniversalPermissions", "Effect": "Allow", "Action": [ "qapps:DisassociateQAppFromUser" ], "Resource": "arn:aws:qapps:{{region
}}:{{source_account
}}:application/{{application_id
}}/qapp/*" }, { "Sid": "QAppsAppOwnerPermissions", "Effect": "Allow", "Action": [ "qapps:GetQApp", "qapps:CopyQApp", "qapps:UpdateQApp", "qapps:DeleteQApp", "qapps:ImportDocument", "qapps:ImportDocumentToQApp", "qapps:CreateLibraryItem", "qapps:UpdateLibraryItem", "qapps:StartQAppSession" ], "Resource": "arn:aws:qapps:{{region
}}:{{source_account
}}:application/{{application_id
}}/qapp/*", "Condition": { "StringEqualsIgnoreCase": { "qapps:UserIsAppOwner": "true" } } }, { "Sid": "QAppsPublishedAppPermissions", "Effect": "Allow", "Action": [ "qapps:GetQApp", "qapps:CopyQApp", "qapps:AssociateQAppWithUser", "qapps:GetLibraryItem", "qapps:CreateLibraryItemReview", "qapps:AssociateLibraryItemReview", "qapps:DisassociateLibraryItemReview", "qapps:StartQAppSession" ], "Resource": "arn:aws:qapps:{{region
}}:{{source_account
}}:application/{{application_id
}}/qapp/*", "Condition": { "StringEqualsIgnoreCase": { "qapps:AppIsPublished": "true" } } }, { "Sid": "QAppsAppSessionModeratorPermissions", "Effect": "Allow", "Action": [ "qapps:ImportDocument", "qapps:ImportDocumentToQAppSession", "qapps:GetQAppSession", "qapps:GetQAppSessionMetadata", "qapps:UpdateQAppSession", "qapps:UpdateQAppSessionMetadata", "qapps:StopQAppSession" ], "Resource": "arn:aws:qapps:{{region}}
:{{source_account
}}:application/{{application_id
}}/qapp/*/session/*", "Condition": { "StringEqualsIgnoreCase": { "qapps:UserIsSessionModerator": "true" } } }, { "Sid": "QAppsSharedAppSessionPermissions", "Effect": "Allow", "Action": [ "qapps:ImportDocument", "qapps:ImportDocumentToQAppSession", "qapps:GetQAppSession", "qapps:GetQAppSessionMetadata", "qapps:UpdateQAppSession" ], "Resource": "arn:aws:qapps:{{region
}}:{{source_account
}}:application/{{application_id
}}/qapp/*/session/*", "Condition": { "StringEqualsIgnoreCase": { "qapps:SessionIsShared": "true" } } } ] }
-
-
Finally, create and attach the roles in IAM using the following command:
aws iam \ create-role \ --role-name --assume-role-policy-document
file://policies/trustpolicyforfederation.json
\ --policy-documentfile://policies/permspolicyforfederation.json
Workflow for each API call session for authenticated user
-
First, use the
IdToken
from Okta to call the AssumeRoleWithWebIdentity API to get AWS credentials. To do so, use the following command:aws sts assume-role-with-web-identity --role-arn
role arn
--role-session-namesession-name
--web-identity-tokenid-token-from-okta
-
Then, set the following environment variables in your command line environment using the credentials you received as a response from the AssumeRoleWithWebIdentity API call.
AWS_ACCESS_KEY_ID="
identity-aware-sigv4-access-key
" AWS_SECRET_ACCESS_KEY="identity-aware-sigv4-secret-key
" AWS_SESSION_TOKEN="identity-aware-sigv4-session-token
" -
Then, make Amazon Q Business API calls using the following command:
aws qbusiness \ chat-sync \ --application-id
application-id
--user-messagesample-chat-request