Skip to main content

Provisioning users and groups with SCIM using the REST API

Manage the lifecycle of user accounts from your identity provider using GitHub's REST API for System for Cross-domain Identity Management (SCIM).

Who can use this feature?

Enterprise Managed Users is available for new enterprise accounts on GitHub Enterprise Cloud. See "About Enterprise Managed Users."

Note

GitHub recommends that you test provisioning in an environment that's isolated from the production data on your IdP and GitHub.

About IAM for Enterprise Managed Users

If your enterprise on GitHub is created for Enterprise Managed Users, you must configure an external identity management system to provision and maintain user accounts. Your identity management system must offer the following functionality:

  • Single sign-on authentication implementing one of the following two single sign-on (SSO) standards:
    • Security Assertion Markup Language (SAML) 2.0
    • OpenID Connect (OIDC), which is only supported if you use Microsoft Entra ID (previously known as Azure AD)
  • User lifecycle management with System for Cross-domain Identity Management (SCIM)

When you configure authentication and provisioning for your enterprise, you can either use a partner IdP, or you can use another combination of identity management systems.

Using a partner identity provider

Each partner IdP provides a "paved-path" application, which implements both SSO and user lifecycle management. To simplify configuration, GitHub recommends that you use a partner IdP's application for both authentication and provisioning. For more information and a list of partner IdPs, see "About Enterprise Managed Users."

For more information about configuring SCIM provisioning using a partner IdP, see "Configuring SCIM provisioning for Enterprise Managed Users."

Using other identity management systems

If you cannot use a partner IdP for both authentication and provisioning due to migration overhead, licensing costs, or organizational inertia, you can use another identity management system or combination of systems. The systems must provide authentication using SAML and user lifecycle management using SCIM, and must adhere to GitHub's integration guidelines.

GitHub has not tested integration with every identity management system. While integration with Enterprise Managed Users may be possible, GitHub's support team may not be able to assist you with issues related to these systems. If you need help with an identity management system that's not a partner IdP, or if you use a partner IdP only for SAML authentication, you must consult the system's documentation, support team, or other resources.

Prerequisites

Best practices for SCIM provisioning with GitHub's REST API

When you configure your identity management system to provision users or groups of users on GitHub Enterprise Cloud, GitHub strongly recommends that you adhere to the following guidelines.

Ensure your identity management system is the only source of write operations

To ensure that your environment has a single source of truth, you should only programmatically write to the REST API for SCIM provisioning from your identity management system. GitHub strongly recommends that only one system sends POST, PUT, PATCH, or DELETE requests to the API.

However, you can safely retrieve information from GitHub's APIs with GET requests in scripts or ad hoc requests by an enterprise owner.

Warning: If you use a partner IdP for SCIM provisioning, the application on the IdP must be the only system that makes write requests to the API. If you make ad hoc requests using the POST, PUT, PATCH, or DELETE methods, subsequent synchronization attempts will fail, and provisioning won't function properly for your enterprise.

Send valid requests to REST API endpoints

GitHub's REST API endpoints for provisioning users with SCIM require well-formed requests. Bear in mind the following guidelines:

  • Requests that don't match the API's expectations will return a 400 Bad Request error.
  • REST API endpoints for provisioning users with SCIM require a User-Agent header. GitHub Enterprise Cloud will reject requests without this header.
  • If your enterprise is on GHE.com, ensure you send API requests to the endpoint for your enterprise at api.SUBDOMAIN.ghe.com.

Provision users before you provision groups

SCIM groups are effective for the management of user access at scale. For example, you can use groups on your identity management system to manage team and organization membership on GitHub Enterprise Cloud.

To manage team membership with groups on your identity management system, you must sequentially complete the following steps:

  1. Provision user accounts on GitHub Enterprise Cloud.
  2. Provision a group on GitHub Enterprise Cloud.
  3. Update the membership of the group on your identity management system.
  4. Create a team on GitHub Enterprise Cloud that's mapped to the group on your identity management system.

Validate access for groups on GitHub

If you manage access using groups on your identity management system, you can validate that users get the access you intend. You can use the REST API to compare your system's group memberships with GitHub's understanding of those groups. For more information, see "REST API endpoints for external groups" and "REST API endpoints for teams" in the REST API documentation.

