Authentication
Authentication delegates user identity to one configured OAuth2 or OpenID Connect provider, then keeps the Polygent browser session with its own short-lived tokens in secure cookies.
Polygent never stores user passwords. All authentication settings live under the Login section of appsettings.json (or Login__* environment variables) and require an API restart.
Sign-in methods
Choose exactly one identity provider for the deployment.
| Method | Login:LoginType | Use |
|---|---|---|
| Google OAuth2 | Google | Google Workspace teams |
| Microsoft OAuth2 | Microsoft | Microsoft 365 / Entra ID teams |
| Generic OpenID Connect | OpenIdConnect | Okta, Auth0, Keycloak, or any OIDC-compliant identity provider |
Only one provider is active at a time.
Login section reference
These restart-required settings define identity-provider integration, token lifetime, and registration policy.
| Setting | Type | Default | Description |
|---|---|---|---|
Login:LoginType | enum | Google | Google, Microsoft, or OpenIdConnect. |
Login:ClientId | string | empty | OAuth client ID. |
Login:ClientSecret | string | empty | OAuth client secret. Prefer an environment variable over the file. |
Login:ClientUrl | string | https://localhost:5173 | Public URL users return to after sign-in. Set to your public HTTPS URL. |
Login:TenantId | string | empty | Microsoft only. common (or empty) for any account, or a tenant ID to restrict sign-in. |
Login:Authority | string | empty | OpenID Connect issuer URL. Required for OpenIdConnect; startup fails when empty. |
Login:OidcDisplayName | string | empty (SSO) | Label on the sign-in button. |
Login:OidcScopes | string | empty | Extra scopes added to openid profile email (space- or comma-separated). |
Login:EnableSeamlessSso | bool | false | Microsoft only. Skip the account picker when the user already has a Microsoft session. |
Login:AllowNewUsers | bool | true | Create an account automatically the first time a new email signs in. |
Login:AccessTokenMinutesLifetime | int | 15 | Access token lifetime in minutes. |
Login:RefreshTokenDaysLifetime | int | 7 | Refresh token lifetime in days. |
Redirect URIs
The identity provider returns users to the Polygent API host after authentication, so register the API's public URL as the redirect.
| Provider | Redirect URI to register |
|---|---|
https://<public-host>/signin-google | |
| Microsoft | https://<public-host>/signin-microsoft |
| OpenID Connect | https://<public-host>/signin-oidc |
<public-host> is the host users reach Polygent on (the same origin as Login:ClientUrl, because the web client is served by the API). Behind a TLS-terminating reverse proxy, set ASPNETCORE_FORWARDEDHEADERS_ENABLED=true and preserve the original Host header; otherwise Polygent sends an http:// redirect URI and the provider rejects the sign-in. See Configuration Overview → Reverse proxy and TLS.
Google OAuth2
Google authentication uses one Web application OAuth client.
- In Google Cloud Console, open APIs & Services → Credentials and create an OAuth client of type Web application.
- Add
https://<public-host>/signin-googleunder Authorized redirect URIs. - Configure Polygent:
{
"Login": {
"LoginType": "Google",
"ClientId": "your-client-id.apps.googleusercontent.com",
"ClientSecret": "your-client-secret",
"ClientUrl": "https://polygent.example.com"
}
}
Microsoft OAuth2
Microsoft authentication uses an Entra ID app registration and either your tenant or the multi-tenant common endpoint.
- In the Azure portal, open Microsoft Entra ID → App registrations and register an application.
- Under Authentication, add a Web redirect URI
https://<public-host>/signin-microsoft. - Create a client secret under Certificates & secrets.
- Configure Polygent:
{
"Login": {
"LoginType": "Microsoft",
"ClientId": "your-application-id",
"ClientSecret": "your-client-secret",
"TenantId": "your-tenant-id",
"ClientUrl": "https://polygent.example.com"
}
}
Use your tenant ID to restrict sign-in to your organization; common allows any Microsoft account.
Generic OpenID Connect (Okta / Auth0 / Keycloak)
Generic OIDC connects Polygent to one standards-compliant issuer; endpoints are discovered from {Authority}/.well-known/openid-configuration.
- Register a confidential (web) client at your identity provider with redirect URI
https://<public-host>/signin-oidc. - Release the
emailandname(orpreferred_username) claims to the client. - Configure Polygent:
{
"Login": {
"LoginType": "OpenIdConnect",
"Authority": "https://your-tenant.okta.com/oauth2/default",
"ClientId": "your-client-id",
"ClientSecret": "your-client-secret",
"OidcDisplayName": "Okta",
"OidcScopes": "",
"ClientUrl": "https://polygent.example.com"
}
}
| Identity provider | Authority example |
|---|---|
| Okta | https://your-tenant.okta.com/oauth2/default |
| Auth0 | https://your-tenant.auth0.com/ |
| Keycloak | https://keycloak.example.com/realms/your-realm |
The flow is Authorization Code with PKCE; Polygent reads claims from the user-info endpoint. Use OidcScopes for extra scopes such as groups or offline_access.
Tokens and cookies
Polygent issues and rotates its own tokens after the identity provider completes sign-in.
| Setting | Default | Notes |
|---|---|---|
| Algorithm | RS256 | 2048-bit RSA key generated on first start at {StoragePath}/signing-key.xml |
| Access token | 15 minutes | Login:AccessTokenMinutesLifetime |
| Refresh token | 7 days | Login:RefreshTokenDaysLifetime; rotates on every refresh |
| Cookies | — | HttpOnly, Secure, SameSite=Lax; tokens are never stored in browser storage |
| Clock skew tolerance | 30 seconds | Built in |
Because cookies are Secure, users must reach Polygent over HTTPS (localhost excepted). An existing signing key is validated on startup; if it is corrupt, startup aborts — restore it from backup, or delete it to let Polygent generate a new one (this signs every user out). Protect signing-key.xml with file permissions that allow only the service account.
Expired and revoked refresh tokens are cleaned up automatically. Browser logout is protected by same-origin anti-forgery validation, so another website cannot sign a user out.
User registration and first administrator
The first user to sign in becomes the Admin. Complete this bootstrap with the intended administrator account before opening access to others.
With Login:AllowNewUsers: true (default), any user who authenticates at the identity provider gets an account on first sign-in; restrict who can authenticate at the provider (app assignment, tenant, or group policy). Every new account counts against the license user limit.
With Login:AllowNewUsers: false:
- Existing users sign in normally.
- Users without an account see a registration-disabled error after provider authentication.
- Pre-provision users under Settings → Users → Create User before they sign in.
- On an empty database nobody can sign in, including the first administrator — leave it
trueuntil the first administrator exists.
Managing users
Administrators manage accounts under Settings → Users (requires Manage Users).
- Create User — enter name, email, and optional roles. On first sign-in Polygent matches the account by email; no invitation email is sent, so share the sign-in URL and make sure the email matches the one at the identity provider.
- Block — reversible. The user is rejected on the next request and cannot sign in; their sessions, tickets, and history are kept, and their license seat is freed. Unblocking checks the user limit again.
- Delete — permanent. A user who owns sessions, tickets, plans, automations, host keys, or similar records cannot be deleted; block them instead.
- Active Sessions (separate settings page, requires Manage Users) — list and revoke signed-in devices for every user.
- The last active administrator cannot be blocked, deleted, or demoted.
Seamless SSO
Seamless SSO skips the Microsoft account picker for users who already have an active Microsoft session. It has no effect for Google or OpenID Connect. With it enabled, a user who has no active Microsoft session receives a sign-in error instead of a prompt, so enable it only where every user is always signed in to the corporate tenant.
Troubleshooting
| Symptom | Check |
|---|---|
| Provider reports a redirect URI mismatch | Register the exact https://<public-host>/signin-* URI; behind a proxy set ASPNETCORE_FORWARDEDHEADERS_ENABLED=true. |
| Sign-in succeeds but the user is sent to localhost | Set Login:ClientUrl to the public URL. |
| Sign-in loops back to the login page | Serve the site over HTTPS; Secure cookies are not stored over plain HTTP. |
| "Registration disabled" error | Login:AllowNewUsers is false; pre-provision the user. |
| New users cannot be created or activated | The license user limit is reached; block unused accounts or extend the license. |
| API fails to start with OpenID Connect | Login:Authority is empty or the discovery document is unreachable from the API host. |
| Everyone was signed out after a restart | The signing key was lost or regenerated; restore signing-key.xml from backup. |
See also
- Permissions — roles and the permission matrix
- Global Settings —
ClientUrland other installation-wide values - Storage — signing key and data-protection key locations