Amazon Q Developer
Analyze AI coding metrics from Amazon Q Developer, including usage, adoption, and productivity insights. Antenna connects to your AWS account using IAM role-based authentication, securely reading usage data from your S3 bucket.
Prerequisites
- An AWS account with Amazon Q Developer Pro subscriptions
- IAM permissions to create policies and roles
- An S3 bucket receiving Amazon Q usage data
To export usage data, enable Q Developer user activity report in your Amazon Q admin settings and set the S3 location to your bucket.
Setup
Get your External ID
On app.antenna.dev, go to Settings > Connected Apps > Amazon Q Developer and copy the External ID.
Create an IAM policy
In your AWS account, create an IAM policy that grants read access to your Amazon Q S3 bucket.
Amazon Q usage data identifies users by UUID only — it does not include email addresses. You can also provide access to IAM Identity Center (formerly AWS SSO). This permission is optional but preferred for automatic syncing of users with Antenna. The only information we sync from your Identity Store are AWS UUID, display name, and email. If you prefer to maintain the user directory CSV yourself, you can remove the identitystore:ListUsers statement from the policy JSON in the next step.
- Go to IAM > Policies > Create policy.
- Select the JSON tab and paste the following, replacing
YOUR_BUCKET_NAME(e.g. q-developer-data) with your bucket name. If you are using the Identity Store permission, replaceYOUR_ACCOUNT_IDwith your 12-digit AWS account ID andYOUR_IDENTITY_STORE_IDwith your identity store ID (for exampled-xxxxxxxxxx). You can find the identity store ID under IAM Identity Center > Settings.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::YOUR_BUCKET_NAME",
"arn:aws:s3:::YOUR_BUCKET_NAME/*"
]
},
{
"Effect": "Allow",
"Action": [
"identitystore:ListUsers"
],
"Resource": "arn:aws:identitystore::YOUR_ACCOUNT_ID:identitystore/YOUR_IDENTITY_STORE_ID"
}
]
}The Identity Store Resource ARN uses the form arn:aws:identitystore::ACCOUNT_ID:identitystore/ID: the segment between identitystore and your account ID is the region field, which AWS leaves empty for this resource type. You must still include your account ID—unlike S3 bucket ARNs, empty ARN components are not wildcards in IAM, so a placeholder with no account ID (for example three colons in a row before identitystore/…) will not grant identitystore:ListUsers on your directory.
- Name the policy (e.g.,
Antenna-AmazonQ-ReadOnly) and create it.
Create an IAM role
Create an IAM role that allows Antenna to read from your S3 bucket. The trust policy below grants access to arn:aws:iam::134217665810:role/software-app-prod, which is the IAM role managed by Antenna.
- Go to IAM > Roles > Create role.
- Select Custom trust policy and paste the following, replacing
YOUR_EXTERNAL_IDwith the value from Step 1:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::134217665810:role/software-app-prod"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "YOUR_EXTERNAL_ID"
}
}
}
]
}- Click Next and attach the policy you created in the Create an IAM policy step.
- Name the role (e.g.,
Antenna-AmazonQ-Role) and create it. - Copy the Role ARN from the role summary page.
Create the user directory
Skip this step if you included identitystore:ListUsers in your IAM policy.
Amazon Q usage data identifies users by UUID only — it does not include email addresses. You need to upload a CSV that maps each UserId to an Email and/or DisplayName so Antenna can match Amazon Q users to your team members.
Create a CSV file with the following format:
UserId,DisplayName,Email
"a1b2c3d4-e5f6-7890-abcd-ef1234567890","Jane Doe","jane@example.com"
"b2c3d4e5-f6a7-8901-bcde-f12345678901","John Jay","john@example.com"You can find both fields in AWS IAM Identity Center (formerly AWS SSO). Use the AWS CLI to list all users:
aws identitystore list-users --identity-store-id YOUR_IDENTITY_STORE_IDThis will return a paginated response. Each user in the response includes a UserId, DisplayName, and their Emails. Upload the finished CSV to a directory in your S3 bucket (e.g., user-directory/).
Here is an example script to extract users from the JSON into a CSV:
#!/bin/bash
# Prompt for Identity Store ID
read -p "Enter your Identity Store ID (e.g., d-1234567890): " IDENTITY_STORE_ID
# Basic validation to ensure ID is provided
if [ -z "$IDENTITY_STORE_ID" ]; then
echo "Error: Identity Store ID cannot be empty."
exit 1
fi
OUTPUT_FILE="identity_store_users.csv"
# Write the CSV header
echo "UserId,DisplayName,Email" > "$OUTPUT_FILE"
echo "Starting export from Identity Store: $IDENTITY_STORE_ID..."
NEXT_TOKEN=""
while : ; do
# Fetch a page of users. We use JSON output for easier parsing with jq.
if [ -z "$NEXT_TOKEN" ]; then
RESPONSE=$(aws identitystore list-users --identity-store-id "$IDENTITY_STORE_ID" --output json)
else
RESPONSE=$(aws identitystore list-users --identity-store-id "$IDENTITY_STORE_ID" --starting-token "$NEXT_TOKEN" --output json)
fi
# Parse and append data
# The jq filter finds the email where .Primary is true, falls back to the first email, or returns empty.
echo "$RESPONSE" | jq -r '.Users[] | [
.UserId,
.DisplayName // "",
(.Emails[]? | select(.Primary == true).Value // .Value) // ""
] | @csv' >> "$OUTPUT_FILE"
# Check for a NextToken to determine if more pages exist
NEXT_TOKEN=$(echo "$RESPONSE" | jq -r '.NextToken // empty')
# Exit loop if no more tokens are returned
if [[ -z "$NEXT_TOKEN" ]]; then
break
fi
done
echo "Export complete! Data saved to $OUTPUT_FILE"To keep the Amazon Q user directory current, you can set up a recurring AWS job using EventBridge Scheduler triggering a Lambda function on a defined schedule. The Lambda function queries IAM Identity Center via the identitystore:ListUsers API to retrieve all users and their primary email addresses, then compiles them into a CSV mapping each UserId to an Email. The resulting file is automatically uploaded to a designated S3 path (e.g., s3://q-developer-data/user-directory/user_directory.csv).
Add the connection
Back on app.antenna.dev, go to Settings > Connected Apps > Amazon Q Developer and enter:
- Role ARN — The ARN of the IAM role you created
- S3 bucket region — The AWS region of your S3 bucket
- Bucket Name — Your S3 bucket name
- Usage metrics directory — The directory that contains the
AWSLogsfolder. For example, if your metrics are ats3://q-developer-data/q-developer-user-data/AWSLogs, enterq-developer-user-data. - Identity Store ID - Your Identity Center Identity Store ID (optional)
- Identity Store region — The AWS region of your Identity Store (optional)
- User directory — The directory that contains your user directory CSV. For example, if your file is at
s3://q-developer-data/user-directory/user-directory.csv, enteruser-directory.
Click Connect to finish.
Alternative: S3 Replication (Push)
If your organization prefers not to grant Antenna cross-account IAM role access, you can use S3 Cross-Account Replication instead. In this model, your S3 bucket automatically pushes data into a dedicated Antenna-managed bucket. Antenna never accesses your account, and you never access Antenna’s account — replication is handled entirely by AWS’s S3 service internally.
This is a push model — you stay in full control and can disable replication at any time by deleting the replication rule. Replication only applies to new objects going forward. If historical data needs to be ingested, a separate S3 Batch Replication job can be run as a one-time backfill.
What you need
- Admin access to your AWS account
- The Destination Bucket ARN and AWS Account ID provided by Antenna
Replication setup
Enable versioning on your source bucket
S3 Cross-Account Replication requires versioning on the source bucket.
- Go to S3 > your source bucket > Properties.
- Under Bucket Versioning, click Edit and select Enable.
- Click Save changes.
Enabling versioning may slightly increase your S3 storage costs, as AWS retains previous versions of objects.
Create a replication IAM role
Create an IAM role in your account that allows S3 to replicate objects to Antenna’s destination bucket.
- Go to IAM > Roles > Create role.
- Select Custom trust policy and paste the following:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}- Click Next, then Create policy and paste the following inline policy. Replace
YOUR_SOURCE_BUCKETwith your bucket name andANTENNA_DESTINATION_BUCKET_ARNwith the ARN provided by Antenna:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetReplicationConfiguration",
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::YOUR_SOURCE_BUCKET"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObjectVersionForReplication",
"s3:GetObjectVersionAcl",
"s3:GetObjectVersionTagging"
],
"Resource": "arn:aws:s3:::YOUR_SOURCE_BUCKET/*"
},
{
"Effect": "Allow",
"Action": [
"s3:ReplicateObject",
"s3:ReplicateDelete",
"s3:ReplicateTags"
],
"Resource": "ANTENNA_DESTINATION_BUCKET_ARN/*"
}
]
}- Name the role (e.g.,
Antenna-S3-Replication-Role) and create it.
Create a replication rule
- Go to S3 > your source bucket > Management > Replication rules > Create replication rule.
- Give the rule a name (e.g.,
Antenna-Replication). - Under Source bucket, scope the rule to the appropriate prefix for your data (e.g.,
AWSLogs/for Bedrock invocation logs orq-developer-user-data/for Amazon Q usage data). - Under Destination, select Specify a bucket in another account, and enter the Account ID and Destination Bucket ARN provided by Antenna.
- Select the IAM role you created in the previous step.
- Click Save.
Verify replication
After creating the rule, new objects written to your source bucket under the configured prefix will automatically replicate to Antenna’s bucket. You can verify replication status in the S3 > Management > Replication rules section of your bucket.
Backfill historical data with S3 Batch Replication (one-time, optional)
The replication rule created above only applies to new objects going forward. To replicate existing objects that were written before the rule was created, run a one-time S3 Batch Replication job.
- Go to S3 > your source bucket > Management > Replication rules.
- Select the replication rule you created in the previous step, then choose Create Batch Replication job.
- Under Batch manifest, select Generate manifest to let S3 automatically identify all eligible existing objects, or provide your own manifest using an S3 Inventory report or CSV file.
- Under Batch replication filters, set the replication status filter to Not replicated to target only objects that have never been replicated.
- Choose a destination for the Completion report so you can verify the results after the job finishes.
- For the IAM role, select the same replication role you created earlier (e.g.,
Antenna-S3-Replication-Role). - Review the job details and choose Create job. The job starts in a Ready state — select the job and choose Run job to begin replication.
- Monitor progress in S3 > Batch Operations. Once complete, review the completion report to confirm all objects replicated successfully.
S3 Batch Replication is a one-time operation. You only need to run this once to backfill historical data. All future objects are handled automatically by the live replication rule.
AWS permissions
Antenna uses only the following permissions to access your Amazon Q usage data:
| Service | Documentation |
|---|---|
sts:AssumeRole | Link |
s3:GetObject | Link |
s3:ListBucket | Link |
identitystore:ListUsers | Link |
Ongoing sync
Amazon Q writes new usage data to your S3 bucket daily. Antenna automatically ingests updated data every 24 hours.