Understand rate limits on GitHub

To ensure the availability and reliability of the platform, GitHub implements rate limits.

Without considering rate limits, large enterprises onboarding with Enterprise Managed Users for the first time are likely to exceed the limits. To avoid exceeding the rate limit on GitHub Enterprise Cloud, do not assign more than 1,000 users per hour to the SCIM integration on your IdP. If you use groups to assign users to the IdP application, do not add more than 1,000 users to each group per hour. If you exceed these thresholds, attempts to provision users may fail with a "rate limit" error. You can review your IdP logs to confirm if attempted SCIM provisioning or push operations failed due to a rate limit error. The response to a failed provisioning attempt will depend on the IdP.

For more information, see "Rate limits for the REST API."

Configure audit log streaming

The audit log for your enterprise displays details about activity in your enterprise. You can use the audit log to support your configuration of SCIM. For more information, see "About the audit log for your enterprise."

Due to the volume of events in this log, GitHub retains the data for 180 days. To ensure that you don't lose audit log data, and to view more granular activity in the audit log, GitHub recommends that you configure audit log streaming. When you stream the audit log, you can optionally choose to stream events for API requests, including requests to REST API endpoints for SCIM provisioning. For more information, see "Streaming the audit log for your enterprise."

Limit the scope of the SCIM token

For a better security posture, we recommend using a personal access token (classic) with only the scim:enterprise scope to limit the token's access to the REST API endpoints required to make SCIM calls.

If you currently use a token with the admin:enterprise scope, be aware that this token grants access to all actions on the enterprise. You can swap your token for a new token with just the scim:enterprise scope without disruption.

Provisioning users with the REST API

To provision, list, or manage users, make requests to the following REST API endpoints. You can read about the associated API endpoints in the REST API documentation and see code examples, and you can review audit log events associated with each request.

Before a person with an identity on your identity management system can sign in to your enterprise, you must create the corresponding user. Your enterprise doesn't require an available license to provision a new user account.

  • For an overview of the supported attributes for users, see "SCIM" in the REST API documentation.
  • You can view provisioned users in the web UI for GitHub Enterprise Cloud. For more information, see "Viewing people in your enterprise."
ActionMethodEndpoint and more informationEvents in the audit log
List all provisioned users for your enterprise, which includes all users who are soft-deprovisioned by setting active to false.GET/scim/v2/enterprises/{enterprise}/UsersN/A
Create a user. The API's response includes an id field for uniquely identifying the user.POST/scim/v2/enterprises/{enterprise}/Users
  • external_identity.provision
  • user.create
  • If request adds the enterprise_owner role, business.add_admin
  • If request adds the billing_manager role, business.add_billing_manager
  • If request succeeds, external_identity.scim_api_success
  • If request fails, external_identity.scim_api_failure
Retrieve an existing user in your enterprise using the id field from the POST request that you sent to create the user.GET/scim/v2/enterprises/{enterprise}/Users/{scim_user_id}N/A
Update all of an existing user's attributes using the id field from the POST request that you sent to create the user. Update active to false to soft-deprovision the user, or true to reactivate the user. For more information, see "Soft-deprovisioning users with the REST API" and "Reactivating users with the REST API."PUT/scim/v2/enterprises/{enterprise}/Users/{scim_user_id}
  • external_identity.update, unless soft-deprovisioning or reprovisioning
  • If request adds the enterprise_owner role, business.add_admin
  • If request adds the billing_manager, business.add_billing_manager
  • If request removes the enterprise_owner role, business.remove_admin
  • If request removes the billing_manager role, business.remove_billing_manager
  • If request succeeds, external_identity.scim_api_success
  • If request fails, external_identity.scim_api_failure
Update an individual attribute for an existing user using the id field from the POST request that you sent to create the user. Update active to false to soft-deprovision the user, or true to reactivate the user. For more information, see "Soft-deprovisioning users with the REST API" and "Reactivating users with the REST API."PATCH/scim/v2/enterprises/{enterprise}/Users/{scim_user_id}
  • external_identity.update, unless soft-deprovisioning or reprovisioning
  • If request adds the enterprise_owner role, business.add_admin
  • If request adds the billing_manager, business.add_billing_manager
  • If request removes the enterprise_owner role, business.remove_admin
  • If request removes the billing_manager role, business.remove_billing_manager
  • If request succeeds, external_identity.scim_api_success
  • If request fails, external_identity.scim_api_failure
