A collection of tools for managing Google Workspace (formerly G Suite), with both GAM (bash) and Python (Admin SDK) implementations.
This repository contains tools for:
- Calendar management - Delete events for specific users
- Groups management - Search and manage groups, including dynamic groups
- User management - Update employee types, list users, automated syncing
- Schema management - Manage custom user attributes/fields
New: See docs/GOOGLE_WORKSPACE_CONFIGURATION.md for comprehensive documentation of the Keboola Google Workspace setup, including all customizations, groups, security policies, and integrations.
Each category may contain multiple implementations:
- GAM (bash) - Traditional bash scripts using GAM command-line tool
- Python - Modern Python scripts using Google Workspace Admin SDK (cloud-ready)
The Python sync script (users/python/set_employee_type.py) follows this logic:
What it does:
- Scans users in
/-adminsOU → Sets their Type of employee to "Admin Account" - Scans users in
/-service-accountsOU → Sets their Type of employee to "Service Account" - Only updates users whose Type doesn't match (efficient, skips already-correct users)
What it does NOT do:
- ❌ Does NOT touch users outside these OUs
- ❌ Does NOT clear/unset Type for users who leave the OUs
- ❌ Does NOT delete or modify users
Why this matters:
This script is OU-aware and additive only. If you move a user OUT of /-admins or /-service-accounts, their Type of employee will remain set (won't be automatically cleared). This is intentional to prevent accidental data loss.
If you need cleanup: Create a separate script to handle users who move out of these OUs. The sync script focuses only on ensuring users IN the specified OUs have the correct Type set.
-
Install GAM (Google Apps Manager):
# For macOS (using Homebrew) brew install gam # For Linux sudo apt-get install gam # Debian/Ubuntu sudo yum install gam # RHEL/CentOS
-
Verify GAM installation:
gam version
-
Configure GAM with your Google Workspace admin account:
gam oauth create
-
Test GAM access:
gam info user
- Bash shell
- Google Workspace admin access
- Python 3.6+ (required by GAM)
- Clone this repository:
git clone https://github.com/yourusername/google-workspace-admin-tools.git
cd google-workspace-admin-tools- Configure your organization settings:
# Copy the example configuration: cp config/org-config.example.sh config/org-config.sh # Edit `config/org-config.sh` with your organization's settings: # Organization Settings ORG_DOMAIN="your-domain.com" ORG_NAME="Your Organization Name" ORG_UNIT_ROOT="/External Users" # Root OU for external users # External Organization OUs ORG_UNIT_EXTERNALS="/External Users" # Main external users OU ORG_UNIT_GENEEA="/External Users/External Org 1" # First external organization ORG_UNIT_NETHOST="/External Users/External Org 2" # Second external organization ORG_UNIT_REVOLGY="/External Users/External Org 3" # Third external organization # Calendar Settings CALENDAR_ID="your-calendar-id@group.calendar.google.com"
Delete calendar events (GAM):
./calendar/delete-events.sh --from-date YYYY-MM-DD user@email.comOptions:
--dry-run: Show what would be deleted without actually deleting--from-date: Specify start date for event deletion (YYYY-MM-DD format)--help: Show usage information
Find group by email (GAM):
./groups/find-group-by-email.sh user@email.comList users:
./users/gam/list-users.shUpdate contractor types:
./users/gam/update-contractor-type.shUpdate employee type for specific user:
./users/gam/update-employee-type.sh user@email.com "Employee Type"Automated employee type sync:
cd users/python
# Test on staging first (always!)
python set_employee_type.py --env staging --dry-run
# Run on staging
python set_employee_type.py --env staging
# Run on production (when explicitly needed)
python set_employee_type.py --env productionThe --env flag is mandatory and selects between staging/production credentials.
See users/python/README.md for complete Python deployment guide (Cloud Functions, Cloud Run, etc.)
Manage custom user attributes (Python):
# List all custom schemas
python schemas/manage_custom_schemas.py --env staging --action list
# Create a schema (dry-run first)
python schemas/manage_custom_schemas.py --env staging --action create --schema Custom_Employee_Information --dry-run
# Create for real
python schemas/manage_custom_schemas.py --env staging --action create --schema Custom_Employee_Information
# Get schema details
python schemas/manage_custom_schemas.py --env staging --action get --schema Custom_Employee_Information
# Delete a schema
python schemas/manage_custom_schemas.py --env production --action delete --schema Old_Schema_NameSee schemas/README.md for complete schema management guide.
google-workspace-admin-tools/
├── calendar/ # Calendar management tools
│ └── delete-events.sh # Delete calendar events (GAM)
├── groups/ # Groups management tools
│ └── find-group-by-email.sh # Search for groups (GAM)
├── users/ # User management tools
│ ├── gam/ # GAM (bash) implementations
│ │ ├── list-users.sh
│ │ ├── update-contractor-type.sh
│ │ └── update-employee-type.sh
│ └── python/ # Python (Admin SDK) implementations
│ ├── set_employee_type.py # Main script
│ ├── keboola_component_sync_employee_types.py # Keboola wrapper
│ ├── requirements.txt
│ ├── README.md # Deployment guide
│ └── service-account.json.example
├── schemas/ # Custom schema management
│ ├── manage_custom_schemas.py # Schema CRUD operations
│ └── README.md # Schema documentation
├── config/ # Configuration files
│ ├── environments.py # Environment-to-credential mapping
│ ├── group_definitions.py # Dynamic group definitions
│ ├── schema_definitions.py # Custom schema definitions
│ ├── gam-config.sh
│ └── org-config.sh.template
├── credentials/ # Service account JSON files (git-ignored)
├── docs/ # Documentation
│ └── GOOGLE_WORKSPACE_CONFIGURATION.md # GWS setup documentation
├── LICENSE
└── README.md
- GAM scripts - Quick, traditional approach. Great for local/manual tasks
- Python scripts - Cloud-native, automated. Deploy to Cloud Functions, Cloud Run, etc.
This README serves as the primary documentation for AI agents (Claude, Gemini, etc.) working on this codebase.
Key Architecture Principles:
- Organization by function - Tools are grouped by what they manage (calendar, groups, users)
- Multiple implementations - GAM (bash) for manual/local, Python for cloud/automation
- OU-driven logic - Python sync only sets Types for users IN specified OUs, never clears
- Configuration-driven - All paths and settings in
config/directory - Service account authentication - Python uses domain-wide delegation for API access
When extending this repository:
- Add new categories as top-level directories (e.g.,
drives/,devices/) - Provide both GAM and Python implementations where applicable
- Document OU-based logic clearly if scripts are OU-aware
- Never auto-remove or clear data - make scripts additive only
- Always support dry-run mode for testing
- Use
--envflag pattern for environment selection (staging/production)
When working with custom schemas:
- Schema definitions are in
config/schema_definitions.py- this is the source of truth - Schemas must be identical on staging and production
- Always test schema changes on staging first
- You cannot modify existing schemas via API - must delete and recreate
- Deleting a schema removes all user data in those fields - confirm with user first
- Use
--dry-runbefore any schema modifications
When creating Keboola components:
- Create a single wrapper file:
keboola_component_{script_name}.py - Use
keboola.component.CommonInterfacefor configuration - Read parameters from
ci.configuration.parameters - Service account handling: Accept as encrypted parameter
#service_account_json(can be string OR object), write to temp file - Handle both string and dict formats: Keboola may pass JSON as parsed object or raw string
- Never expect service account files in
/data/in/files/- code is deployed from public GitHub! - Set environment variables for the main script
- Write state file with
ci.write_state_file()for monitoring - Handle errors with proper exit codes (0=success, 1=config error, 2=runtime error)
- Clean up temporary files in
finallyblock - Document parameters in the main README with table format (including
#service_account_json) - Keep wrapper simple - just configuration and execution bridge
- Add
requirements.txtto repo root - Keboola only reads from root for git source
Using Keboola MCP to manage components:
- Use
mcp__keboola__get_jobsto check job status and errors - Use
mcp__keboola__run_jobto trigger component execution - Use
mcp__keboola__get_configsto list and inspect configurations - Use
mcp__keboola__update_configto modify configuration parameters - Use
mcp__keboola__create_configto create new configurations - Always check job logs after errors:
mcp__keboola__get_jobs --job_ids '["JOB_ID"]'
OAuth Scopes Required for Python Scripts:
https://www.googleapis.com/auth/admin.directory.user
https://www.googleapis.com/auth/admin.directory.orgunit
https://www.googleapis.com/auth/admin.directory.userschema
https://www.googleapis.com/auth/cloud-identity.groups
Custom schemas define additional fields for user profiles in Google Workspace.
| Field | Type | Access | Description |
|---|---|---|---|
| Account_Type | STRING | ADMINS_AND_SELF | Type of account (e.g., Admin, Service) |
| Division | STRING | ADMINS_AND_SELF | Division or department |
This schema is defined in config/schema_definitions.py and should be identical on both staging and production.
If you need to set up a new Google Workspace environment (or recreate after deletion):
-
Ensure OAuth scope is configured in Admin Console:
- Security > API Controls > Domain-wide Delegation
- Add scope:
https://www.googleapis.com/auth/admin.directory.userschema
-
Create the schema:
python schemas/manage_custom_schemas.py --env staging --action create --schema Custom_Employee_Information
-
Verify creation:
python schemas/manage_custom_schemas.py --env staging --action get --schema Custom_Employee_Information
- Edit
config/schema_definitions.py - Add fields to the schema definition
- Note: You cannot modify existing schemas via API - you must delete and recreate
| Environment | Domain | Admin Email | Credential File |
|---|---|---|---|
| staging | test.keboola.com | admin-jiri.manas@test.keboola.com | credentials/service-account-staging.json |
| production | keboola.com | admin-jiri.manas@keboola.com | credentials/service-account-production.json |
All Python scripts use the mandatory --env flag to select the environment.
Service account JSON files are stored in 1Password (search for "Google Workspace Admin Tools" or "GWS service account").
To set up locally:
- Download the service account JSON from 1Password
- Save to
credentials/service-account-staging.jsonorcredentials/service-account-production.json - These files are git-ignored and must never be committed
The service accounts must have these scopes authorized via domain-wide delegation in Google Workspace Admin Console:
| Scope | Purpose |
|---|---|
https://www.googleapis.com/auth/admin.directory.user |
Read/write user profiles |
https://www.googleapis.com/auth/admin.directory.orgunit |
Read organizational units |
https://www.googleapis.com/auth/admin.directory.userschema |
Manage custom user schemas |
https://www.googleapis.com/auth/cloud-identity.groups |
Manage dynamic groups |
To configure domain-wide delegation:
- Go to Google Workspace Admin Console
- Navigate to Security > API Controls > Domain-wide Delegation
- Find the service account (by Client ID) or add it
- Add all four scopes listed above
- Click Authorize
Note: Each environment (staging/production) has its own service account that must be configured separately in its respective Admin Console.
-
If GAM command is not found:
# Check if GAM is in PATH which gam # If not found, add GAM to PATH in your shell profile echo 'export PATH="$PATH:/path/to/gam"' >> ~/.bashrc # or ~/.zshrc source ~/.bashrc # or source ~/.zshrc
-
If GAM authentication fails:
# Re-authenticate GAM gam oauth delete gam oauth create
-
If scripts fail with "configuration not found":
# Make sure you've copied and configured the org-config.sh file cp config/org-config.sh.template config/org-config.sh nano config/org-config.sh -
If organization unit paths are incorrect:
# List all organization units to find the correct paths gam print orgs
- Fork the repository
- Create your feature branch
- Commit your changes
- Push to the branch
- Create a new Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.