Workspaces
Single sign-on
Connect a workspace to your identity provider over SAML 2.0, OpenID Connect or OAuth 2.0, let its people join, and require it of members. On every paid plan.
A workspace can connect to its own identity provider, such as Okta, Microsoft Entra ID, Google Workspace, Auth0, OneLogin or JumpCloud, over OpenID Connect, SAML 2.0 or plain OAuth 2.0. It comes with every paid plan at no extra price. A free workspace sees the page with everything turned off until an owner starts the plan.
Single sign-on never signs anyone in to g1t. People sign in to g1t as themselves, with their password, GitHub and two-factor authentication as usual, then sign in through your provider to use the workspace. The first time they do, g1t links who they are at your provider to their g1t account. Their personal repositories and other workspaces are never your provider’s to open.
Set it up
Section titled “Set it up”Owners only, at Workspace → Access → Single sign-on,
g1t.sh/<workspace>/-/sso.
-
Choose the protocol. Use OpenID Connect when your provider offers it; SAML 2.0 for providers set up for SAML apps; OAuth 2.0 for one with neither.
-
In your provider, create an app with the addresses the page shows:
Redirect URI (OpenID Connect, OAuth 2.0) https://g1t.sh/auth/sso/<workspace-id>/callbackEntity id, audience (SAML) https://g1t.sh/auth/sso/<workspace-id>/metadataAssertion consumer service URL, HTTP-POST (SAML) https://g1t.sh/auth/sso/<workspace-id>/samlMetadata (SAML) https://g1t.sh/auth/sso/<workspace-id>/metadataThey name the workspace by its id (
wsp_…), which never changes, so renaming the workspace leaves your provider’s setup as it is. The page shows them with the id filled in. -
Copy what the provider gives you back into the page:
- OpenID Connect: the issuer (where its
/.well-known/openid-configurationlives), the client id and the client secret. Scopes default toopenid email profile. - SAML 2.0: the provider’s entity id (its issuer), its single sign-on URL, and its signing certificate (PEM). Paste more than one while you rotate certificates.
- OAuth 2.0: the authorization, token and userinfo URLs, the client
id and secret, the scopes, and which claims of the userinfo answer
are the person’s stable id (
sub, thenid, by default) and their address (email).
- OpenID Connect: the issuer (where its
-
Choose Set up single sign-on. For OpenID Connect g1t reads the issuer’s discovery document first, and says so if it cannot.
The client secret is kept encrypted and never shown again; leave it empty when you save other changes to keep it.
Test it
Section titled “Test it”Choose Test sign-in. g1t sends you to your provider and back, links your account, and marks the connection Tested with your name. You must have signed in through it yourself before you can require it of everyone.
Let people join
Section titled “Let people join”Turn on Let people from your provider join (it starts off) and anyone
your provider signs in becomes a member of the workspace when they first
sign in through it, with no invitation: send them to
g1t.sh/auth/sso/<workspace>. g1t asks them to confirm first, so a link
alone never makes anyone a member. They need a g1t account with a
confirmed email address, and the workspace’s other rules still apply, such
as requiring two-factor authentication.
Only addresses at limits who may join to people whose address your
provider vouches for (OpenID Connect’s email_verified, or a signed SAML
assertion) at your domains, such as acme.com. Set it, or leave joining
off, whenever your provider lets anyone sign in: a personal Google or
GitHub account would otherwise let in anyone. With joining off, only
people who are already members can sign in through it.
Require it
Section titled “Require it”Turn on Require single sign-on under Test and require. From then on a member uses the workspace only:
- On the site, from a session that signed in through your provider in the last day. After a day they go through it again, which is usually instant: your provider remembers them.
- With an access token or SSH key, once they have linked their account (and, with SCIM, while your provider still has them assigned).
- Never with their g1t password for git over HTTPS: use a token.
A member who has not keeps their place but cannot use the workspace: its private repositories, pages and API answer as if they were not a member, including repositories they have a role on directly, and every page shows a notice with a link to sign in through your provider.
Owners are never held out, so a provider that breaks or a certificate that expires never locks you out of your own workspace. Outside collaborators are not asked: they are not your provider’s people.
Linked people
Section titled “Linked people”The page lists everyone who has signed in through your provider, who they are there, and when they last did. Unlink someone to let them link another account at your provider; their sessions go through it again. Each account at your provider links to one g1t account, and each g1t account to one account at your provider.
Changing the provider itself (the protocol, the issuer, or the SAML entity id) unlinks everyone and stops requiring it, until someone has signed in through the new one. Changing the client, the scopes or the certificate keeps everyone linked.
What g1t checks
Section titled “What g1t checks”- OpenID Connect and OAuth 2.0 use the authorization code flow with
PKCE. For OpenID Connect, the ID token must be issued by your issuer, for
your client id, unexpired, and answer this sign-in’s nonce, and its
signature must verify with a key your provider publishes (its
jwks_uri): RS256, RS384, RS512, PS256, PS384, PS512 or ES256. Tokens signed with a shared secret (HS256) or not at all are refused. - SAML responses must be signed, the assertion or the whole response, with RSA and SHA-256, SHA-384 or SHA-512, by one of the certificates you saved. The response must answer the request g1t sent (sign-ins started at your provider are refused), be addressed to the workspace’s assertion consumer service, name g1t’s entity id as the audience, come from your provider’s entity id, and be in its validity window. When only the assertion is signed, its own subject confirmation must name g1t’s request. Responses with comments or processing instructions are refused. Leave the assertion unencrypted: it reaches g1t over HTTPS.
If the plan ends
Section titled “If the plan ends”The settings stay. Members cannot sign in through your provider until the plan starts again, so a workspace that requires it holds its members out meanwhile; owners can still turn the requirement off. Turning it off and removing it never need a plan.
Remove it
Section titled “Remove it”Danger zone → Remove forgets your provider and who everyone is there, and stops requiring it. Members keep their place in the workspace.
Audit log
Section titled “Audit log”Recorded in the workspace’s audit log:
sso.created, sso.updated, sso.deleted, sso.required,
sso.not_required, sso.identity_linked, sso.identity_unlinked, and
member.joined_by_sso.
API and MCP
Section titled “API and MCP”Owners can do all of it with an access token, through the REST API or the
workspace tool’s actions on the MCP server:
| REST | MCP action | Scope | |
|---|---|---|---|
| Read it, with where to point the provider | GET /workspaces/{workspace}/sso |
get_sso |
workspace:read |
| Set it up or change it | PUT /workspaces/{workspace}/sso |
configure_sso |
workspace:admin |
| Require it, or stop | PUT /workspaces/{workspace}/sso/required |
set_sso_required |
workspace:admin |
| Remove it | DELETE /workspaces/{workspace}/sso |
delete_sso |
workspace:admin |
| The linked people | GET /workspaces/{workspace}/sso/identities |
list_sso_identities |
access:read |
| Unlink someone | DELETE /workspaces/{workspace}/sso/identities/{username} |
unlink_sso_identity |
access:admin |
configure_sso takes protocol (oidc, oauth2 or saml) and the
protocol’s fields as the page names them: issuer, client_id,
client_secret, scopes; authorization_url, token_url,
userinfo_url, subject_claim, email_claim; idp_entity_id,
idp_sso_url, certificate (PEM). Its answer, like get_sso’s, has
service_provider: the redirect_uri, entity_id, acs_url,
metadata_url and sign_in_url to give your provider and your people.
The client secret is never returned.
curl -X PUT https://api.g1t.sh/workspaces/acme/sso -H "Authorization: Bearer $G1T_TOKEN" -d '{"protocol": "oidc", "issuer": "https://acme.okta.com", "client_id": "0oa1b2c3", "client_secret": "…"}'Signing in through the provider is a trip in the browser, so it has no
API: send people to sign_in_url.
With SCIM, your provider tells g1t who is assigned to the workspace, and who is not any more:
- Only people your provider has assigned, and not deactivated, can sign in through it. Someone else is told to ask whoever runs your provider.
- Someone it unassigns, deactivates or deletes leaves the workspace at once: their membership, their roles on its repositories and teams, their link, and their sessions through it. Their g1t account is theirs and stays. Owners are never removed this way; the audit log says so, and you remove one by hand if they should go.
- People, not groups. Assign a group to the app in your provider and its members are provisioned one by one. Groups your provider pushes are accepted and not kept, so pushing them never fails.
To turn it on, open Single sign-on → SCIM provisioning and choose Turn on SCIM. Give your provider:
| SCIM base URL (tenant URL) | https://api.g1t.sh/scim/v2/<workspace-id> |
| Authentication | Bearer token: the SCIM token, shown once |
| Unique identifier | userName |
| Supported | Create, update (PUT and PATCH), deactivate and delete users; filtering by userName, externalId, id or emails.value |
Whoever signs in through your provider is matched to the person it
assigned by a stable id it gave (the SAML NameID, OpenID’s sub, and for
Microsoft Entra ID the object id and a member’s user principal name) as
their userName or externalId, or by an address your provider vouches
for as their userName or primary address. If more than one assigned
person matches, nobody is chosen and they are told so. Make a new
token replaces the old one at once; Turn off SCIM forgets who was
assigned and removes nobody.
Through the API: POST /workspaces/{workspace}/sso/scim (enable_scim)
answers with the token and scim_url; DELETE turns it off
(disable_scim). get_sso lists who is assigned under scim. Recorded as
sso.scim_enabled, sso.scim_token_rotated, sso.scim_disabled,
sso.scim_user_provisioned, sso.scim_user_activated,
sso.scim_user_deactivated, sso.scim_user_deleted,
member.removed_by_scim and sso.scim_owner_kept, with scim as the
actor.