To completely delete an existing user, you can hard-deprovision the user. After hard-deprovisioning, you cannot reactivate the user, and you must provision the user as a new user. For more information, see "Hard-deprovisioning users with the REST API."DELETE/scim/v2/enterprises/{enterprise}/Users/{scim_user_id}
  • external_identity.deprovision
  • user.remove_email
  • If request succeeds, external_identity.scim_api_success
  • If request fails, external_identity.scim_api_failure

Soft-deprovisioning users with the REST API

To prevent a user from signing in to access your enterprise, you can soft-deprovision the user by sending a PUT or PATCH request to update a user's active field to false to /scim/v2/enterprises/{enterprise}/Users/{scim_user_id}. When you soft-deprovision a user, GitHub Enterprise Cloud obfuscates the user record's login and email fields, and the user is suspended.

When you soft-deprovision a user, the external_identity.update event does not appear in the audit log. The following events appear in the audit log:

  • user.suspend
  • user.remove_email
  • user.rename
  • external_identity.deprovision
  • If the request succeeds, external_identity.scim_api_success
  • If the request fails, external_identity.scim_api_failure

You can view all suspended users for your enterprise. For more information, see "Viewing people in your enterprise.

Reactivating users with the REST API

To allow a soft-deprovisioned user to sign in to access your enterprise, unsuspend the user by sending a PUT or PATCH request to /scim/v2/enterprises/{enterprise}/Users/{scim_user_id} that updates the user's active field to true.

When you reactivate a user, the external_identity.update event does not appear in the audit log. The following events appear in the audit log:

  • user.unsuspend
  • user.remove_email
  • user.rename
  • external_identity.provision
  • If the request succeeds, external_identity.scim_api_success
  • If the request fails, external_identity.scim_api_failure

Hard-deprovisioning users with the REST API

To completely delete a user, you can hard-deprovision the user by sending a DELETE request to /scim/v2/enterprises/{enterprise}/Users/{scim_user_id}. Your enterprise will retain any resources and comments created by the user.

When you hard-deprovision a user, the following events occur:

  • The user record's login and email fields are obfuscated.
  • The user's display name is set to an empty string.
  • GitHub Enterprise Cloud deletes all of the user's SCIM attributes, emails, SSH keys, personal access tokens, and GPG keys.
  • The user's account on GitHub Enterprise Cloud is suspended, and authentication to sign in to the account will fail.

To reprovision the user, you must use the POST method to create a new user. The new user can reuse the deprovisioned user's login. If the email addresses of the hard-deprovisioned user and the new user match, GitHub Enterprise Cloud will attribute existing Git commits associated with the email address to the new user. Existing resources and comments created by the original user will not be associated with the new user.

Provisioning groups with the REST API

To control access to repositories in your enterprise, you can use groups on your identity management system to control organization and team membership for users in your enterprise. You can read about the associated API endpoints in the REST API documentation and see code examples, and you can review audit log events associated with each request.

While your enterprise doesn't require an available license to provision a new user account, if you provision a group that results in the addition of users to an organization, you must have available licenses for those users. If your enterprise only uses Visual Studio subscriptions with GitHub Enterprise, the associated user must be assigned to a subscriber. For more information, see "About Visual Studio subscriptions with GitHub Enterprise."

ActionMethodEndpoint and more informationRelated events in the audit log
List all groups defined for your enterprise.GET/scim/v2/enterprises/{enterprise}/GroupsN/A
To define a new IdP group for your enterprise, create the group. The API's response includes an id field for uniquely identifying the group.POST/scim/v2/enterprises/{enterprise}/Groups
  • external_group.provision
  • external_group.update_display_name
  • If the request included a list of users, external_group.add_member
  • If request succeeds, external_group.scim_api_success
  • If request fails, external_group.scim_api_failure
