项目作者: github

项目描述 :
Sync GitHub teams to groups in Active Directory, LDAP, Okta, OneLogin or AzureAD when using any authentication method for GitHub.
高级语言: Python
项目地址: git://github.com/github/github-team-sync.git
创建时间: 2018-11-12T17:51:40Z
项目社区:https://github.com/github/github-team-sync

开源协议:MIT License

下载


GitHub Team Sync

This utility is intended to enable synchronization between GitHub and various LDAP and SAML providers.
This is particularly useful for large organizations with many teams that either use GitHub Enterprise Cloud,
do not use LDAP for authentication, or use a SAML provider other than what is natively supported.
It supports both GitHub.com, GitHub Enterprise Server (GHES) and GitHub, but it will need to live in a location that can access your LDAP servers.

Supported user directories

  • LDAP
  • Active Directory
  • Azure AD
  • Okta
  • OneLogin
  • Google Workspace
  • Keycloak

Features

This utility provides the following functionality:

Feature Supported Description
Sync Users Yes Add or remove users from Teams in GitHub to keep in sync with Active Directory groups
Dynamic Config Yes Utilize a settings file to derive Active Directory and GitHub settings
LDAP SSL Yes SSL or TLS connections.
Failure notifications Yes Presently supports opening a GitHub issue when sync failed. The repo is configurable.
Sync on new team Yes Synchronize users when a new team is created
Sync on team edit No This event is not processed currently
Custom team/group maps Yes The team slug and group name will be matched automatically, unless you define a custom mapping with syncmap.yml
Force custom map Yes Sync only team defined in syncmap.yml
Dry run / Test mode Yes Run and print the differences, but make no changes
Nested teams/groups No Synchronize groups within groups. Presently, if a group is a member of another group, it is skipped

