User Management¶
This guide covers creating and managing users in SYNDI systems, including Cognito user administration, group management, and password policies.
Overview¶
SYNDI uses AWS Cognito User Pools for user management, with each organization having its own isolated User Pool. Users are assigned to groups that determine their permissions.
See RBAC System for detailed information about roles and permissions.
User Groups¶
SYNDI provides four core groups:
Group |
Permissions |
Description |
|---|---|---|
ADMINS |
All ( |
System administrators with full access |
LAB_MANAGERS |
Submit, view, approve |
Lab oversight and SOP approval |
RESEARCHERS |
Submit, view own/group, drafts |
Laboratory work and data entry |
CLINICIANS |
Submit, view own |
Clinical data entry |
Note: Current template.yaml creates these groups: ADMINS, LAB_MANAGERS, RESEARCHERS, CLINICIANS (not the legacy admin/researcher/viewer names).
Creating Users¶
During Deployment (Automated)¶
Create an admin user automatically during deployment:
# Deploy with admin user creation
ENABLE_AUTH=true CREATE_BUCKETS=true \
ADMIN_USERNAME=admin@myorg.com \
ADMIN_PASSWORD=SecurePassword2025! \
ORG=myorg ENV=stage make rs-deploy
This automatically:
Creates Cognito user with email as username
Ensures ADMINS group exists
Adds user to ADMINS group
Sets permanent password (no temp password)
Tests authentication
Displays success confirmation
Via AWS CLI¶
Create users manually after deployment:
# Get User Pool ID from CloudFormation
USER_POOL_ID=$(aws cloudformation describe-stacks \
--stack-name rawscribe-stage-myorg \
--query 'Stacks[0].Outputs[?OutputKey==`CognitoUserPoolId`].OutputValue' \
--output text)
# Create user
aws cognito-idp admin-create-user \
--user-pool-id ${USER_POOL_ID} \
--username researcher1@myorg.com \
--user-attributes Name=email,Value=researcher1@myorg.com Name=name,Value="Jane Researcher" \
--temporary-password TempPass123! \
--message-action SUPPRESS \
--region us-east-1
# Add to RESEARCHERS group
aws cognito-idp admin-add-user-to-group \
--user-pool-id ${USER_POOL_ID} \
--username researcher1@myorg.com \
--group-name RESEARCHERS \
--region us-east-1
# Set permanent password
aws cognito-idp admin-set-user-password \
--user-pool-id ${USER_POOL_ID} \
--username researcher1@myorg.com \
--password ResearcherPass123! \
--permanent \
--region us-east-1
Via AWS Console¶
Navigate to Amazon Cognito
Select your User Pool (
rawscribe-{env}-{org}-userpool)Click “Create user”
Fill in email and temporary password
Select “Send invitation” or “Mark as confirmed”
After creation, add user to appropriate group
Managing User Groups¶
Available Groups¶
Groups are automatically created during deployment when ENABLE_AUTH=true:
# Groups created by template.yaml:
ADMINS # Precedence 1 - Full system access
LAB_MANAGERS # Precedence 2 - Lab oversight
RESEARCHERS # Precedence 3 - Data entry and submission
CLINICIANS # Precedence 4 - Clinical data entry
Add User to Group¶
aws cognito-idp admin-add-user-to-group \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--group-name RESEARCHERS \
--region us-east-1
Remove User from Group¶
aws cognito-idp admin-remove-user-from-group \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--group-name RESEARCHERS \
--region us-east-1
List User’s Groups¶
aws cognito-idp admin-list-groups-for-user \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--region us-east-1
List All Users in Group¶
aws cognito-idp list-users-in-group \
--user-pool-id ${USER_POOL_ID} \
--group-name RESEARCHERS \
--region us-east-1
Password Management¶
Password Policy¶
Cognito User Pools are configured with strong password requirements (from template.yaml):
Minimum Length: 8 characters
Requires: Uppercase, lowercase, numbers, symbols
Enforced by: Cognito automatically
Set User Password¶
# Set permanent password
aws cognito-idp admin-set-user-password \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--password NewSecurePass123! \
--permanent \
--region us-east-1
Reset Password¶
# Generate new temporary password
aws cognito-idp admin-reset-user-password \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--region us-east-1
# User must change on next login
Force Password Change¶
# Require password change on next login
aws cognito-idp admin-create-user \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--user-attributes Name=email,Value=user@myorg.com \
--desired-delivery-mediums EMAIL \
--region us-east-1
User Lifecycle Management¶
Enable/Disable Users¶
# Disable user (prevents login)
aws cognito-idp admin-disable-user \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--region us-east-1
# Enable user
aws cognito-idp admin-enable-user \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--region us-east-1
Delete Users¶
# Permanently delete user
aws cognito-idp admin-delete-user \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--region us-east-1
⚠️ Warning: Deletion is permanent. User data (ELN submissions) in S3 is NOT deleted.
List All Users¶
# List all users in pool
aws cognito-idp list-users \
--user-pool-id ${USER_POOL_ID} \
--region us-east-1
# With specific attributes
aws cognito-idp list-users \
--user-pool-id ${USER_POOL_ID} \
--region us-east-1 \
--attributes-to-get email name
Get User Details¶
# Get complete user information
aws cognito-idp admin-get-user \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--region us-east-1
Bulk User Management¶
Create Multiple Users¶
Create a script for bulk user creation:
#!/bin/bash
# bulk-create-users.sh
USER_POOL_ID="us-east-1_ABC123"
GROUP="RESEARCHERS"
# Read from CSV or array
USERS=(
"researcher1@myorg.com:Jane Researcher"
"researcher2@myorg.com:John Researcher"
"researcher3@myorg.com:Bob Researcher"
)
for user in "${USERS[@]}"; do
EMAIL="${user%%:*}"
NAME="${user##*:}"
echo "Creating user: $EMAIL"
aws cognito-idp admin-create-user \
--user-pool-id ${USER_POOL_ID} \
--username "$EMAIL" \
--user-attributes Name=email,Value="$EMAIL" Name=name,Value="$NAME" \
--temporary-password TempPass123! \
--message-action SUPPRESS \
--region us-east-1
aws cognito-idp admin-add-user-to-group \
--user-pool-id ${USER_POOL_ID} \
--username "$EMAIL" \
--group-name "$GROUP" \
--region us-east-1
echo "✅ Created $EMAIL"
done
Export Users¶
Export user list for backup:
# Export to JSON
aws cognito-idp list-users \
--user-pool-id ${USER_POOL_ID} \
--region us-east-1 > users-backup-$(date +%Y%m%d).json
# Export just usernames and emails
aws cognito-idp list-users \
--user-pool-id ${USER_POOL_ID} \
--region us-east-1 \
--query 'Users[].[Username, Attributes[?Name==`email`].Value | [0]]' \
--output table
Username Requirements¶
Format Rules¶
Must be: Valid email address
No hyphens: Hyphens conflict with filesystem delimiters
Case sensitive:
User@org.com≠user@org.comUnique: Per User Pool (org-specific isolation)
Valid Usernames¶
✅ admin@myorg.com
✅ researcher1@myorg.com
✅ jane.researcher@myorg.com
✅ jane_researcher@myorg.com
Invalid Usernames¶
❌ user-with-hyphens@myorg.com # No hyphens allowed
❌ user@org # Not a valid email
❌ user_only # Must be email format
Role Assignment Best Practices¶
Principle of Least Privilege¶
Start with the minimum permissions needed:
New user → RESEARCHERS or CLINICIANS
Team lead → LAB_MANAGERS
IT admin → ADMINS (sparingly)
Role Assignment Guidelines¶
Assign ADMINS when:
User needs system configuration access
User manages other users
User troubleshoots system issues
User needs unrestricted data access
Assign LAB_MANAGERS when:
User oversees laboratory operations
User needs to approve submissions
User manages team members
User requires broad data visibility
Assign RESEARCHERS when:
User actively conducts laboratory work
User needs to submit ELN data
User works in collaborative teams
User uploads experimental files
Assign CLINICIANS when:
User performs clinical data entry
User needs to submit clinical forms
User should only see own data
User has limited system interaction
Multiple Groups¶
Users can belong to multiple groups:
# Add user to multiple groups
aws cognito-idp admin-add-user-to-group \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--group-name RESEARCHERS
aws cognito-idp admin-add-user-to-group \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--group-name LAB_MANAGERS
Permission resolution: User gets combined permissions from all groups.
Security Considerations¶
Password Security¶
Strong Passwords: Enforce minimum 8 characters with complexity
Regular Rotation: Encourage users to change passwords quarterly
No Sharing: Each user must have individual account
Temporary Passwords: Require change on first login
Account Security¶
Regular Audits: Review user list quarterly
Disable Inactive Users: Disable users who haven’t logged in for 90+ days
Remove Departed Users: Delete accounts promptly when users leave
Monitor Failed Logins: Set up CloudWatch alarms for failed auth attempts
Access Control¶
Least Privilege: Assign minimum required role
Group-Based: Use groups, not individual permissions
Regular Reviews: Audit group membership quarterly
Separation of Duties: Admins shouldn’t be the only researchers
Troubleshooting¶
User Cannot Login¶
Symptoms:
“Incorrect username or password”
“User does not exist”
Solutions:
# Check if user exists
aws cognito-idp admin-get-user \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--region us-east-1
# Check user status
aws cognito-idp admin-get-user \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--query 'UserStatus' \
--region us-east-1
# Possible statuses:
# - UNCONFIRMED: User needs to confirm email
# - CONFIRMED: User can login
# - FORCE_CHANGE_PASSWORD: User must change temp password
# - RESET_REQUIRED: Admin reset password
“User is disabled”¶
Solution:
# Enable the user
aws cognito-idp admin-enable-user \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--region us-east-1
“Invalid password format”¶
Cause: Password doesn’t meet policy requirements
Solution: Ensure password has:
At least 8 characters
Uppercase letter
Lowercase letter
Number
Symbol
User Has Wrong Permissions¶
Check user’s groups:
aws cognito-idp admin-list-groups-for-user \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--region us-east-1
Fix:
# Add to correct group
aws cognito-idp admin-add-user-to-group \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--group-name RESEARCHERS
# Remove from wrong group
aws cognito-idp admin-remove-user-from-group \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--group-name CLINICIANS
Finding Resources¶
Discover User Pool¶
# Find User Pool by organization
ENV=stage
ORG=myorg
USER_POOL_ID=$(aws cognito-idp list-user-pools --max-results 60 \
--query "UserPools[?contains(Name,'rawscribe-${ENV}-${ORG}')].Id | [0]" \
--output text --region us-east-1)
echo "User Pool ID: ${USER_POOL_ID}"
Using Makefile¶
# Show User Pool ID
make show-rs-user-pool ENV=stage ORG=myorg
# Show Client ID
make show-rs-client-id ENV=stage ORG=myorg
Advanced User Management¶
Custom Attributes¶
Store additional user metadata:
# Create user with custom attributes
aws cognito-idp admin-create-user \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--user-attributes \
Name=email,Value=user@myorg.com \
Name=name,Value="User Name" \
Name=custom:department,Value="Biochemistry" \
Name=custom:lab_id,Value="LAB-001" \
--region us-east-1
Note: Custom attributes must be defined in User Pool schema (see template.yaml).
Update User Attributes¶
# Update user's name
aws cognito-idp admin-update-user-attributes \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--user-attributes Name=name,Value="New Name" \
--region us-east-1
User Status Management¶
# Confirm user (skip email verification)
aws cognito-idp admin-confirm-sign-up \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--region us-east-1
# Check last login
aws cognito-idp admin-get-user \
--user-pool-id ${USER_POOL_ID} \
--username user@myorg.com \
--query 'UserLastModifiedDate' \
--region us-east-1
User Management Scripts¶
Complete User Creation Script¶
#!/bin/bash
# create-user.sh
set -e
# Parameters
USER_POOL_ID="${1}"
EMAIL="${2}"
GROUP="${3:-RESEARCHERS}"
PASSWORD="${4}"
if [ -z "$PASSWORD" ]; then
echo "Usage: $0 <user-pool-id> <email> <group> <password>"
exit 1
fi
echo "Creating user $EMAIL in group $GROUP..."
# Create user
aws cognito-idp admin-create-user \
--user-pool-id ${USER_POOL_ID} \
--username "$EMAIL" \
--user-attributes Name=email,Value="$EMAIL" \
--temporary-password TempPass123! \
--message-action SUPPRESS \
--region us-east-1
# Add to group
aws cognito-idp admin-add-user-to-group \
--user-pool-id ${USER_POOL_ID} \
--username "$EMAIL" \
--group-name "$GROUP" \
--region us-east-1
# Set permanent password
aws cognito-idp admin-set-user-password \
--user-pool-id ${USER_POOL_ID} \
--username "$EMAIL" \
--password "$PASSWORD" \
--permanent \
--region us-east-1
echo "✅ User $EMAIL created successfully"
Usage:
./create-user.sh us-east-1_ABC123 researcher@myorg.com RESEARCHERS Pass123!
Best Practices¶
User Naming¶
Use email addresses - Clear, unique, professional
Organizational domains -
user@myorg.compatternRole indicators -
admin@myorg.com,researcher1@myorg.comNo generic names - Avoid
admin,test,user
Group Management¶
Use standard groups - ADMINS, LAB_MANAGERS, RESEARCHERS, CLINICIANS
Assign sparingly - Not everyone needs ADMINS
Document assignments - Keep track of who has what role
Review regularly - Quarterly group membership audits
Password Management¶
Strong passwords - Meet policy requirements
Unique passwords - Different from other systems
Secure storage - Use password manager
Regular rotation - Change quarterly for sensitive roles
No sharing - Each person gets own account
Audit Trail¶
CloudTrail logging - Enabled automatically for Cognito
Regular reviews - Check authentication logs
Monitor failures - Alert on repeated failed logins
Track changes - Review user/group modifications
Multi-Organization Considerations¶
User Isolation¶
Users are completely isolated between organizations:
User
admin@org1.comin org1’s User PoolUser
admin@org2.comin org2’s User PoolCannot share users between orgs
Cannot authenticate across orgs
Cross-Organization Users¶
If someone needs access to multiple organizations:
# Create separate account in each org
# Org 1
aws cognito-idp admin-create-user \
--user-pool-id ${ORG1_POOL_ID} \
--username user@org1.com \
--region us-east-1
# Org 2
aws cognito-idp admin-create-user \
--user-pool-id ${ORG2_POOL_ID} \
--username user@org2.com \
--region us-east-1