Skip to content

Register an identity provider (OIDC or SAML)

View as Markdown
POST
/v1/auth/providers
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.

Idempotency-Key
string
>= 1 characters

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).

Media typeapplication/json
One of: discriminator: kind

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
providerId
required
string
>= 1 characters
displayName

The name a sign-in page shows (“Sign in with …”). Default: providerId.

string
>= 1 characters
domains

The email domains whose people sign in with this provider (lowercase, e.g. acme.com): how an email-first sign-in page finds it.

Array<string>
join

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.

string
Allowed values: invite domain
signIn
One of:
object
redirectUri
required
string format: uri
metadata
object
key
additional properties
any
kind
required
string
Allowed value: oidc
issuer
required
string format: uri
clientId
required
string
>= 1 characters
clientSecretRef
required

Opaque reference resolved server-side. Never a plaintext secret.

string
>= 1 characters
scopes

Default openid email profile.

Array<string>
authorizationEndpoint
string format: uri
tokenEndpoint
string format: uri
userinfoEndpoint
string format: uri
jwksEndpoint
string format: uri
claimMapping

Per-provider claim mapping. All fields optional; closer to OIDC defaults (sub/email/name) → fewer overrides needed.

object
userId
string
>= 1 characters
email
string
>= 1 characters
displayName
string
>= 1 characters
scopes

Claim path + optional delimiter for extracting Kindgi OAuth scopes from provider claims. When absent, scopes come from the token response scope field instead.

object
claim
required
string
>= 1 characters
delimiter
string
metadata
Array<string>

Provider registered.

Media typeapplication/json
object
providerId
required
string
>= 1 characters
provider
One of: discriminator: kind

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
providerId
required
string
>= 1 characters
displayName

The name a sign-in page shows (“Sign in with …”). Default: providerId.

string
>= 1 characters
domains

The email domains whose people sign in with this provider (lowercase, e.g. acme.com): how an email-first sign-in page finds it.

Array<string>
join

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.

string
Allowed values: invite domain
signIn
One of:
object
redirectUri
required
string format: uri
metadata
object
key
additional properties
any
kind
required
string
Allowed value: oidc
issuer
required
string format: uri
clientId
required
string
>= 1 characters
clientSecretRef
required

Opaque reference resolved server-side. Never a plaintext secret.

string
>= 1 characters
scopes

Default openid email profile.

Array<string>
authorizationEndpoint
string format: uri
tokenEndpoint
string format: uri
userinfoEndpoint
string format: uri
jwksEndpoint
string format: uri
claimMapping

Per-provider claim mapping. All fields optional; closer to OIDC defaults (sub/email/name) → fewer overrides needed.

object
userId
string
>= 1 characters
email
string
>= 1 characters
displayName
string
>= 1 characters
scopes

Claim path + optional delimiter for extracting Kindgi OAuth scopes from provider claims. When absent, scopes come from the token response scope field instead.

object
claim
required
string
>= 1 characters
delimiter
string
metadata
Array<string>
Example
{
"provider": {
"join": "invite",
"kind": "oidc"
}
}

Malformed request body.

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": {},
"requestId": "example"
}
}

Missing / malformed / expired / revoked bearer token.

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
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.

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": {},
"requestId": "example"
}
}

Idempotency-Key was reused with a different body, or resource-state conflict (identity-provider-already-registered: a provider with this id is registered). Or this deployment has no secrets store (identity-providers-need-secrets-store, KINDGI_SECRETS_BACKEND): a provider’s client secret and keys are references into one, so no provider is added or changed until it has one.

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
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).

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
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).

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": {},
"requestId": "example"
}
}

Server error (unmapped domain code or framework crash).

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": {},
"requestId": "example"
}
}

See also