Google Workspace (GAM)¶
Google Workspace is the primary identity source for CWIQ.
@cwiq.ioaccounts are the SSO identity that flows into Authentik via Google OAuth. GAM7 (Google Apps Manager) provides CLI management of users and groups.
Architecture¶
Google Workspace (@cwiq.io accounts)
│
│ Google OAuth source
▼
Authentik SSO
(sso.shared.cwiq.io)
│
├── SAML → AWS Identity Center → AWS Console
├── OIDC → GitLab, Vault, Grafana, Semaphore
└── Proxy → Icinga, SonarQube
All CWIQ users authenticate to Authentik using their Google Workspace account. Creating a GWS account is always the first step in onboarding. No separate Authentik password is needed — Google handles the credential.
GAM7 Setup¶
GAM7 runs in a Docker container on the Semaphore server (semaphore.shared.cwiq.io). Ansible playbooks in gam/ invoke it for user and group operations.
Authorization¶
# On the Semaphore server, authorize GAM with a GWS admin account
gam oauth create
# Follow prompts to authenticate with admin@cwiq.io
Running GAM Playbooks¶
All GAM playbooks run on localhost via the virtual environment:
User Management¶
Create a Single User¶
ansible-playbook gam/create_user.yml \
-e "user_email=john.doe@cwiq.io" \
-e "user_firstname=John" \
-e "user_lastname=Doe" \
-e "user_password=TempPass123\!"
| Variable | Required | Description |
|---|---|---|
user_email |
Yes | Full @cwiq.io email |
user_firstname |
Yes | First name |
user_lastname |
Yes | Last name |
user_password |
Yes | Temporary password |
user_org |
No | Org unit path (e.g., /Engineering) |
New users are created with changepassword on — they must change their password on first login.
Bulk Create Users¶
CSV format:
email,firstname,lastname,password,org
john.doe@cwiq.io,John,Doe,TempPass123!,/Engineering
jane.smith@cwiq.io,Jane,Smith,TempPass456!,/DevOps
Provide the full absolute path to the CSV file.
Export Users¶
# Export to timestamped file
ansible-playbook gam/export_users.yml
# Export to specific file
ansible-playbook gam/export_users.yml \
-e "output_file=/tmp/cwiq-users-$(date +%Y%m%d).csv"
Group Management¶
Create a Group¶
ansible-playbook gam/create_group.yml \
-e "group_email=engineering@cwiq.io" \
-e "group_name='Engineering Team'" \
-e "group_description='Engineering department'"
Add User to Group¶
ansible-playbook gam/add_user_to_group.yml \
-e "group_email=engineering@cwiq.io" \
-e "user_email=john.doe@cwiq.io" \
-e "role=MEMBER"
Valid roles: MEMBER (default), MANAGER, OWNER.
Bulk Create Groups¶
CSV format:
email,name,description
devops@cwiq.io,DevOps Team,DevOps department
swe@cwiq.io,Software Engineering,SWE department
Export Groups¶
Key GWS Groups¶
These GWS groups integrate with other systems:
| Group | Purpose |
|---|---|
cwiq-io-pilot |
All CWIQ users — added during onboarding, controls GWS app access |
cwiq-io-m365 |
Users with M365 Business Premium license — synced to Azure Entra via SCIM |
The cwiq-io-m365 group is the trigger for M365 license assignment: adding a user to this group in GWS → SCIM sync to Azure Entra → M365 license auto-assigned within minutes.
Onboarding Integration¶
The "Onboard New Hire" Semaphore template (ID 27) calls gam/create_user.yml internally as step 1. Admins typically do not need to run GAM playbooks directly during normal onboarding.
Direct GAM use is appropriate for: - Bulk provisioning (team migrations, new hires in batch) - Exporting user/group lists for audits - Creating GWS groups for new team structures - Edge cases where the Semaphore template is unavailable
Troubleshooting¶
| Symptom | Cause | Fix |
|---|---|---|
| "GAM not authorized" | OAuth token expired | Run gam oauth create from the Semaphore server |
| "CSV file not found" | Relative path provided | Always use absolute file paths |
| "Permission denied" | GWS admin account lacks permissions | Verify admin account has User Management and Group Management permissions in GWS Admin Console |
Related Documentation¶
- Authentik: User Lifecycle — Full onboarding/offboarding flow
- Identity: Azure Entra — M365 license assignment, Azure federation