Creating the GitHub App on your GitHub instance

  1. On your GitHub instance, visit the settings page on the organization that you want to own the GitHub App, and navigate to the GitHub Apps section.
    • You can access this page by visiting the following url:
      https://<MY_GITHUB_HOSTNAME>/organizations/<MY_ORG_NAME>/settings/apps
  2. Create a new GitHub App with the following settings:
    • Webhook URL: URL of the machine on which this app has been deployed (Example: http://ip.of.machine:3000)
    • Homepage URL: URL of the machine on which this app has been deployed (Example: http://ip.of.machine:3000)
    • Webhook Secret: The webhook secret that will be or has been defined as an environment variable in your deployment environment as WEBHOOK_SECRET
    • Permissions and Events: This application will need to be able to manage teams on GitHub, so the events and permissions listed below will be required. For more information on how to create a GitHub App, please visit https://developer.github.com/apps/building-github-apps/creating-a-github-app
  3. Once these have been configured, select the Create GitHub App button at the bottom of the page to continue
  4. Make a note of the APP ID on your newly-created GitHub App. You will need to set this as an environment variable when configuring the app.
  5. Generate and download a private key from the new App page, and store it in your deployment environment. You can either do this by saving the file directly in the environment and specifying its path with the environment variable PRIVATE_KEY_PATH
  6. After you have created the GitHub App, you will need to install it to the desired GitHub Organizations.
    • Select Install App
    • Select All Repositories or the desired repositories you wish to watch

Permissions and Events

Permissions

Category Attribute Permission
Repository permissions Issues Read & write
Repository permissions Metadata Read-only
Organization permissions Members Read & write
User permissions Email addresses Read-only

Events

Event Required? Description
Team Optional Trigger when a new team is created, deleted, edited, renamed, etc.

Azure AD Permissions

Authentication methods

  • Username/Password
  • Service Principal
  • Certificate
  • Device Auth

This app requires the following Azure permissions:

  • GroupMember.Read.All
  • User.Read.All

Keycloak Permissions

If you have ADMIN_FINE_GRAINED_AUTHZ enabled, you only need the following permission for the user realm:

  • view-users

Google Workspace Permissions

You must delegate domain-wide authority to the service account with the following scopes:

  • https://www.googleapis.com/auth/admin.directory.group.readonly
  • https://www.googleapis.com/auth/admin.directory.group.member.readonly
  • https://www.googleapis.com/auth/admin.directory.user.readonly

You must provide a Google Workspace Admin account for the service account to impersonate.
It must have Admin API permissions greater or equal to the scopes listed above.

Getting Started

To get started, ensure that you are using Python 3.9 (or update your Pipfile to the version you’re running, 3.4+). The following additional libraries are required:

  • Flask
  • github3.py
  • python-ldap3
  • APScheduler
  • python-dotenv
  • PyYAML
  • msal
  • asyncio
  • okta
  • onelogin
  • python-keycloak

Install the required libraries.

  1. pipenv install

Once you have all of the requirements installed, be sure to edit the .env to match your environment.

Sample .env for GitHub App settings

  1. ## GitHub App settings
  2. WEBHOOK_SECRET=development
  3. APP_ID=12345
  4. PRIVATE_KEY_PATH=.ssh/team-sync.pem
  5. GHE_HOST=github.example.com

Sample .env for choosing your backend

  1. ## AzureAD = AAD
  2. ## AD/LDAP = LDAP
  3. ## Okta = OKTA
  4. ## OneLogin = ONELOGIN
  5. ## Google Workspace = GOOGLE_WORKSPACE
  6. USER_DIRECTORY=LDAP
  7. ## Sync users on username or email attribute
  8. USER_SYNC_ATTRIBUTE=username

Sample .env for Active Directory

  1. LDAP_SERVER_HOST=dc1.example.com
  2. LDAP_SERVER_PORT=389
  3. LDAP_BASE_DN="DC=example,DC=com"
  4. LDAP_USER_BASE_DN="CN=Users,DC=example,DC=example"
  5. LDAP_GROUP_BASE_DN="OU=Groups,DC=example,DC=example"
  6. LDAP_USER_FILTER="(objectClass=person)"
  7. LDAP_USER_ATTRIBUTE=sAMAccountName
  8. LDAP_USER_MAIL_ATTRIBUTE=mail
  9. LDAP_GROUP_FILTER="(&(objectClass=group)(cn={group_name}))"
  10. LDAP_GROUP_MEMBER_ATTRIBUTE=member
  11. LDAP_BIND_USER="bind-user@example.com"
  12. LDAP_BIND_PASSWORD="p4$$w0rd"
  13. LDAP_SEARCH_PAGE_SIZE=1000

Sample .env for OpenLDAP

  1. LDAP_SERVER_HOST=dc1.example.com
  2. LDAP_SERVER_PORT=389
  3. LDAP_BASE_DN="dc=example,dc=com"
  4. LDAP_USER_BASE_DN="ou=People,dc=example,dc=com"
  5. LDAP_GROUP_BASE_DN="ou=Groups,dc=example,dc=com"
  6. LDAP_USER_FILTER="(&(objectClass=person)({ldap_user_attribute}={username}))"
  7. LDAP_USER_ATTRIBUTE=uid
  8. LDAP_USER_MAIL_ATTRIBUTE=mail
  9. LDAP_GROUP_FILTER="(&(objectClass=posixGroup)(cn={group_name}))"
  10. LDAP_GROUP_MEMBER_ATTRIBUTE=memberUid
  11. LDAP_BIND_USER="cn=admin,dc=example,dc=com"
  12. LDAP_BIND_PASSWORD="p4$$w0rd"
  13. LDAP_SEARCH_PAGE_SIZE=1000

Sample .env for AzureAD

  1. AZURE_TENANT_ID="<tenant_id>"
  2. AZURE_CLIENT_ID="<client_id>"
  3. AZURE_CLIENT_SECRET="<client_secret>"
  4. AZURE_APP_SCOPE="default"
  5. AZURE_API_ENDPOINT="https://graph.microsoft.com/v1.0"
  6. # can also be an extensionAttribute
  7. AZURE_USERNAME_ATTRIBUTE=userPrincipalName
  8. AZURE_USER_IS_UPN=true
  9. # use transitive members of a group instead of direct members
  10. AZURE_USE_TRANSITIVE_GROUP_MEMBERS=false

Sample .env for Okta

  1. OKTA_ORG_URL=https://example.okta.com
  2. OKTA_USERNAME_ATTRIBUTE=github_username
  3. # token login
  4. OKTA_ACCESS_TOKEN=asdfghkjliptojkjsj00294759
  5. # OAuth login
  6. OKTA_AUTH_METHOD=oauth
  7. OKTA_CLIENT_ID=abcdefghijkl
  8. OKTA_SCOPES='okta.users.read okta.groups.read'
  9. OKTA_PRIVATE_KEY='{"kty": "RSA", ...}'

Sample .env for Keycloak

  1. KEYCLOAK_USERNAME=api-account
  2. KEYCLOAK_PASSWORD=ExamplePassword
  3. KEYCLOAK_REALM=ExampleCorp
  4. KEYCLOAK_ADMIN_REALM=master
  5. KEYCLOAK_USE_GITHUB_IDP=true

Sample .env for OneLogin

  1. ONELOGIN_CLIENT_ID='asdafsflkjlk13q33433445wee'
  2. ONELOGIN_CLIENT_SECRET='ca3a86f982fjjkjjkfkhls'
  3. REGION=US

Sample .env for Google Workspace

  1. GOOGLE_WORKSPACE_SA_CREDS_FILE=googleAuth.json
  2. GOOGLE_WORKSPACE_ADMIN_EMAIL=admin@example.com
  3. GOOGLE_WORKSPACE_USERNAME_CUSTOM_SCHEMA_NAME=schema-name
  4. GOOGLE_WORKSPACE_USERNAME_FIELD=field-name

Sample .env settings for additional settings

  1. ## Additional settings
  2. CHANGE_THRESHOLD=25
  3. OPEN_ISSUE_ON_FAILURE=true
  4. REPO_FOR_ISSUES=github-demo/demo-repo
  5. ISSUE_ASSIGNEE=githubber
  6. SYNC_SCHEDULE=0 * * * *
  7. TEST_MODE=false
  8. SYNCMAP_ONLY=false
  9. EMU_SHORTCODE=volcano
  10. ### Automatically add users missing from the organization
  11. ADD_MEMBER=false
  12. ## Automatically remove users from the organization that are not part of a team
  13. REMOVE_ORG_MEMBERS_WITHOUT_TEAM=false

Sample .env setting for flask app

  1. ####################
  2. ## Flask Settings ##
  3. ####################
  4. ## Default: app, comment out to run once as a script
  5. FLASK_APP=app
  6. ## Default: production
  7. FLASK_ENV=development
  8. ## Default: 5000
  9. FLASK_RUN_PORT=5000
  10. ## Default: 127.0.0.1
  11. FLASK_RUN_HOST=0.0.0.0

Sample syncmap.yml custom mapping file

  1. ---
  2. mapping:
  3. - github: demo-team
  4. directory: ldap super users
  5. org: my github org
  6. - github: demo-admin-2
  7. directory: some other group

The custom map uses slugs that are lowercase. If you don’t specify organization name, it will synchronize all teams with same name in any organization.

Usage Examples

Start the application from Pipenv

This example runs the app in a standard Flask environment.

  1. pipenv run flask run --host=0.0.0.0 --port=5000

Or you can run the app with Python directly.

  1. pipenv run python app.py

Support

⚠️ This is free and open-source software that is supported by the open-source community, and is not included as part of GitHub’s official platform support.

Credits

This project draws much from: