Set up or change the identity provider
const url = 'https://api.asklucy.eu/v1/org/sso/provider';const options = { method: 'PUT', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"kind":"entra","name":"example","client_id":"example","client_secret":"example","tenant_id":"example","issuer":"https://example.com"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PUT \ --url https://api.asklucy.eu/v1/org/sso/provider \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "kind": "entra", "name": "example", "client_id": "example", "client_secret": "example", "tenant_id": "example", "issuer": "https://example.com" }'One provider per organization. The admin registers Lucy at their provider (redirect URI redirect_uri,
scopes openid profile email; for Entra, a web app registration in their tenant with the Microsoft Graph
User.Read permission) and pastes the client ID and secret here. The secret goes to the identity service
in this call and is never kept, returned or logged by Lucy. Accounts are made on first sign-in and matched
to existing ones by verified email.
The same kind again updates the provider: a new client_secret replaces the old one, none keeps it. A
change of provider (kind, client_id, tenant_id or issuer) undoes the last test and stops enforcing.
Audited as org.sso.provider_set (never the secret).
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
Microsoft Entra ID, Google Workspace, or any OpenID Connect provider (Okta, Keycloak, Authentik…).
Optional; the kind’s name when absent.
Required for a new provider; on an update, absent keeps the one the identity service has.
Entra only; the directory (tenant) ID, a GUID. Absent: any work or school account.
oidc only: the issuer URL, whose /.well-known/openid-configuration says the rest.
Responses
Section titled “Responses”OK
object
What to register at the provider as the redirect (reply) URI.
object
Microsoft Entra ID, Google Workspace, or any OpenID Connect provider (Okta, Keycloak, Authentik…).
Shown on the sign-in page and in Lucy.
Entra; null means any work or school account.
The OpenID Connect issuer (oidc only).
Members sign in only through the provider.
A provider, a verified domain and a passed test sign-in.
Example
{ "redirect_uri": "https://id.asklucy.eu/idps/callback", "provider": { "kind": "entra", "test": { "status": "passed" }, "updated_by": { "kind": "person" } }, "domains": [ { "domain": "acme.lu", "dns": { "type": "TXT", "name": "_asklucy-challenge.acme.lu", "value": "asklucy-domain-verification=4f1c0e9b2a7d4c6e8b1f3a5d7c9e0b2d" } } ]}The request is invalid; errors lists what’s wrong.
RFC 9457 problem details.
object
For quota-exceeded, the window that is used up.
object
Null for a rolling window that hasn’t started.
organization when the organization’s budget is closer to running out than the member’s own limit.
Field-level problems (400 only).
object
JSON pointer into the request body.
Example
{ "type": "https://docs.asklucy.eu/errors/answer-in-progress", "quota": { "window": "five_hours", "limited_by": "personal", "request": { "status": "pending" } }}Headers
Section titled “Headers”Unique per request; quote it to support.
Missing, expired or invalid token.
RFC 9457 problem details.
object
For quota-exceeded, the window that is used up.
object
Null for a rolling window that hasn’t started.
organization when the organization’s budget is closer to running out than the member’s own limit.
Field-level problems (400 only).
object
JSON pointer into the request body.
Example
{ "type": "https://docs.asklucy.eu/errors/answer-in-progress", "quota": { "window": "five_hours", "limited_by": "personal", "request": { "status": "pending" } }}Headers
Section titled “Headers”Unique per request; quote it to support.
The token is valid but lacks the role this needs.
RFC 9457 problem details.
object
For quota-exceeded, the window that is used up.
object
Null for a rolling window that hasn’t started.
organization when the organization’s budget is closer to running out than the member’s own limit.
Field-level problems (400 only).
object
JSON pointer into the request body.
Example
{ "type": "https://docs.asklucy.eu/errors/answer-in-progress", "quota": { "window": "five_hours", "limited_by": "personal", "request": { "status": "pending" } }}Headers
Section titled “Headers”Unique per request; quote it to support.
Another service Lucy needed didn’t answer as it should (the problem’s type says which).
RFC 9457 problem details.
object
For quota-exceeded, the window that is used up.
object
Null for a rolling window that hasn’t started.
organization when the organization’s budget is closer to running out than the member’s own limit.
Field-level problems (400 only).
object
JSON pointer into the request body.
Example
{ "type": "https://docs.asklucy.eu/errors/answer-in-progress", "quota": { "window": "five_hours", "limited_by": "personal", "request": { "status": "pending" } }}Headers
Section titled “Headers”Unique per request; quote it to support.
Storage for this isn’t configured on the server (e.g. …/errors/desktop-unavailable).
RFC 9457 problem details.
object
For quota-exceeded, the window that is used up.
object
Null for a rolling window that hasn’t started.
organization when the organization’s budget is closer to running out than the member’s own limit.
Field-level problems (400 only).
object
JSON pointer into the request body.
Example
{ "type": "https://docs.asklucy.eu/errors/answer-in-progress", "quota": { "window": "five_hours", "limited_by": "personal", "request": { "status": "pending" } }}Headers
Section titled “Headers”Unique per request; quote it to support.