Register an identity provider (OIDC or SAML)
const url = 'https://example.com/v1/auth/providers';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"providerId":"example","displayName":"example","domains":["example"],"join":"invite","signIn":{"redirectUri":"https://example.com"},"metadata":{},"kind":"oidc","issuer":"https://example.com","clientId":"example","clientSecretRef":"example","scopes":["example"],"authorizationEndpoint":"https://example.com","tokenEndpoint":"https://example.com","userinfoEndpoint":"https://example.com","jwksEndpoint":"https://example.com","claimMapping":{"userId":"example","email":"example","displayName":"example","scopes":{"claim":"example","delimiter":"example"},"metadata":["example"]}}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://example.com/v1/auth/providers \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "providerId": "example", "displayName": "example", "domains": [ "example" ], "join": "invite", "signIn": { "redirectUri": "https://example.com" }, "metadata": {}, "kind": "oidc", "issuer": "https://example.com", "clientId": "example", "clientSecretRef": "example", "scopes": [ "example" ], "authorizationEndpoint": "https://example.com", "tokenEndpoint": "https://example.com", "userinfoEndpoint": "https://example.com", "jwksEndpoint": "https://example.com", "claimMapping": { "userId": "example", "email": "example", "displayName": "example", "scopes": { "claim": "example", "delimiter": "example" }, "metadata": [ "example" ] } }'Unique per tenant on providerId: re-registering a known provider returns 409 identity-provider-already-registered; change it with PATCH /v1/auth/providers/{providerId}, which keeps its sign-in URLs. Secrets are given by reference (clientSecretRef, spSigningKeyRef…); a clientSecret (or a raw key) is refused with 400 invalid-provider-config, as is allowedRedirectUris, which nothing would enforce (sign-in runs in the deployment, at its own callback URL). The deployment may check the configuration (OIDC discovery, SAML metadata): 422 identity-provider-invalid says what failed. The answer carries the stored provider when the deployment returns it, with signIn: what to give the identity provider.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Header Parameters
Section titled “Header Parameters”Caller-supplied idempotency key, scoped to the caller: the same key from someone else in the tenant is their own request (from 0.1.5). Retries with the same key return the original response byte-identical (per docs/API-ROUTE-CONVENTIONS.md §3.1). A retry sent while the first request still runs is answered 409 idempotency-key-in-flight with Retry-After, on a runtime whose store holds keys (from 0.1.5); retry after it, and you get the first request’s answer. An answer that carries a secret (a new API key or public run token, a session token, a generated signing secret) isn’t kept: a retry gets 409 idempotency-key-replay-withheld, with the first request’s status and when it succeeded (from 0.1.5).
Request Bodyrequired
Section titled “Request Bodyrequired”An OpenID Connect identity provider people sign in with. The endpoints come from the issuer’s discovery document when absent, and are returned once the deployment has them.
object
The name a sign-in page shows (“Sign in with …”). Default: providerId.
The email domains whose people sign in with this provider (lowercase, e.g. acme.com): how an email-first sign-in page finds it.
Who may sign in the first time: invite (default) only people a tenant admin added; domain also anyone from one of domains, once the deployment has verified them.
object
Opaque reference resolved server-side. Never a plaintext secret.
Default openid email profile.
Per-provider claim mapping. All fields optional; closer to OIDC defaults (sub/email/name) → fewer overrides needed.
object
Claim path + optional delimiter for extracting Kindgi OAuth scopes from provider claims. When absent, scopes come from the token response scope field instead.
object
A SAML 2.0 identity provider people sign in with: its metadata XML, or its entity ID, single sign-on URL and signing certificates. Keys are given as references, never as keys.
object
The name a sign-in page shows (“Sign in with …”). Default: providerId.
The email domains whose people sign in with this provider (lowercase, e.g. acme.com): how an email-first sign-in page finds it.
Who may sign in the first time: invite (default) only people a tenant admin added; domain also anyone from one of domains, once the deployment has verified them.
object
The IdP’s single sign-on URL (HTTP-Redirect binding).
The IdP’s signing certificates (PEM); several during a rollover.
Opaque reference to the service provider’s signing key, for IdPs that require signed AuthnRequests. Never a plaintext key.
Opaque reference to the key that decrypts encrypted assertions. Never a plaintext key.
Require signed assertions. Default true.
Assertion attribute names. Defaults: userId = the NameID, email = email.
object
Responses
Section titled “Responses”Provider registered.
object
An OpenID Connect identity provider people sign in with. The endpoints come from the issuer’s discovery document when absent, and are returned once the deployment has them.
object
The name a sign-in page shows (“Sign in with …”). Default: providerId.
The email domains whose people sign in with this provider (lowercase, e.g. acme.com): how an email-first sign-in page finds it.
Who may sign in the first time: invite (default) only people a tenant admin added; domain also anyone from one of domains, once the deployment has verified them.
object
Opaque reference resolved server-side. Never a plaintext secret.
Default openid email profile.
Per-provider claim mapping. All fields optional; closer to OIDC defaults (sub/email/name) → fewer overrides needed.
object
Claim path + optional delimiter for extracting Kindgi OAuth scopes from provider claims. When absent, scopes come from the token response scope field instead.
object
A SAML 2.0 identity provider people sign in with: its metadata XML, or its entity ID, single sign-on URL and signing certificates. Keys are given as references, never as keys.
object
The name a sign-in page shows (“Sign in with …”). Default: providerId.
The email domains whose people sign in with this provider (lowercase, e.g. acme.com): how an email-first sign-in page finds it.
Who may sign in the first time: invite (default) only people a tenant admin added; domain also anyone from one of domains, once the deployment has verified them.
object
The IdP’s single sign-on URL (HTTP-Redirect binding).
The IdP’s signing certificates (PEM); several during a rollover.
Opaque reference to the service provider’s signing key, for IdPs that require signed AuthnRequests. Never a plaintext key.
Opaque reference to the key that decrypts encrypted assertions. Never a plaintext key.
Require signed assertions. Default true.
Assertion attribute names. Defaults: userId = the NameID, email = email.
object
Example
{ "provider": { "join": "invite", "kind": "oidc" }}Malformed request body.
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}Missing / malformed / expired / revoked bearer token.
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}Not a tenant admin (permission-denied), or this deployment’s operator manages sign-in (identity-providers-operator-managed, KINDGI_AUTH_TENANT_PROVIDERS=off): only the deployment’s own token can change its providers.
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}Idempotency-Key was reused with a different body, or resource-state conflict.
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}The request body is over the API’s limit (request-too-large; details.maxBytes says how much).
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}The deployment could not use the configuration, or kind is oauth2, a plain OAuth 2.0 provider, which sign-in does not use (identity-provider-invalid).
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}Server error (unmapped domain code or framework crash).
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}See also
GET /v1/auth/providers: List identity providers configured for the tenantGET /v1/auth/providers/{providerId}: Get one identity providerPATCH /v1/auth/providers/{providerId}: Change an identity provider, keeping its sign-in URLsGET /v1/auth/providers/{providerId}/sign-in: What to give the identity provider, before or after registering- Error code
identity-provider-invalid - Error code
identity-providers-operator-managed - Error code
permission-denied - Error code
request-too-large - Every error code