Note
This is an unofficial tool created by Field Security Specialists, and is not officially supported by GitHub.
These scripts provide an emulated Enterprise security manager team to GitHub Enterprise (Cloud or Server) administrators by using the existing organization Security Manager role.
The scripts will give you a list of all organizations in the enterprise as a CSV to work with programmatically, add you to some or all organizations as an owner, and can create/manage a team with the Security Manager role to see all GitHub Advanced Security alerts throughout the entire enterprise without having admin rights to that code.
Note
This uses the security manager role and parts of the GraphQL API that is available in GitHub.com (free/pro/teams and enterprise), as well as GitHub Enterprise Server versions 3.5 and higher.
org-admin-promote.pyreplaces some of the functionality ofghe-org-admin-promote, a built-in shell command on GHES that promotes an enterprise admin to own some/all organizations in the enterprise. It also outputs a CSV file similar to theall_organizations.csvreport, to better inventory organizations.manage-sec-team.pycreates a team in each organization, assigns it the security manager role, and then adds the people you want to that team (and removes the rest).org-admin-demote.pytakes the text file of orgs that the user wasn't already an owner of and "un-does" that promotion to org owner. By default, it removes the admin from those organizations. It can instead retain the admin as an organization member, preserving security manager team membership.
Note
You need to be an Enterprise administrator to use these scripts
-
Read ☝️ and decide what you want to do.
-
Create a classic personal access token with the
admin:enterpriseandadmin:orgscopes using an Enterprise administrator account. -
Clone this repository to a machine that has Python 3 installed.
-
Install the requirements.
python3 -m pip install --upgrade pip pip install -r requirements.txt
-
Choose inputs as arguments to the scripts as follows:
- The server URL (for GHES, EMU, or data residency) in
--github-url.- For GHEC this is not required.
- Call the scripts with the correct GitHub PAT:
- Place it in
GITHUB_TOKENin your environment, or - create a file and save your token there to read it, and call the script with the
--token-fileargument.
- Place it in
- See progress with the
--progressflag. - Promote/demote scripts:
- Limit the promotion to a subset of organization slugs/names using the
--orgsor--orgs-filearguments.- For
--orgs/-o, list them space separated after the argument. - For
--orgs-file/-f, put a new-line separated list of organizations in a file and provide the path.
- For
- Use the enterprise slug as the first argument:
- This is string URL version of the enterprise identity. It's available in the enterprise admin url (for cloud and server), e.g.
https://github.com/enterprises/ENTERPRISE-SLUG-HERE.
- This is string URL version of the enterprise identity. It's available in the enterprise admin url (for cloud and server), e.g.
- By default, a list of all of the organizations in scope, and the unmanaged set, will be output to
all_orgs.csvandunmanaged_orgs.txtrespectively.- You can use the
--orgs-csvand--unmanaged-orgsarguments to place these elsewhere.
- You can use the
- For
org-admin-demote.py, use--target-role memberto retain the enterprise admin as an organization member after removing owner access. The default,--target-role unaffiliated, preserves the existing behavior and removes the admin from the organization.
- Limit the promotion to a subset of organization slugs/names using the
- Security manager team script:
- Put the name of the security manager team and the team members to add in
--team-nameand--team-members. --sec-team-members(and--sec-team-members-file) are optional. If neither is supplied, the security managers team will still be created in each organization and assigned the security manager role, but its membership will not be modified. This is useful when team membership is managed via Team Sync.- If you are using GHES 3.15 or below, use the
--legacyflag to use the legacy security managers API. - Use the list of orgs output by
org-admin-promote.pyin--unmanaged-orgs, if you changed the output path.
- Put the name of the security manager team and the team members to add in
- The server URL (for GHES, EMU, or data residency) in
-
Run them in the following order:
org-admin-promote.pyto add the enterprise admin to all organizations as an owner, creating a CSV of organizations.manage-sec-team.pyto create a security manager team on all organizations and manage the members.org-admin-demote.pywill remove the enterprise admin's owner access from all the organizations the promotion script added them to. It removes the admin from those organizations by default, or retains organization and security manager team membership with--target-role member.
- The security manager team isn't already an existing team that's using team sync for enterprise or for organizations.
- Because team membership requires organization membership, the default
unaffiliatedtarget also removes the admin from the security managers team. If the enterprise admin should remain in that team, runorg-admin-demote.pywith--target-role member.
This is what a successful run looks like. Here's the inputs:
- The enterprise admin is named
ghe-admin. - The security team is named
security-managers(the default) and has two membersluigiandhubot. - The organizations break down as such:
acmeorg was already configured correctly.testorg-00001needed the team created, withghe-adminremoved andluigiandhubotadded.testorg-00002was already created.
- We've used the
--progressflag
$ ./manage-sec-team.py --sec-team-members luigi hubot --progress
✓ Team security-managers updated as a security manager for acme
Creating team security-managers
✓ Team security-managers updated as a security manager for testorg-00001
Removing ghe-admin from security-managers
Adding luigi to security-managers
Adding hubot to security-managers
Creating team security-managers
✓ Team security-managers updated as a security manager for testorg-00002
Removing ghe-admin from security-managers
✓ Team security-managers updated as a security manager for testorg-00003Remove the enterprise admin from the organizations recorded in unmanaged_orgs.txt:
./org-admin-demote.py ENTERPRISE_SLUGRemove owner access while retaining the enterprise admin as an organization member and preserving its security manager team membership:
./org-admin-demote.py ENTERPRISE_SLUG --target-role memberBoth modes operate only on the organization IDs recorded by org-admin-promote.py. The demotion script does not modify teams or team memberships directly.
- Scripts that do things are in the root directory.
- Functions that do small parts are in
/src, grouped roughly by what part of GitHub they work on. - Python code is formatted with black.
- Python dependencies are minimal by default. There are two:
- requests is a simple and popular HTTP library.
- defusedcsv is used over
csvto mitigate spreadsheet application exploitation in older versions.
- The
.csvfiles and.txtfiles are in the.gitignorefile to avoid accidental commits into the repo.
If you are running against a GitHub Enterprise Server instance that uses a self‑signed certificate or an internal certificate authority, you can provide a custom root CA (or certificate bundle) with the --ca-bundle argument on all three scripts:
./org-admin-promote.py ENTERPRISE_SLUG --github-url https://ghe.example.com --ca-bundle /path/to/internal-ca.pem
./manage-sec-team.py --github-url https://ghe.example.com --ca-bundle /path/to/internal-ca.pem --sec-team-members alice bob
./org-admin-demote.py ENTERPRISE_SLUG --github-url https://ghe.example.com --ca-bundle /path/to/internal-ca.pemThe value passed must be a readable PEM file containing the certificate(s). If omitted, the Python default trust store is used.