# g2g-scim-sync
A Python CLI tool that synchronizes Google Workspace users and groups to GitHub Enterprise using SCIM provisioning. Designed for scheduled batch execution via cron.
## Features
- **One-way sync** from Google Workspace to GitHub Enterprise
- **OU-based provisioning** - sync users in specified Google Workspace Organizational Units
- **Individual user sync** - sync specific users outside of OUs (contractors, consultants, etc.)
- **Automatic idP Group creation** - creates missing GitHub idP Groups (teams) from Google OUs
- **OU flattening** - converts nested OUs into individual GitHub idP Groups (teams)
- **User lifecycle management** - handles create, update, suspend, and delete operations
- **Dry run mode** - preview changes without applying them
- **Comprehensive logging** - detailed audit trail for all operations
- **Idempotent operations** - safe to run multiple times
## Requirements
- Python 3.12+
- Google Workspace admin access with service account
- GitHub Enterprise with SCIM API access
- GitHub enterprise account admin permissions
## Installation
```bash
# Clone the repository
git clone https://github.com/gmr/g2g-scim-sync
cd g2g-scim-sync
# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install the package
pip install -e .
```
## Configuration
For detailed setup instructions including Google Workspace and GitHub Enterprise Cloud configuration, see the [complete setup guide](docs/setup-guide.md).
Quick start:
1. Copy the example configuration:
```bash
cp config.example.toml config.toml
```
2. Update `config.toml` with your settings:
- Google service account JSON file path
- Google Workspace domain, subject email, and OUs to sync
- Individual users to sync (optional)
- GitHub Enterprise hostname, SCIM token, and enterprise account name
- Sync and logging preferences
## Usage
### Basic Sync
```bash
g2g-scim-sync --config config.toml
```
### Dry Run (Preview Changes)
```bash
g2g-scim-sync --config config.toml --dry-run
```
### Force Delete Suspended Users
```bash
g2g-scim-sync --config config.toml --delete-suspended
```
### Sync Specific OUs Only
```bash
g2g-scim-sync --config config.toml --organizational-units "/Engineering,/Sales"
```
### Sync Individual Users Only
```bash
g2g-scim-sync --config config.toml --individual-users "contractor@company.com,consultant@company.com"
```
### Verbose Logging
```bash
g2g-scim-sync --config config.toml --verbose
```
## How It Works
1. **Fetch**: Retrieves users from specified Google OUs and individual users via Admin SDK
2. **Flatten**: Processes nested OU memberships into flat idP Group structure (optional)
3. **Compare**: Diffs current GitHub users/idP Groups via SCIM API
4. **Provision**: Applies changes (users and idP Groups) via SCIM API
5. **Log**: Records all operations for audit trail
## User Lifecycle
- **New Users**: Provisioned on next sync run
- **Updates**: Attribute changes synchronized each run
- **Suspensions**: Suspended Google users become inactive in GitHub
- **Deletions**: Immediate deprovisioning (requires `--delete-suspended`)
## idP Group Management
- Google OUs are flattened into individual GitHub idP Groups (configurable)
- idP Group names use OU names as-is (e.g., "Engineering" → "engineering")
- Missing GitHub idP Groups are created automatically
- Nested group memberships cascade (removing from parent removes from children)
## Development
```bash
# Install development dependencies
pip install -e .[dev]
# Set up pre-commit hooks
pre-commit install
# Run tests
pytest
# Run tests with coverage
pytest --cov=g2g_scim_sync --cov-report=html
# Format code
ruff format
# Lint code
ruff check
```
## License
BSD-3-Clause License. See [LICENSE](LICENSE) file for details.
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes with tests
4. Ensure tests pass and coverage is maintained
5. Submit a pull request
## Support
- Create an issue on GitHub for bugs or feature requests
- Check existing issues before creating new ones
- Provide detailed information including logs and configuration (sanitized)
Raw data
{
"_id": null,
"home_page": null,
"name": "g2g-scim-sync",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "github-enterprise, google-workspace, identity-management, provisioning, scim",
"author": null,
"author_email": "\"Gavin M. Roy\" <gavinr@aweber.com>",
"download_url": "https://files.pythonhosted.org/packages/28/b4/e0ed43c60839303fb161ac1a546f87f02e57f61ea43c58a0a01cb01dd4d0/g2g_scim_sync-1.0.0.tar.gz",
"platform": null,
"description": "# g2g-scim-sync\n\nA Python CLI tool that synchronizes Google Workspace users and groups to GitHub Enterprise using SCIM provisioning. Designed for scheduled batch execution via cron.\n\n## Features\n\n- **One-way sync** from Google Workspace to GitHub Enterprise\n- **OU-based provisioning** - sync users in specified Google Workspace Organizational Units\n- **Individual user sync** - sync specific users outside of OUs (contractors, consultants, etc.)\n- **Automatic idP Group creation** - creates missing GitHub idP Groups (teams) from Google OUs\n- **OU flattening** - converts nested OUs into individual GitHub idP Groups (teams)\n- **User lifecycle management** - handles create, update, suspend, and delete operations\n- **Dry run mode** - preview changes without applying them\n- **Comprehensive logging** - detailed audit trail for all operations\n- **Idempotent operations** - safe to run multiple times\n\n## Requirements\n\n- Python 3.12+\n- Google Workspace admin access with service account\n- GitHub Enterprise with SCIM API access\n- GitHub enterprise account admin permissions\n\n## Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/gmr/g2g-scim-sync\ncd g2g-scim-sync\n\n# Create virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate # On Windows: .venv\\Scripts\\activate\n\n# Install the package\npip install -e .\n```\n\n## Configuration\n\nFor detailed setup instructions including Google Workspace and GitHub Enterprise Cloud configuration, see the [complete setup guide](docs/setup-guide.md).\n\nQuick start:\n\n1. Copy the example configuration:\n ```bash\n cp config.example.toml config.toml\n ```\n\n2. Update `config.toml` with your settings:\n - Google service account JSON file path\n - Google Workspace domain, subject email, and OUs to sync\n - Individual users to sync (optional)\n - GitHub Enterprise hostname, SCIM token, and enterprise account name\n - Sync and logging preferences\n\n## Usage\n\n### Basic Sync\n```bash\ng2g-scim-sync --config config.toml\n```\n\n### Dry Run (Preview Changes)\n```bash\ng2g-scim-sync --config config.toml --dry-run\n```\n\n### Force Delete Suspended Users\n```bash\ng2g-scim-sync --config config.toml --delete-suspended\n```\n\n### Sync Specific OUs Only\n```bash\ng2g-scim-sync --config config.toml --organizational-units \"/Engineering,/Sales\"\n```\n\n### Sync Individual Users Only\n```bash\ng2g-scim-sync --config config.toml --individual-users \"contractor@company.com,consultant@company.com\"\n```\n\n### Verbose Logging\n```bash\ng2g-scim-sync --config config.toml --verbose\n```\n\n## How It Works\n\n1. **Fetch**: Retrieves users from specified Google OUs and individual users via Admin SDK\n2. **Flatten**: Processes nested OU memberships into flat idP Group structure (optional)\n3. **Compare**: Diffs current GitHub users/idP Groups via SCIM API\n4. **Provision**: Applies changes (users and idP Groups) via SCIM API\n5. **Log**: Records all operations for audit trail\n\n## User Lifecycle\n\n- **New Users**: Provisioned on next sync run\n- **Updates**: Attribute changes synchronized each run\n- **Suspensions**: Suspended Google users become inactive in GitHub\n- **Deletions**: Immediate deprovisioning (requires `--delete-suspended`)\n\n## idP Group Management\n\n- Google OUs are flattened into individual GitHub idP Groups (configurable)\n- idP Group names use OU names as-is (e.g., \"Engineering\" \u2192 \"engineering\")\n- Missing GitHub idP Groups are created automatically\n- Nested group memberships cascade (removing from parent removes from children)\n\n## Development\n\n```bash\n# Install development dependencies\npip install -e .[dev]\n\n# Set up pre-commit hooks\npre-commit install\n\n# Run tests\npytest\n\n# Run tests with coverage\npytest --cov=g2g_scim_sync --cov-report=html\n\n# Format code\nruff format\n\n# Lint code\nruff check\n```\n\n## License\n\nBSD-3-Clause License. See [LICENSE](LICENSE) file for details.\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes with tests\n4. Ensure tests pass and coverage is maintained\n5. Submit a pull request\n\n## Support\n\n- Create an issue on GitHub for bugs or feature requests\n- Check existing issues before creating new ones\n- Provide detailed information including logs and configuration (sanitized)\n",
"bugtrack_url": null,
"license": "BSD-3-Clause",
"summary": "Google Workspace to GitHub Enterprise SCIM synchronization tool",
"version": "1.0.0",
"project_urls": {
"Bug Tracker": "https://github.com/gmr/g2g-scim-sync/issues",
"Documentation": "https://github.com/gmr/g2g-scim-sync",
"Homepage": "https://github.com/gmr/g2g-scim-sync",
"Repository": "https://github.com/gmr/g2g-scim-sync"
},
"split_keywords": [
"github-enterprise",
" google-workspace",
" identity-management",
" provisioning",
" scim"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "cfbef2489a5c35c06aa3dd11c5c94f06130f003223115d6afbe32be6f93fe8f5",
"md5": "2fe5e0139af45cd86f04169986e06a03",
"sha256": "8bfd9d02ffe9df99f1a53163c463872535afd3e0d061a0227016ec3530c59cc0"
},
"downloads": -1,
"filename": "g2g_scim_sync-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "2fe5e0139af45cd86f04169986e06a03",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 22244,
"upload_time": "2025-08-13T19:53:34",
"upload_time_iso_8601": "2025-08-13T19:53:34.087313Z",
"url": "https://files.pythonhosted.org/packages/cf/be/f2489a5c35c06aa3dd11c5c94f06130f003223115d6afbe32be6f93fe8f5/g2g_scim_sync-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "28b4e0ed43c60839303fb161ac1a546f87f02e57f61ea43c58a0a01cb01dd4d0",
"md5": "b75326bb7b6503fba69e261a6ecb050b",
"sha256": "bdcb3c7318d5d0a11378630f7353c7616112a855b4f9b9d3240b11f6673d1732"
},
"downloads": -1,
"filename": "g2g_scim_sync-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "b75326bb7b6503fba69e261a6ecb050b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 40343,
"upload_time": "2025-08-13T19:53:35",
"upload_time_iso_8601": "2025-08-13T19:53:35.579860Z",
"url": "https://files.pythonhosted.org/packages/28/b4/e0ed43c60839303fb161ac1a546f87f02e57f61ea43c58a0a01cb01dd4d0/g2g_scim_sync-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-13 19:53:35",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "gmr",
"github_project": "g2g-scim-sync",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "g2g-scim-sync"
}