src-auth-perms-sync automates Sourcegraph's Explicit Permissions GraphQL API, setting user-to-repo permissions based on mapping rules, for example:
- Users who authenticated to SAML auth provider A, and their SAML assertion includes group 1, are granted access to repos cloned via code host X
This repo was created for Sourcegraph Implementation Engineering deployments, and is not intended, designed, built, or supported for use in any other scenario. Feel free to open issues or PRs, but responses are best effort.
- Release versions are
major.minor.patch - Because this project is still major version 0:
- Minor version updates are probably breaking changes
- Patch version updates are probably not breaking changes
-
Customers need to be able to trust this, and audit this, similar to code host permissions
-
To keep the interface simple, auditable, and trustable, the user and repo filters in each map only match "all," not "any," i.e., adding multiple filters to each map casts a smaller net of users / repos. This can result in more maps, but they will be easier to understand and trust.
-
Backup files are saved in
src-auth-perms-sync-runs/<src_endpoint>/runs/<run>/, unless the--no-backuparg is provided, so customers can review the changes made over time, and restore to a specific backup file, if needed -
It is assumed that this script is the only operator of Explicit Permissions on the Sourcegraph instance. Any other Explicit Permissions may be overwritten by this script.
-
As with all usage of the Explicit Permissions API, user-repo permissions synced from code hosts are not affected by this script, but an Explicit Permissions rule overrides any conflicting permissions synced from code hosts
-
One installation of this script can apply separate
maps.yamlfiles on separate Sourcegraph instances- By default, each Sourcegraph instance gets its own generated
maps.yamlundersrc-auth-perms-sync-runs/<src_endpoint>/ - If you pass
--maps-path, relative paths are resolved from your current working directory - Set the
SRC_ENDPOINTandSRC_ACCESS_TOKENenvironment variables correctly for each run
- By default, each Sourcegraph instance gets its own generated
-
As we're using the Explicit Permissions API, bindIDs are always usernames, never email addresses
-
The Sourcegraph instance's site config must contain:
{ "auth.enableUsernameChanges": false, "permissions.userMapping": { "bindID": "username", "enabled": true } }
-
-
As different SAML providers have different schemas, this script uses the Sourcegraph instance's
groupsAttributeNamesite config attribute of each auth provider config-
If
groupsAttributeNameis not set, then the defaultgroupsis used -
If
groupsAttributeNameis set, then theconfigIDattribute is also required -
If org mapping is used, then the
configIDattribute is also required{ "auth.providers": [ { "allowSignup": true, "configID": "okta", // Required because groupsAttributeName is set, or for org mapping "groupsAttributeName": "custom-group-attribute-name", "identityProviderMetadataURL": "https://example.okta.com/app/example-id/sso/saml/metadata", "type": "saml" } ] }
-
-
It is strongly recommended to configure SCIM between your auth provider, and your Sourcegraph instance, so the new user's account is created on the Sourcegraph instance immediately after they're approved, giving this script more time to run before the user tries logging in for the first time
- Requires Python >= 3.11
- Recommended: Use a Python virtual environment
# Set up virtual environment
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
# Install package from PyPI
python -m pip install src-auth-perms-sync
# Run the CLI
src-auth-perms-sync --helpDownload the .tar.gz file from a GitHub release
tar -xzf src-auth-perms-sync-linux-x64.tar.gz
pip install --no-index --find-links ./wheelhouse src-auth-perms-sync
# Run the CLI
src-auth-perms-sync --helpfrom pathlib import Path
import src_auth_perms_sync as src
config = src.Config(
src_endpoint="https://sourcegraph.example.com",
src_access_token="sgp_...",
maps_path=Path("/absolute/path/to/maps.yaml"),
apply=False, # Dry run (default), set to True to make changes
)
succeeded = src.Set(config)
# Other command wrappers:
# succeeded = src.Get(config)
# succeeded = src.Restore(config)
# succeeded = src.SyncSamlOrgs(config)-
Environment variables (CLI), or src.Config args (Python import)
SRC_ENDPOINTSRC_ACCESS_TOKENfrom a user with site-admin perms- See .env.example
-
YAML maps file
- By default:
src-auth-perms-sync-runs/<src_endpoint>/maps.yaml - Or pass
--maps-path ./path/to/maps.yaml - A list of mapping rules
- Each mapping rule takes
- A map of filters for users
- A map of filters for repos
- See maps-example.yaml
- An empty maps.yaml file is created for you on the first
getrun
- By default:
-
Get auth providers and code hosts
src-auth-perms-sync get
- Queries the Sourcegraph instance for auth providers and code host connections
- Writes generated reference files
auth-providers.yamlandcode-hosts.yamlundersrc-auth-perms-sync-runs/<src_endpoint>/ - Creates an empty
maps.yamlif it doesn't exist
-
Configure mapping rules
- Edit
src-auth-perms-sync-runs/<src_endpoint>/maps.yaml - Add mapping rules under the
maps:top level key - See maps-example.yaml
- Edit
-
Set: Dry run
src-auth-perms-sync set --full -
Set: Apply
src-auth-perms-sync set --full --apply- To use a maps file outside the generated endpoint directory, pass an
explicit path, for example
--maps-path ./maps.yaml
- To use a maps file outside the generated endpoint directory, pass an
explicit path, for example
-
Restore: Dry run
src-auth-perms-sync restore \ --restore-path src-auth-perms-sync-runs/<src_endpoint>/runs/<run>/before.json
- Roll back the explicit-permissions state on the instance to match a previously captured snapshot
- Relative
--restore-pathvalues are resolved from your current working directory
-
Restore: Apply
src-auth-perms-sync restore \ --restore-path src-auth-perms-sync-runs/<src_endpoint>/runs/<run>/before.json \ --apply
-
Get user and org metadata
src-auth-perms-sync sync-saml-orgs
- Queries the Sourcegraph instance for auth providers, users, users' SAML groups, and orgs
- Dry run
-
Apply org sync
src-auth-perms-sync sync-saml-orgs --apply
- Creates the orgs if they don't exist, and sync the members from the SAML groups to the orgs
--sync-saml-orgscan also be added to asetrun, to run both at the same time
Run src-auth-perms-sync --help for options
src-auth-perms-sync-runs/<src_endpoint>/
├── auth-providers.yaml
├── code-hosts.yaml
├── maps.yaml
└── runs
└── timestamp-command
├── before.json
├── after.json
├── diff.json
├── log.json
└── maps.yaml
- The
src-auth-perms-sync-runsdir is created under your current working directory - The
<src_endpoint>dir is created with the hostname fromSRC_ENDPOINT - If
maps.yamldoesn't exist already, it'll be created for you auth-providers.yamlandcode-hosts.yamlare created / replaced by thegetcommand, for you to copy values from, to use in yourmaps.yaml- Only one
maps.yamlfile can be used at a time per Sourcegraph instance, as eachset --applycommand resets the state on the Sourcegraph instance to themaps.yamlfile which was used - Each run of the script creates a new
timestamp-commanddir under therunsdir, with:- A
before.jsonfile, capturing the before state, which can be used in a restore run - A log file
- A backup copy of the
maps.yamlfile which was used in that run
- A
- Runs using
--applyalso create- An
after.jsonfile, capturing the new state - A
diff.jsonfile, a shorter, reviewable file containing the diffs between before and after
- An