Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

174 linesCodeBlameRaw
1---
2title: Single sign-on
3description: 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.
4---
5
6A workspace can connect to its own identity provider, such as Okta,
7Microsoft Entra ID, Google Workspace, Auth0, OneLogin or JumpCloud, over
8**OpenID Connect**, **SAML 2.0** or plain **OAuth 2.0**. It comes with
9every paid plan at no extra price. A free workspace sees the page with
10everything turned off until an owner starts the plan.
11
12Single sign-on never signs anyone in to g1t. People sign in to g1t as
13themselves, with their password, GitHub and two-factor authentication as
14usual, then sign in through your provider to use the workspace. The
15first time they do, g1t links who they are at your provider to their g1t
16account. Their personal repositories and other workspaces are never your
17provider's to open.
18
19## Set it up
20
21Owners only, at **Workspace → Access → Single sign-on**,
22`g1t.sh/<workspace>/-/sso`.
23
241. Choose the protocol. Use **OpenID Connect** when your provider offers
25 it; **SAML 2.0** for providers set up for SAML apps; **OAuth 2.0** for
26 one with neither.
272. In your provider, create an app with the addresses the page shows:
28
29 | | |
30 | --- | --- |
31 | Redirect URI (OpenID Connect, OAuth 2.0) | `https://g1t.sh/auth/sso/<workspace>/callback` |
32 | Entity id, audience (SAML) | `https://g1t.sh/auth/sso/<workspace>/metadata` |
33 | Assertion consumer service URL, HTTP-POST (SAML) | `https://g1t.sh/auth/sso/<workspace>/saml` |
34 | Metadata (SAML) | `https://g1t.sh/auth/sso/<workspace>/metadata` |
35
363. Copy what the provider gives you back into the page:
37
38 - **OpenID Connect**: the issuer (where its
39 `/.well-known/openid-configuration` lives), the client id and the
40 client secret. Scopes default to `openid email profile`.
41 - **SAML 2.0**: the provider's entity id (its issuer), its single
42 sign-on URL, and its signing certificate (PEM). Paste more than one
43 while you rotate certificates.
44 - **OAuth 2.0**: the authorization, token and userinfo URLs, the client
45 id and secret, the scopes, and which claims of the userinfo answer
46 are the person's stable id (`sub`, then `id`, by default) and their
47 address (`email`).
48
494. Choose **Set up single sign-on**. For OpenID Connect g1t reads the
50 issuer's discovery document first, and says so if it cannot.
51
52The client secret is kept encrypted and never shown again; leave it empty
53when you save other changes to keep it.
54
55## Test it
56
57Choose **Test sign-in**. g1t sends you to your provider and back, links
58your account, and marks the connection **Tested** with your name. You
59must have signed in through it yourself before you can require it of
60everyone.
61
62## Let people join
63
64With **Let people from your provider join** on (the default), anyone your
65provider signs in becomes a member of the workspace when they first sign
66in through it, with no invitation: send them to
67`g1t.sh/auth/sso/<workspace>`. They need a g1t account with a confirmed
68email address first, and the workspace's other rules still apply, such as
69[requiring two-factor authentication](/guides/workspaces/#require-two-factor-authentication).
70Turn it off and only people who are already members can sign in through
71it.
72
73## Require it
74
75Turn on **Require single sign-on** under **Test and require**. From then
76on a member uses the workspace only:
77
78- **On the site**, from a session that signed in through your provider in
79 the last day. After a day they go through it again, which is usually
80 instant: your provider remembers them.
81- **With an access token, SSH key or git credentials**, once they have
82 linked their account.
83
84A member who has not keeps their place but cannot use the workspace: its
85private repositories, pages and API answer as if they were not a member,
86including repositories they have a role on directly, and every page shows
87a notice with a link to sign in through your provider.
88
89**Owners are never held out**, so a provider that breaks or a certificate
90that expires never locks you out of your own workspace. Outside
91collaborators are not asked: they are not your provider's people.
92
93## Linked people
94
95The page lists everyone who has signed in through your provider, who they
96are there, and when they last did. **Unlink** someone to let them link
97another account at your provider; their sessions go through it again.
98Each account at your provider links to one g1t account, and each g1t
99account to one account at your provider.
100
101Changing the provider itself (the protocol, the issuer, or the SAML entity
102id) unlinks everyone and stops requiring it, until someone has signed in
103through the new one. Changing the client, the scopes or the certificate
104keeps everyone linked.
105
106## What g1t checks
107
108- **OpenID Connect and OAuth 2.0** use the authorization code flow with
109 PKCE. For OpenID Connect, the ID token must be issued by your issuer, for
110 your client id, unexpired, and answer this sign-in's nonce. g1t receives
111 it straight from your provider's token endpoint over TLS.
112- **SAML** responses must be signed, the assertion or the whole response,
113 with RSA and SHA-256, SHA-384 or SHA-512, by one of the certificates you
114 saved. The response must answer the request g1t sent (sign-ins started
115 at your provider are refused), be addressed to the workspace's assertion
116 consumer service, name g1t's entity id as the audience, come from your
117 provider's entity id, and be in its validity window. Leave the assertion
118 unencrypted: it reaches g1t over HTTPS.
119
120## If the plan ends
121
122The settings stay. Members cannot sign in through your provider until the
123plan starts again, so a workspace that requires it holds its members out
124meanwhile; owners can still turn the requirement off. Turning it off and
125removing it never need a plan.
126
127## Remove it
128
129**Danger zone → Remove** forgets your provider and who everyone is there,
130and stops requiring it. Members keep their place in the workspace.
131
132## Audit log
133
134Recorded in the workspace's [audit log](/guides/audit-log/):
135`sso.created`, `sso.updated`, `sso.deleted`, `sso.required`,
136`sso.not_required`, `sso.identity_linked`, `sso.identity_unlinked`, and
137`member.joined_by_sso`.
138
139## API and MCP
140
141Owners can do all of it with an access token, through the REST API or the
142`workspace` tool's actions on the MCP server:
143
144| | REST | MCP action | Scope |
145| --- | --- | --- | --- |
146| Read it, with where to point the provider | `GET /workspaces/{workspace}/sso` | `get_sso` | `workspace:read` |
147| Set it up or change it | `PUT /workspaces/{workspace}/sso` | `configure_sso` | `workspace:admin` |
148| Require it, or stop | `PUT /workspaces/{workspace}/sso/required` | `set_sso_required` | `workspace:admin` |
149| Remove it | `DELETE /workspaces/{workspace}/sso` | `delete_sso` | `workspace:admin` |
150| The linked people | `GET /workspaces/{workspace}/sso/identities` | `list_sso_identities` | `access:read` |
151| Unlink someone | `DELETE /workspaces/{workspace}/sso/identities/{username}` | `unlink_sso_identity` | `access:admin` |
152
153`configure_sso` takes `protocol` (`oidc`, `oauth2` or `saml`) and the
154protocol's fields as the page names them: `issuer`, `client_id`,
155`client_secret`, `scopes`; `authorization_url`, `token_url`,
156`userinfo_url`, `subject_claim`, `email_claim`; `idp_entity_id`,
157`idp_sso_url`, `certificate` (PEM). Its answer, like `get_sso`'s, has
158`service_provider`: the `redirect_uri`, `entity_id`, `acs_url`,
159`metadata_url` and `sign_in_url` to give your provider and your people.
160The client secret is never returned.
161
162```sh
163curl -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": "…"}'
164```
165
166Signing in through the provider is a trip in the browser, so it has no
167API: send people to `sign_in_url`.
168
169## Not yet
170
171Provisioning and deprovisioning with SCIM is not available yet. Until it
172is, someone you remove at your provider keeps their g1t session for up to
173a day and their tokens until an owner removes them from the workspace or
174unlinks them.