Retrieve an existing group for your enterprise using the id from the POST request that you sent to create the group.GET/scim/v2/enterprises/{enterprise}/Groups/{scim_group_id}N/A
Update all of the attributes for an existing group.PUT/scim/v2/enterprises/{enterprise}/Groups/{scim_group_id}
  • external_group.update
  • If request updates the group's name, external_group.update_display_name
  • If request adds a user to the group, external_group.add_member
  • If request removes a user from the group, external_group.remove_member
  • If request succeeds, external_group.scim_api_success
  • If request fails, external_group.scim_api_failure
  • Additional events may appear in the audit log depending on whether the user is already a member of the organization with the team that you linked to the IdP group. For more information, see "Additional audit log events for changes to IdP groups."
Update an individual attribute for an existing group.PATCH/scim/v2/enterprises/{enterprise}/Groups/{scim_group_id}
  • external_group.update
  • If request updates the group's name, external_group.update_display_name
  • If request adds a user to the group, external_group.add_member
  • If request removes a user from the group, external_group.remove_member
  • If request succeeds, external_group.scim_api_success
  • If request fails, external_group.scim_api_failure
  • Additional events may appear in the audit log depending on whether the user is already a member of the organization with the team that you linked to the IdP group. For more information, see "Additional audit log events for changes to IdP groups."
Completely delete an existing group.DELETE/scim/v2/enterprises/{enterprise}/Groups/{scim_group_id}
  • external_group.delete
  • If the request deletes a group linked to a team in an organization where the user has no other team membership, org.remove_member
  • If the request deletes a group linked to a team in an organization where the user has other team membership, team.remove_member
  • If request succeeds, external_group.scim_api_success
  • If request fails, external_group.scim_api_failure

Additional audit log events for changes to IdP groups

If you update the members of an existing group using a PUT or PATCH request to /scim/v2/enterprises/{enterprise}/Groups/{scim_group_id}, GitHub Enterprise Cloud may add the user to the organization or remove the user from the organization depending on the user's current organization membership. If the user is already a member of at least one team in the organization, the user is a member of the organization. If the user is not a member of any teams in the organization, the user may also not already be a member of the organization.

If your request updates a group linked to a team in an organization where a user is not already a member, in addition to external_group.update, the following events appear in the audit log:

  • org.add_member
  • If the request adds a user to a group that's linked to a team in an organization where the user is not already a member, org.add_member
  • If the request adds the user to a group that's linked to a team in an organization, team.add_member

If your request updates a group linked to a team in an organization where a user is already a member, in addition to external_group.update, the following events appear in the audit log:

  • If the request removes the user from a group that's linked to a team in an organization, and the team is not the last team in the organization where the user is a member, team.remove_member
  • If the request removes a user from a group that's linked to the last team in an organization where the user is already a member, org.remove_member

Migrating to a new SCIM provider

After you configure SCIM provisioning for your enterprise, you may need to migrate to a new SCIM provider. For more information, see "Migrating your enterprise to a new identity provider or tenant."

Troubleshooting SCIM provisioning

  • If your requests to the REST API are rate-limited, you can learn more in "Understand rate limits on GitHub."

  • If you enable audit log streaming and stream events for API requests, you can review any requests to the REST API endpoints for SCIM provisioning by filtering for events from the EnterpriseUsersScim or EnterpriseGroupsScim controllers.

  • If a SCIM request fails and you're unable to determine the cause, check the status of your identity management system to ensure that services were available. Additionally, check GitHub's status page. For more information, see "About GitHub Support."

  • If a request to provision a user fails with a 400 error, and the error message in your identity management system's log indicates issues with account ownership or username formatting, review "Username considerations for external authentication."

  • After successful authentication, GitHub Enterprise Cloud links the user who authenticated to an identity provisioned by SCIM. The unique identifiers for authentication and provisioning must match. For more information, see "REST API endpoints for SCIM." You can also view this mapping on GitHub. See "Viewing and managing a user's SAML access to your enterprise."

  • If you manage access using groups on your identity management system, you can troubleshoot using the REST API or web UI for GitHub Enterprise Cloud.

For additional troubleshooting suggestions, see "Troubleshooting identity and access management for your enterprise."