Skip to content

Single sign-on

Set up the workspace's single sign-on, or change it; a field left out keeps what is saved for the same protocol. oidc: issuer (read for its discovery document first), client_id, client_secret, scopes (openid email profile by default). oauth2: authorization_url, token_url, userinfo_url, client_id, client_secret, scopes, subject_claim (sub, then id, by default) and email_claim (email). saml: idp_entity_id, idp_sso_url and certificate (the provider's signing certificates, PEM; several while rotating). client_secret and certificate left out keep what is saved. allow_join (false by default) lets anyone the provider signs in join as a member; join_domains limits that to addresses the provider vouches for at those domains.

PUT/workspaces/{workspace}/sso

Moving to another provider (protocol, issuer or entity id) unlinks everyone and stops requiring it. Needs a paid plan. Returns what get_sso does. Recorded as sso.created or sso.updated. Owners only, as people.

  • Authentication: Required. Send an access token as Authorization: Bearer.
  • MCP tool: workspace with action configure_sso, and the same inputs
  • Scope: An access token needs workspace:admin.
Name Type Required Description
workspace string Yes The workspace’s name, e.g. “acme”.

Send a JSON object. Names are snake_case, as in responses; the camelCase spelling is accepted too.

Name Type Required Description
protocol string Yes How g1t speaks to the provider. One of oidc, oauth2, saml.
issuer string No oidc: the issuer, where its /.well-known/openid-configuration lives.
client_id string No oidc, oauth2: the client id.
client_secret string No oidc, oauth2: the client secret; kept encrypted, never returned. Left out keeps the one saved.
scopes string No oidc, oauth2: space-separated scopes.
authorization_url string No oauth2: the authorization endpoint (https).
token_url string No oauth2: the token endpoint (https).
userinfo_url string No oauth2: the userinfo endpoint (https).
subject_claim string No oauth2: the userinfo claim that is the person’s stable id; a dotted path works.
email_claim string No oauth2: the userinfo claim that is their address.
idp_entity_id string No saml: the provider’s entity id (its issuer).
idp_sso_url string No saml: where the provider takes requests (HTTP-Redirect, https).
certificate string No saml: the provider’s signing certificates, PEM. Left out keeps the ones saved.
allow_join boolean No Anyone the provider signs in joins as a member when they first sign in through it. False by default; leave it off for a provider anyone can sign in to.
join_domains array of strings No When joining is on, only people whose address the provider vouches for (OpenID’s email_verified, or a signed SAML assertion) is at one of these domains, such as [“acme.com”]. Empty: anyone it signs in.
curl -X PUT https://api.g1t.sh/workspaces/flagon-io/sso \
-H "Authorization: Bearer $G1T_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"protocol": "oidc"
}'

A successful request answers 200 with:

{
"slug": "flagon-io",
"connection": {
"id": "sso_01m54gq2v0e8e3c5yj6k9t1r2a",
"protocol": "saml",
"config": {
"idp_entity_id": "http://www.okta.com/exk1a2b3c4d5",
"idp_sso_url": "https://flagon.okta.com/app/flagon_g1t/exk1a2b3c4d5/sso/saml",
"certificates": [
"MIICsDCCAZigAwIBAgICA+gwDQYJKoZIhvcNAQELBQAw"
]
},
"has_client_secret": false,
"certificates": [
{
"fingerprint": "3F:A1:9C:22:7B:E0:44:D1:8A:6F:0B:93:12:C7:5E:AA:41:08:DD:6C:39:F2:B5:7E:90:1A:C3:58:24:EF:6B:0D"
}
],
"allow_join": true,
"tested_at": "2026-10-17T09:12:44.000Z",
"tested_by": "syntaqx",
"created_at": "2026-10-17T09:05:10.000Z",
"updated_at": "2026-10-17T09:05:10.000Z"
},
"required": true,
"you_linked": true,
"identities": [
{
"username": "syntaqx",
"subject": "chase@flagon.io",
"email": "chase@flagon.io",
"linked_at": "2026-10-17T09:12:44.000Z",
"last_used_at": "2026-10-17T14:02:31.000Z"
}
],
"service_provider": {
"redirect_uri": "https://g1t.sh/auth/sso/wsp_01m3xbtsa9d3b4c5e6f7g8h9j0/callback",
"entity_id": "https://g1t.sh/auth/sso/wsp_01m3xbtsa9d3b4c5e6f7g8h9j0/metadata",
"acs_url": "https://g1t.sh/auth/sso/wsp_01m3xbtsa9d3b4c5e6f7g8h9j0/saml",
"metadata_url": "https://g1t.sh/auth/sso/wsp_01m3xbtsa9d3b4c5e6f7g8h9j0/metadata",
"sign_in_url": "https://g1t.sh/auth/sso/flagon-io",
"scim_url": "https://api.g1t.sh/scim/v2/wsp_01m3xbtsa9d3b4c5e6f7g8h9j0"
}
}

A failed request answers with one of these statuses and a body like {"error": {"code": "not_found", "message": "Repository not found."}}. See errors.

Status Code When
401 unauthenticated A token is required, or the one sent is not valid.
403 forbidden The token is valid but not allowed to do this, such as a member-only change, or a token without the scope it needs.
404 not_found It does not exist, or you cannot see it.
409 conflict The request conflicts with the current state.
422 invalid The input is not valid. message says which field and why.