See Deployment Guide → Dependencies for the full list of required build tools and installation instructions (AWS CLI, SAM CLI, Python 3.12+, Node.js 22+).
Note:idp-cli publish does not build Docker images locally — they are built in AWS by CodeBuild during stack deployment. Docker is not required on your workstation.
The ELB hostname (internal-<stack>-webui-alb-<id>.<region>.elb.amazonaws.com) is only known after the stack is deployed, so generating a cert that matches it requires two steps:
Step A: Generate a placeholder cert and deploy the stack:
# Reimport the cert with the ELB hostname as SAN (same ARN — no stack update needed)
./scripts/generate_self_signed_cert.sh\
--regionus-east-1\
--domain"$ALB_DNS"\
--cert-arn"$CERT_ARN"
# The ALB serves the updated cert within ~30 seconds.
Why this matters: browsers block background JavaScript requests (AppSync GraphQL, Cognito token exchange) to hosts with a mismatched TLS cert — even if the user clicked through the initial page-level cert warning. The cert domain must exactly match the hostname in the browser’s address bar.
Production: this isn’t a concern when using DNS + a CA-signed cert. For example, if users access https://idp.internal.company.com and the cert covers that domain, everything works seamlessly.
The command creates an S3 bucket (<bucket-basename>-<region>) if needed, builds all Lambda layers and templates, and uploads artifacts. When done, it prints the Template URL to use in Step 2.
Note:publish.py is deprecated — use idp-cli publish instead.
For enterprise environments with compliance requirements (KMS encryption, tagging, bucket policies, access logging), pre-create the S3 bucket before publishing:
Create a compliant bucket in your account (apply your CMK, tags, bucket policy, access logging, block public access — whatever your compliance requirements dictate)
Run idp-cli publish --bucket-basename <your-bucket-name> — the CLI detects the existing bucket and uploads artifacts without modifying its configuration
When deploying, pass ArtifactsBucketKmsKeyArn=<key-arn> so CodeBuild (DockerBuildRole) and the configuration copy Lambda (ConfigurationCopyFunction) receive kms:Decrypt permission to read from the encrypted bucket
Terminal window
# Step 1: Pre-create your compliant bucket (example — apply your own policies)
If you published with --artifacts-bucket-kms-key-arn in Step 1, you must pass the same KMS key ARN as a parameter when deploying — otherwise CodeBuild (DockerBuildRole) and the configuration copy Lambda (ConfigurationCopyFunction) will fail with AccessDenied: kms:Decrypt when trying to read from the encrypted bucket:
Lambda functions need VPC Interface Endpoints to reach AWS services (AppSync, Bedrock, SQS, etc.) without leaving the AWS backbone.
Run the deployment script — it automatically detects which of the 12 endpoints required by the IDP app (plus 2 optional endpoints for SSM testing) already exist in your VPC and deploys only the missing ones:
Terminal window
pythonscripts/deploy-vpc-endpoints.py\
--vpc-id<vpc-id>\
--stack-nameIDP-PRIVATE\
--region<region>
Windows (PowerShell):
Terminal window
python scripts/deploy-vpc-endpoints.py `
--vpc-id <vpc-id>`
--stack-name IDP-PRIVATE `
--region <region>
The script:
Reads LambdaSubnetIds and LambdaVpcSecurityGroupId from the IDP stack automatically
Checks each of the 14 required endpoints against the VPC
Deploys only the missing ones (skips any that already exist to avoid DNS conflicts)
Amazon WorkSpaces provides a Windows desktop running inside the VPC, giving the browser direct access to the internal ALB and VPC endpoints — no port forwarding or /etc/hosts entries needed.
Requirements:
AWS Directory Service (Simple AD) registered with WorkSpaces in the same VPC
WorkSpaces directory with internet access enabled (EnableInternetAccess=true)
A dedicated public subnet with a NAT Gateway (required for Cognito IDP — the browser calls cognito-idp.<region>.amazonaws.com which has no VPC Interface Endpoint)
Key setup notes:
NAT Gateway placement: the NAT GW must be in a separate public subnet (with 0.0.0.0/0 → IGW route). It cannot provide egress for traffic originating in the same subnet it lives in. Private subnets route 0.0.0.0/0 → NAT GW.
Enable internet access before launching: set EnableInternetAccess=true on the WorkSpaces directory. If the WorkSpace is already running without it, you must rebuild it (~25 min) for the setting to take effect.
Reimport the cert: after the IDP stack is deployed, run the 2-step cert process (see Prerequisites §3) so the TLS cert covers the actual ELB hostname. Browsers silently block background API calls to cert-mismatched domains.
Verifying the deployment:
Once connected to WorkSpaces, open the browser and navigate to the ALB URL (ApplicationWebURL stack output). Accept the self-signed cert warning, then:
✅ Login succeeds and the app loads
✅ Upload a document (e.g. samples/lending_package.pdf) — the status should update live in the document list without refreshing: QUEUED → OCR → CLASSIFICATION → EXTRACTION → ...
✅ Open browser DevTools → Network → WS tab — confirm an active WebSocket connection to *.appsync-realtime-api.<region>.amazonaws.com
The live status updates confirm that AppSync WebSocket subscriptions work through the appsync-api VPC Interface Endpoint. There is no separate appsync-realtime-api endpoint — the appsync-api endpoint handles both HTTPS (queries/mutations) and WSS (subscriptions/realtime).
If WebSocket subscriptions are not working (document status does not update live), the following features are degraded (queries and mutations still work):
Feature
Impact
Document list auto-refresh
❌ Does not update after upload — must reload manually
Processing status live updates
❌ Status stays frozen — must reload to see progress
Agent chat streaming
❌ Messages don’t appear in real time
Discovery job live status
❌ Does not update automatically
To diagnose: check that the appsync-api VPC endpoint is available and its security group allows inbound HTTPS (443) from the WorkSpace subnet CIDR.
Cost estimate: WorkSpaces AutoStop bundle ~$7.25/mo + NAT Gateway ~$0.045/hr while active. Clean up WorkSpace, directory, NAT Gateway, and Internet Gateway when testing is complete.
A VPC endpoint already exists for that service. Re-run check-vpc-endpoints.sh — it will detect this and set the right Create*=false flags.
UI loads but shows “network error”
AppSync API is PRIVATE. From outside the VPC you need an SSM tunnel + /etc/hosts entry. From inside VPN/VPC it works automatically.
CodeBuild fails: AccessDenied: kms:Decrypt
The artifact bucket is KMS-encrypted but ArtifactsBucketKmsKeyArn was not passed to the deploy command. Redeploy with --parameters "...ArtifactsBucketKmsKeyArn=<key-arn>".
UpdateDefaultConfig custom resource fails with NoSuchKey
Same root cause as above — ConfigurationCopyFunction silently skipped copying config files due to missing kms:Decrypt. Pass ArtifactsBucketKmsKeyArn and redeploy.
OCR Lambda times out / Textract calls hang
Missing textract VPC endpoint. Lambda can’t reach com.amazonaws.<region>.textract — security group only allows port 443 outbound to VPC endpoints. Run deploy-vpc-endpoints.py to add the missing endpoint.
BDA Lambda times out / STS AssumeRole fails
Missing sts VPC endpoint. Lambda can’t reach com.amazonaws.<region>.sts. Run deploy-vpc-endpoints.py to add the missing endpoint.
403 Forbidden on ALB
Check ALB target group health checks (expected: 200, 307, 405). Verify S3 bucket policy has the correct VPC endpoint ID.
Target Group Unhealthy
VPC endpoint ENIs may be stale. Check the endpoint SG allows HTTPS (443) from the ALB.
App spins after login (stuck loading)
TLS cert domain mismatch. The ALB cert must include the ELB DNS hostname as a SAN. Run scripts/generate_self_signed_cert.sh with --cert-arn and --domain set to the ALB DNS name to reimport the cert. See Prerequisites §3.
Login hangs on cognito-idp.amazonaws.com
Browser (WorkSpaces, bastion) needs internet access to reach Cognito IDP — there is no VPC endpoint for Cognito IDP. Ensure a NAT Gateway exists in a public subnet (with 0.0.0.0/0 → IGW route) and private subnets route internet traffic through it.