Complete guide for deploying, configuring, and managing the Defect Detection Application (DDA) Portal.
- Architecture Overview
- Initial Portal Deployment
- Account Setup
- Onboarding a New Customer
- Creating a UseCase
- Portal Features
- Troubleshooting
Related Guides:
- DATA_ACCOUNT_SETUP.md - Detailed data account configuration scenarios
- SHARED_COMPONENTS.md - Greengrass component provisioning
- DEPLOYMENT.md - Quick deployment reference
┌─────────────────────────────────────────────────────────────────────────┐
│ PORTAL ACCOUNT │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ CloudFront │ │ API Gateway │ │ Cognito │ │ DynamoDB │ │
│ │ (Frontend) │ │ (REST) │ │ (Auth) │ │ (Storage) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │
│ └────────────────┼──────────────────────────────────────────────┤
│ │ │
│ Lambda Functions │
│ │ │
└──────────────────────────┼──────────────────────────────────────────────┘
│
┌──────────────┴──────────────┐
│ AssumeRole (STS) │
│ with External ID │
▼ ▼
┌─────────────────────────────┐ ┌─────────────────────────────┐
│ USECASE ACCOUNT │ │ DATA ACCOUNT (Optional) │
│ ┌─────────────────────┐ │ │ ┌─────────────────────┐ │
│ │ DDAPortalAccessRole │ │ │ │ DDADataAccessRole │ │
│ └─────────────────────┘ │ │ └─────────────────────┘ │
│ │ │ │
│ • SageMaker Training │ │ • S3 Training Data │
│ • Ground Truth Labeling │ │ • Tagged Buckets │
│ • Greengrass Components │ │ │
│ • IoT Core Devices │ │ │
│ • S3 Buckets (if no Data) │ │ │
└─────────────────────────────┘ └─────────────────────────────┘
| Account | Purpose | Required |
|---|---|---|
| Portal Account | Hosts the portal infrastructure (API, frontend, auth) | Yes |
| UseCase Account | Runs ML workloads (training, labeling, deployments) | Yes |
| Data Account | Stores training data in isolated S3 buckets | Optional |
Flexibility: All three can be the same AWS account for simple deployments, or separate accounts for enterprise isolation.
The portal uses two different scoping models depending on where data is stored:
| Resource Type | Storage | Scoping | Notes |
|---|---|---|---|
| Training Jobs | Portal DynamoDB | Per UseCase ID | Strictly isolated by usecase_id |
| Labeling Jobs | Portal DynamoDB | Per UseCase ID | Strictly isolated by usecase_id |
| Pre-labeled Datasets | Portal DynamoDB | Per UseCase ID | Strictly isolated by usecase_id |
| S3 Buckets | UseCase/Data Account | Per AWS Account | All buckets tagged dda-portal:managed=true |
| Greengrass Components | UseCase Account | Per AWS Account | All components tagged dda-portal:managed=true |
| IoT Devices | UseCase Account | Per AWS Account | All devices tagged dda-portal:managed=true |
Important: For AWS resources (S3, Components, Devices), selecting a UseCase in the portal determines which AWS account to query via cross-account role. All portal-managed resources in that account will be visible.
Recommendation: Use one UseCase per AWS account for clear resource isolation. If you need multiple use cases, use separate AWS accounts.
Future Enhancement: UseCase-level isolation for AWS resources can be added by filtering on
dda-portal:usecase-idtag. Components already include this tag; devices and buckets would need to be updated.
- AWS CLI configured with admin credentials
- Node.js 18+, Python 3.11+
- AWS CDK:
npm install -g aws-cdk
cd edge-cv-portal/infrastructure
npm install
cdk bootstrap # First time only
cdk deploy --all --require-approval neverOutputs to save:
ApiUrl- Backend API endpointUserPoolId- Cognito User Pool IDUserPoolClientId- Cognito Client IDDistributionDomainName- CloudFront URL
cd ../frontend
npm install
# Create config with CDK outputs
cat > public/config.json << EOF
{
"apiUrl": "<API_URL>",
"userPoolId": "<USER_POOL_ID>",
"userPoolClientId": "<CLIENT_ID>",
"region": "us-east-1"
}
EOF
npm run build
./deploy-frontend.shUSER_POOL_ID="<your-user-pool-id>"
# Create user
aws cognito-idp admin-create-user \
--user-pool-id $USER_POOL_ID \
--username admin \
--user-attributes Name=email,Value=admin@company.com \
--temporary-password TempPass123!
# Set permanent password
aws cognito-idp admin-set-user-password \
--user-pool-id $USER_POOL_ID \
--username admin \
--password YourSecurePassword123! \
--permanent
# Get user sub for role assignment
USER_SUB=$(aws cognito-idp admin-get-user \
--user-pool-id $USER_POOL_ID \
--username admin \
--query 'UserAttributes[?Name==`sub`].Value' --output text)
# Assign PortalAdmin role
aws dynamodb put-item \
--table-name edge-cv-portal-user-roles \
--item "{
\"user_id\": {\"S\": \"$USER_SUB\"},
\"usecase_id\": {\"S\": \"global\"},
\"role\": {\"S\": \"PortalAdmin\"},
\"assigned_at\": {\"N\": \"$(date +%s)000\"},
\"assigned_by\": {\"S\": \"system\"}
}"Run in the UseCase Account (where ML workloads will run):
cd edge-cv-portal
./deploy-account-role.shSelect option 1 for UseCase Account Role.
What gets created:
DDAPortalAccessRole- Cross-account access roleDDASageMakerExecutionRole- For training jobsDDAGroundTruthExecutionRole- For labeling jobs
Save these outputs:
- Role ARN
- External ID (generated automatically)
- SageMaker Execution Role ARN
If storing training data in a separate account:
cd edge-cv-portal
./deploy-account-role.shSelect option 2 for Data Account Role.
What gets created:
DDAPortalDataAccessRole- For Portal to browse data and update bucket policiesDDASageMakerDataAccessRole- For SageMaker cross-account access
Save these outputs:
- Portal Access Role ARN
- External ID
Note: The bucket policy for SageMaker access is automatically configured when you onboard the UseCase in the portal. The Portal assumes the Data Account role and adds the necessary bucket policy statements.
📖 See DATA_ACCOUNT_SETUP.md for detailed scenarios and step-by-step guides.
The portal uses tag-based access. Tag each bucket:
aws s3api put-bucket-tagging \
--bucket YOUR_BUCKET_NAME \
--tagging 'TagSet=[{Key=dda-portal:managed,Value=true}]'Important: Tagging alone is not enough. To upload files from the portal, you must also configure CORS on each bucket.
The portal frontend (running in your browser) uploads files directly to S3 using presigned URLs. This is a "cross-origin" request (from CloudFront to S3), which S3 blocks by default.
- Go to S3 in AWS Console
- Select your bucket
- Go to Permissions tab
- Scroll to Cross-origin resource sharing (CORS) → Click Edit
- Paste this configuration (replace
YOUR_CLOUDFRONT_DOMAIN):
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "PUT", "POST", "HEAD"],
"AllowedOrigins": ["https://YOUR_CLOUDFRONT_DOMAIN"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3000
}
]- Click Save changes
# Replace values
BUCKET_NAME="your-bucket-name"
CLOUDFRONT_DOMAIN="d3qeryypza4i9i.cloudfront.net"
aws s3api put-bucket-cors --bucket $BUCKET_NAME --cors-configuration '{
"CORSRules": [{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "PUT", "POST", "HEAD"],
"AllowedOrigins": ["https://'"$CLOUDFRONT_DOMAIN"'"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3000
}]
}'cd edge-cv-portal
./configure-bucket-cors.sh YOUR_BUCKET_NAME YOUR_CLOUDFRONT_DOMAINaws s3api get-bucket-cors --bucket YOUR_BUCKET_NAMERequired in UseCase Account before training:
- Go to Computer Vision Defect Detection Model
- Click Continue to Subscribe → Accept Offer
- Wait for activation (~2 minutes)
Verify:
aws sagemaker list-algorithms --name-contains "computer-vision-defect-detection"┌─────────────────────────────────────────────────────────────────────────┐
│ USECASE ONBOARDING FLOW │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. Deploy UseCaseAccountStack (in UseCase Account) │
│ └─> Creates: DDAPortalAccessRole, DDASageMakerExecutionRole, │
│ DDAPortalComponentAccessPolicy │
│ │
│ 2. (Optional) Deploy DataAccountStack (in Data Account) │
│ └─> Creates: DDAPortalDataAccessRole │
│ │
│ 3. Create UseCase in Portal UI │
│ └─> Stores: Account IDs, Role ARNs, External IDs │
│ │
│ 4. Provision Shared Components (in Portal) │
│ └─> Creates: Greengrass components in UseCase Account │
│ └─> Updates: S3 bucket policy for cross-account access │
│ │
│ 5. Setup Edge Device (on physical device) │
│ └─> Creates: GreengrassV2TokenExchangeRole │
│ └─> Attaches: DDAPortalComponentAccessPolicy │
│ └─> Tags: Device for portal discovery │
│ │
│ 6. Deploy to Device (in Portal) │
│ └─> Device downloads artifacts from Portal's S3 bucket │
│ │
└─────────────────────────────────────────────────────────────────────────┘
For each user in the customer organization:
aws cognito-idp admin-create-user \
--user-pool-id $USER_POOL_ID \
--username user@customer.com \
--user-attributes Name=email,Value=user@customer.com \
--temporary-password TempPass123!Have the customer run in their AWS account:
./deploy-account-role.sh
# Select option 1 (UseCase Account)
# Enter Portal Account ID when prompted- Login to portal as PortalAdmin
- Go to Use Cases → Create Use Case
- Enter:
- Name: Customer project name
- AWS Account ID: Customer's UseCase Account ID
- Cross-Account Role ARN: From deploy script output
- External ID: From deploy script output
- SageMaker Execution Role ARN: From deploy script output
# Get user's sub
USER_SUB=$(aws cognito-idp admin-get-user \
--user-pool-id $USER_POOL_ID \
--username user@customer.com \
--query 'UserAttributes[?Name==`sub`].Value' --output text)
# Assign to usecase
aws dynamodb put-item \
--table-name edge-cv-portal-user-roles \
--item "{
\"user_id\": {\"S\": \"$USER_SUB\"},
\"usecase_id\": {\"S\": \"<USECASE_ID>\"},
\"role\": {\"S\": \"UseCaseAdmin\"},
\"assigned_at\": {\"N\": \"$(date +%s)000\"},
\"assigned_by\": {\"S\": \"admin\"}
}"Customer runs in their account:
# Tag bucket for portal access
aws s3api put-bucket-tagging \
--bucket training-data-bucket \
--tagging 'TagSet=[{Key=dda-portal:managed,Value=true}]'
# Configure CORS for uploads (replace CLOUDFRONT_DOMAIN)
aws s3api put-bucket-cors --bucket training-data-bucket --cors-configuration '{
"CORSRules": [{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "PUT", "POST", "HEAD"],
"AllowedOrigins": ["https://CLOUDFRONT_DOMAIN"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3000
}]
}'Note: Both tagging AND CORS are required. Tagging enables IAM access; CORS enables browser uploads.
- Navigate to Use Cases → Create Use Case
- Fill in the wizard:
- Basic Info: Name, description, cost center
- AWS Account: Role ARN, External ID, SageMaker Role ARN
- S3 Storage: Bucket name and prefix for outputs
- Data Account Configuration: Choose where training data is stored
| Option | When to Use | What Happens |
|---|---|---|
| Same as UseCase Account | Data is in the same account as SageMaker | No extra role assumption; simplest setup |
| Separate Data Account | Data is in a centralized data lake | Portal assumes Data Account role; SageMaker uses bucket policy |
For Separate Data Account, you'll need:
- Data Account ID
- Data Account Role ARN (
DDAPortalDataAccessRole) - Data Account External ID
- Data S3 Bucket name
**📖 See DATA_ACCOUNT_SETUP.md for detailed setup instructions.
curl -X POST "$API_URL/usecases" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Manufacturing Line 1",
"account_id": "123456789012",
"cross_account_role_arn": "arn:aws:iam::123456789012:role/DDAPortalAccessRole",
"external_id": "UUID-FROM-DEPLOY-SCRIPT",
"sagemaker_execution_role_arn": "arn:aws:iam::123456789012:role/DDASageMakerExecutionRole"
}'If you regenerate the External ID:
aws dynamodb update-item \
--table-name edge-cv-portal-usecases \
--key '{"usecase_id": {"S": "<USECASE_ID>"}}' \
--update-expression "SET external_id = :eid" \
--expression-attribute-values '{":eid": {"S": "<NEW_EXTERNAL_ID>"}}'- Browse S3 buckets tagged with
dda-portal:managed=true - Upload training images via presigned URLs
- Organize data into folders
- Create bounding box labeling jobs
- Monitor labeling progress
- Use pre-labeled datasets for quick starts
- Start SageMaker training jobs using Marketplace algorithm
- Monitor training progress and metrics
- View training logs
- Compile models for edge devices (x86-64, ARM64)
- Target CPU or GPU inference
- Automatic Greengrass component creation
- View portal-created components (tagged
dda-portal:managed=true) - Component versioning
- Deploy to edge devices
- View portal-managed Greengrass core devices (tagged
dda-portal:managed=true) - Monitor device status, installed components, and deployments
- Devices must be set up using
setup_station.shscript
Devices are registered using the setup_station.sh script in the station_install/ folder. This script:
- Installs Python 3.9, Java, Docker, and dependencies
- Downloads and installs AWS IoT Greengrass Core v2
- Creates an IoT Thing and provisions certificates
- Creates
GreengrassV2TokenExchangeRolefor device credentials - Attaches
DDAPortalComponentAccessPolicyfor cross-account S3 access and ECR image pulls - Tags the Greengrass Core Device with
dda-portal:managed=truefor portal discovery
Prerequisites:
- Deploy
UseCaseAccountStackfirst (createsDDAPortalComponentAccessPolicy) - AWS CLI configured on the device with UseCase Account credentials
Setup Command:
cd station_install
sudo ./setup_station.sh <aws-region> <thing-name>
# Example:
sudo ./setup_station.sh us-east-1 manufacturing-line-1-deviceFor Existing Devices (set up before portal tagging):
# Tag the Greengrass Core Device (not IoT Thing)
aws greengrassv2 tag-resource \
--resource-arn arn:aws:greengrass:REGION:ACCOUNT:coreDevices:THING_NAME \
--tags "dda-portal:managed=true"
# Attach the component access policy
aws iam attach-role-policy \
--role-name GreengrassV2TokenExchangeRole \
--policy-arn "arn:aws:iam::ACCOUNT:policy/DDAPortalComponentAccessPolicy"- Create Greengrass deployments
- Target specific devices or groups
- Monitor deployment status
Cause: External ID mismatch between IAM role and DynamoDB.
Fix:
# Check current DynamoDB value
aws dynamodb get-item \
--table-name edge-cv-portal-usecases \
--key '{"usecase_id": {"S": "<ID>"}}'
# Update to match IAM role
aws dynamodb update-item \
--table-name edge-cv-portal-usecases \
--key '{"usecase_id": {"S": "<ID>"}}' \
--update-expression "SET external_id = :eid" \
--expression-attribute-values '{":eid": {"S": "<CORRECT_EXTERNAL_ID>"}}'Cause: AWS Marketplace subscription not active in UseCase Account.
Fix: Subscribe to the algorithm in the UseCase Account (not Portal Account).
Cause: Components not tagged with dda-portal:managed=true.
Fix: Only components created through the portal are shown. Create a new component via the training → compilation workflow.
Cause: Devices not tagged with dda-portal:managed=true or not set up via setup_station.sh.
Fix:
- Ensure the device was set up using
setup_station.sh(which auto-tags) - For existing devices, manually tag them:
aws greengrassv2 tag-resource \
--resource-arn arn:aws:greengrass:REGION:ACCOUNT:coreDevices:THING_NAME \
--tags "dda-portal:managed=true"- Verify the device is a Greengrass Core Device (not just an IoT Thing)
Symptom: Deployment shows FAILED_NO_STATE_CHANGE with "S3 HeadObject returns 403 Access Denied".
Cause: The device's GreengrassV2TokenExchangeRole doesn't have permission to access the Portal Account's component bucket.
Fix:
- Verify
DDAPortalComponentAccessPolicyexists in the UseCase Account:
aws iam get-policy --policy-arn "arn:aws:iam::USECASE_ACCOUNT:policy/DDAPortalComponentAccessPolicy"- If missing, redeploy
UseCaseAccountStack:
cd edge-cv-portal/infrastructure
npm run build
rm -rf cdk.out
cdk deploy -a "npx ts-node bin/usecase-account-app.ts" \
-c portalAccountId=PORTAL_ACCOUNT_ID \
-c externalId=YOUR_EXTERNAL_ID \
--require-approval never- Attach the policy to the device role:
aws iam attach-role-policy \
--role-name GreengrassV2TokenExchangeRole \
--policy-arn "arn:aws:iam::USECASE_ACCOUNT:policy/DDAPortalComponentAccessPolicy"- Verify the Portal's component bucket policy allows the UseCase Account:
aws s3api get-bucket-policy --bucket dda-component-REGION-PORTAL_ACCOUNTThe policy should include both GreengrassV2TokenExchangeRole and greengrass.amazonaws.com service principal.
Symptom: Re-provisioning shared components fails with "Specified artifact resource cannot be accessed".
Cause: The Greengrass service can't validate the S3 artifact during CreateComponentVersion.
Fix: Update the Portal's component bucket policy to include the Greengrass service principal:
# This is automatically done during provisioning, but if it fails:
aws s3api put-bucket-policy --bucket dda-component-REGION-PORTAL_ACCOUNT --policy '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowUseCaseAccountsGreengrassAccess",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::USECASE_ACCOUNT:role/DDAPortalAccessRole",
"arn:aws:iam::USECASE_ACCOUNT:role/GreengrassV2TokenExchangeRole"
]
},
"Action": ["s3:GetObject", "s3:GetObjectVersion", "s3:GetBucketLocation"],
"Resource": [
"arn:aws:s3:::dda-component-REGION-PORTAL_ACCOUNT",
"arn:aws:s3:::dda-component-REGION-PORTAL_ACCOUNT/*"
]
},
{
"Sid": "AllowGreengrassServiceAccess",
"Effect": "Allow",
"Principal": {
"Service": "greengrass.amazonaws.com"
},
"Action": ["s3:GetObject", "s3:GetBucketLocation"],
"Resource": [
"arn:aws:s3:::dda-component-REGION-PORTAL_ACCOUNT",
"arn:aws:s3:::dda-component-REGION-PORTAL_ACCOUNT/*"
],
"Condition": {
"StringEquals": {
"aws:SourceAccount": ["PORTAL_ACCOUNT", "USECASE_ACCOUNT"]
}
}
}
]
}'Cause: Bucket not tagged.
Fix:
aws s3api put-bucket-tagging \
--bucket BUCKET_NAME \
--tagging 'TagSet=[{Key=dda-portal:managed,Value=true}]'Symptom: Browser console shows No 'Access-Control-Allow-Origin' header error.
Cause: S3 bucket CORS not configured for portal uploads.
Fix: Configure CORS on the bucket (see Configure S3 Bucket CORS section above).
Quick CLI fix:
BUCKET="your-bucket"
DOMAIN="your-cloudfront-domain.cloudfront.net"
aws s3api put-bucket-cors --bucket $BUCKET --cors-configuration '{
"CORSRules": [{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "PUT", "POST", "HEAD"],
"AllowedOrigins": ["https://'"$DOMAIN"'"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3000
}]
}'Symptom: SageMaker training job fails with S3 access denied error.
Cause: When using a separate Data Account, the bucket policy doesn't allow the UseCase Account's SageMaker role.
Fix: Deploy (or redeploy) the Data Account stack with the bucket name:
cd edge-cv-portal/infrastructure
cdk deploy -a "npx ts-node bin/data-account-app.ts" \
-c portalAccountId=PORTAL_ID \
-c usecaseAccountIds=USECASE_ID \
-c dataBucketNames=your-data-bucketThis creates a bucket policy allowing DDASageMakerExecutionRole from the UseCase Account to read from the bucket.
Symptom: "No images found" when creating labeling job, but images exist.
Cause: Portal can't assume Data Account role or wrong bucket configured.
Fix:
-
Verify UseCase has correct
data_account_role_arnanddata_s3_bucket:aws dynamodb get-item \ --table-name edge-cv-portal-usecases \ --key '{"usecase_id": {"S": "YOUR_ID"}}' \ --query 'Item.{data_account_id:data_account_id.S, data_s3_bucket:data_s3_bucket.S, data_account_role_arn:data_account_role_arn.S}'
-
Verify External ID matches between DynamoDB and IAM role trust policy
-
Test role assumption manually:
aws sts assume-role \ --role-arn arn:aws:iam::DATA_ACCOUNT:role/DDAPortalDataAccessRole \ --role-session-name test \ --external-id YOUR_EXTERNAL_ID
**📖 See DATA_ACCOUNT_SETUP.md for complete troubleshooting guide.
Cause: Cross-account API calls taking too long.
Fix: Check CloudWatch logs for the specific Lambda function:
aws logs tail /aws/lambda/EdgeCVPortalComputeStack-ComponentsHandler --followThe portal uses a two-layer permission model:
- IDP Role (from Cognito/SSO): Determines global capabilities
- UseCase Assignment (from DynamoDB): Determines which usecases a user can access
| Role | Scope | Description |
|---|---|---|
| PortalAdmin | Global | Super user with full access to all usecases and user management |
| UseCaseAdmin | Per-UseCase | Full access within assigned usecases, can manage team members |
| DataScientist | Per-UseCase | Can create labeling jobs, training jobs, and manage models |
| Operator | Per-UseCase | Can create deployments, manage devices, view logs |
| Viewer | Per-UseCase | Read-only access to view usecases, jobs, models, deployments |
| Action | PortalAdmin | UseCaseAdmin | DataScientist | Operator | Viewer |
|---|---|---|---|---|---|
| UseCase Management | |||||
| Create UseCase | ✅ | ✅ | ✅ | ✅ | ✅ |
| View All UseCases | ✅ | ❌ | ❌ | ❌ | ❌ |
| View Assigned UseCases | ✅ | ✅ | ✅ | ✅ | ✅ |
| Update UseCase | ✅ | ✅ | ❌ | ❌ | ❌ |
| Delete UseCase | ✅ | ❌ | ❌ | ❌ | ❌ |
| Manage Team Members | ✅ | ✅ | ❌ | ❌ | ❌ |
| Labeling | |||||
| Create Labeling Job | ✅ | ✅ | ✅ | ❌ | ❌ |
| View Labeling Jobs | ✅ | ✅ | ✅ | ✅ | ✅ |
| Delete Labeling Job | ✅ | ✅ | ✅ | ❌ | ❌ |
| Training | |||||
| Create Training Job | ✅ | ✅ | ✅ | ❌ | ❌ |
| View Training Jobs | ✅ | ✅ | ✅ | ✅ | ✅ |
| Stop Training Job | ✅ | ✅ | ✅ | ❌ | ❌ |
| Models | |||||
| View Models | ✅ | ✅ | ✅ | ✅ | ✅ |
| Compile Model | ✅ | ✅ | ✅ | ❌ | ❌ |
| Package Model | ✅ | ✅ | ✅ | ❌ | ❌ |
| Publish Component | ✅ | ✅ | ✅ | ❌ | ❌ |
| Delete Model | ✅ | ✅ | ✅ | ❌ | ❌ |
| Deployments | |||||
| Create Deployment | ✅ | ✅ | ❌ | ✅ | ❌ |
| View Deployments | ✅ | ✅ | ✅ | ✅ | ✅ |
| Cancel Deployment | ✅ | ✅ | ❌ | ✅ | ❌ |
| Devices | |||||
| View Devices | ✅ | ✅ | ✅ | ✅ | ✅ |
| Restart Greengrass | ✅ | ✅ | ❌ | ✅ | ❌ |
| Reboot Device | ✅ | ✅ | ❌ | ✅ | ❌ |
| Browse Files | ✅ | ✅ | ❌ | ✅ | ❌ |
| View Logs | ✅ | ✅ | ✅ | ✅ | ✅ |
| Update Config | ✅ | ✅ | ❌ | ✅ | ❌ |
Any authenticated user can create a new usecase. When a user creates a usecase:
- The usecase is created in DynamoDB
- The creator is automatically assigned as UseCaseAdmin for that usecase
- The creator can then add other team members via "Manage Team"
UseCaseAdmins and PortalAdmins can manage team members for their usecases:
- Go to Use Cases page
- Click Actions → Manage Team for the usecase
- Add users by email and assign a role
- Remove users as needed
PortalAdmins have global access to all usecases. This ensures:
- No usecase becomes orphaned if the UseCaseAdmin leaves
- PortalAdmins can reassign admins when needed
- Emergency access is always available
To set a user's IDP role (for PortalAdmin access):
# Set custom:role attribute
aws cognito-idp admin-update-user-attributes \
--user-pool-id us-east-1_jBJ4LzuQ8 \
--username USERNAME \
--user-attributes Name=custom:role,Value=PortalAdminValid role values: PortalAdmin, UseCaseAdmin, DataScientist, Operator, Viewer
- Logs: CloudWatch Logs under
/aws/lambda/EdgeCVPortal* - API Errors: Check browser DevTools Network tab
- Infrastructure:
cdk diffto see pending changes