Introduction to single sign-on (SSO) in Nightingale v8, including configuration and usage of LDAP, CAS, OAuth2, OIDC.
Nightingale supports single sign-on (SSO), with support for protocols such as LDAP, CAS, OAuth2, and OIDC. The SSO feature allows users to log into Nightingale through a unified identity authentication system, simplifying user management and login processes, while also reducing security risks.
For CAS, OAuth2, and OIDC, after a user logs into Nightingale via SSO, Nightingale will check whether the currently logged-in user exists in the Nightingale user table. If not, a user will be automatically created. If yes, Nightingale will overwrite the existing user information in Nightingale with the user information in SSO (provided that the configuration item CoverAttributes = true, which will be introduced later). The advantage of this is that users only need to maintain their phone number and email in SSO, and Nightingale will automatically sync at login time (of course, only at login time, so the user must log into Nightingale via SSO at least once, otherwise Nightingale will not have the user’s information).
Configure OIDC
This is the most recommended method. If your SSO supports both OIDC and OAuth2, OIDC is recommended.
Configuration Item Description
The following is a description of each OIDC configuration item:
# Whether to enable OIDC single sign-on. Nightingale can enable multiple SSO methods simultaneously
Enable = false
# The login page will display a hyperlink to the SSO login address. DisplayName is used to configure the text content of the hyperlink
DisplayName = 'OIDC'
# After IDC login verification passes, you need to redirect to Nightingale. Below is the callback address used by Nightingale for OIDC
# You need to replace n9e.com with your Nightingale address. /callback is the fixed path
RedirectURL = 'http://n9e.com/callback'
# OIDC SSO server root address. Replace with your OIDC server address
SsoAddr = 'http://sso.example.org'
# OIDC SSO server logout address. When the user clicks logout in Nightingale, it will redirect to this address to complete the synchronized logout of Nightingale and SSO
SsoLogoutAddr = 'http://sso.example.org/session/end'
# The ClientId and ClientSecret assigned to Nightingale by OIDC. Must be configured. Usually obtained when registering the application on the SSO server
ClientId = ''
ClientSecret = ''
# When a user logs into Nightingale via SSO and Nightingale finds that the user does not exist in the Nightingale user table, a user will be automatically created
# When creating a user, a role needs to be assigned to the user. Below is the list of default roles
DefaultRoles = ['Standard']
# When a user logs into Nightingale via SSO, Nightingale will request user information from the SSO server and write the user information to the Nightingale user table
# If CoverAttributes = true, the existing user information in Nightingale will be overwritten, such as phone number, email, etc. Usually configured as true
CoverAttributes = true
# Scope is a concept in the OIDC protocol, indicating the list of user information fields requested. Usually the following fields
Scopes = ['openid', 'profile', 'email', 'phone']
# The user information fields in OIDC and the user information fields in Nightingale are not 100% one-to-one
# So the following configures: which fields in OIDC each Nightingale field corresponds to
# Username, Nickname, Phone, Email are the user information fields in Nightingale
# The following sub, nickname, phone_number, email are the user field names in OIDC
# Please adjust according to the user information fields of your OIDC server
[Attributes]
Username = 'sub'
Nickname = 'nickname'
Phone = 'phone_number'
Email = 'email'
Configuration FAQ
1. The user can log in successfully using OIDC, but the username, phone number, etc. cannot be obtained
You can adjust the log level of Nightingale to DEBUG (adjust in config.toml), then restart Nightingale, filter the log keyword: sso_exchange_user: oidc info, then test the login again, you can see what user information was obtained from the SSO system, and then adjust the field mapping in Attributes according to the actual situation.
Authing Integration Demo
The following uses Authing as the OIDC SSO server for demonstration. First, create an application on Authing and get the ClientId and ClientSecret.

Then configure OIDC information in Nightingale:
Enable = true
DisplayName = 'OIDC'
RedirectURL = 'http://192.168.127.151:17000/callback'
SsoAddr = 'https://n9e.authing.cn/oidc'
SsoLoginOutAddr = 'https://n9e.authing.cn/oidc/session/end'
ClientId = '65befb5b452d4854f9731b9b'
ClientSecret = '0af4...'
CoverAttributes = true
DefaultRoles = ['Standard']
Scopes = ['openid', 'profile', 'username', 'email', 'phone']
[Attributes]
Username = 'username'
Nickname = 'nickname'
Phone = 'phone_number'
Email = 'email'
The 192.168.127.151:17000 above is the Nightingale address for my test environment. You need to replace it with your own Nightingale address.
Feishu Integration Demo
Feishu also supports the OIDC protocol. Let’s also explain this method. Refer to Feishu’s official documentation to create an application: Configure Application Single Sign-On, related configurations:
- Authorization mode: You can select both authorization_code and refresh_token
- Scope: You can select openid profile email phone offline_access
- Callback address: Fill in
http://n9e.com/callback. Note to replacen9e.comwith your Nightingale address, which needs to be reachable from the public network, unless your Feishu is also deployed in a private intranet
After configuration, you can get the Issuer (i.e., SSO Server address), ClientId, and ClientSecret, and configure them in Nightingale. In addition, you can also get the SSO Logout address, which is an address like this:
https://anycross.feishu.cn/sso/....../oidc/revoke
This address is also configured in Nightingale’s SsoLogoutAddr. Although this address is configured, it cannot achieve linked logout. Below is the official explanation from Feishu documentation:
Since the login state of the SSO application is derived from the Feishu login state, single sign-out is not supported. That is, when the SSO application logs out, Feishu cannot be logged out at the same time. Although the platform provides a single sign-out address, this address is provided to prevent third-party systems from setting it as a required field, and the address itself does not take effect.
The final configuration in Nightingale is as follows:
Enable = true
DisplayName = 'OIDC'
RedirectURL = 'http://n9e.com/callback'
SsoAddr = 'https://anycross.feishu.cn/sso/XXXXX'
SsoLoginOutAddr = 'https://anycross.feishu.cn/sso/XXXXX/oidc/revoke'
ClientId = 'xxx'
ClientSecret = 'xxx'
CoverAttributes = true
DefaultRoles = ['Standard']
Scopes = ['openid', 'profile', 'email', 'phone']
[Attributes]
Username = 'name'
Nickname = 'name'
Phone = 'phone_number'
Email = 'email'
The
n9e.comabove needs to be replaced with your own Nightingale address, which needs to be reachable from the public network, unless your Feishu is also deployed in a private intranet.
Keycloak Integration Demo
A community member has previously written an article on integrating Grafana and Nightingale with Keycloak. You can refer to: Deep Integration of Grafana and Nightingale through Keycloak.
Configure OAuth2
If your SSO supports both OIDC and OAuth2, OIDC is recommended. Use OAuth2 only if there is no other choice. OAuth2 has many pitfalls.
Configuration Item Description
# Whether to enable OAuth2 single sign-on. Nightingale can enable multiple SSO methods simultaneously
Enable = false
# The login page will display a hyperlink to the SSO login address. DisplayName is used to configure the text content of the hyperlink
DisplayName = 'OAuth2'
# After SSO login verification passes, you need to redirect to Nightingale. Below is the callback address used by Nightingale for OAuth2
# You need to replace n9e.com with your Nightingale address. /callback/oauth is the fixed path
RedirectURL = 'http://n9e.com/callback/oauth'
# OAuth2 SSO server root address. Replace with your OAuth2 server address
SsoAddr = 'https://sso.example.com/oauth2/authorize'
# OAuth2 SSO server logout address. When the user clicks logout in Nightingale, it will redirect to this address to complete the synchronized logout of Nightingale and SSO
SsoLogoutAddr = 'https://sso.example.com/oauth2/authorize/session/end'
# Address for obtaining OAuth2 token
TokenAddr = 'https://sso.example.com/oauth2/token'
# User information address provided by OAuth2. Nightingale will get user information through this address
UserInfoAddr = 'https://sso.example.com/api/v1/user/info'
# When getting user information from OAuth2, the token obtained in the previous step needs to be placed in the request header
# The token can be placed in the header, or in formdata or querystring. Configure according to the requirements of your OAuth2 server
TranTokenMethod = 'header'
# The ClientId and ClientSecret assigned to Nightingale by OAuth2. Must be configured. Usually obtained when registering the application on the SSO server
ClientId = ''
ClientSecret = ''
# When a user logs into Nightingale via SSO and Nightingale finds that the user does not exist in the Nightingale user table, a user will be automatically created
# When creating a user, a role needs to be assigned to the user. Below is the list of default roles
DefaultRoles = ['Standard']
# When a user logs into Nightingale via SSO, Nightingale will request user information from the SSO server and write the user information to the Nightingale user table
# If CoverAttributes = true, the existing user information in Nightingale will be overwritten, such as phone number, email, etc. Usually configured as true
CoverAttributes = true
# Whether the JSON format data returned when getting user data from OAuth2 is an array. Configure according to the return format of your OAuth2 server
# If it is an array, Nightingale will take the first element as the user information
UserinfoIsArray = false
# Prefix of OAuth2 user information. Usually 'data', meaning there will be a 'data' field in the returned JSON data containing the user information
UserinfoPrefix = 'data'
# Scope is a concept in the OAuth2 protocol, indicating the list of user information fields requested. Usually the following fields
Scopes = ['profile', 'email', 'phone']
# The user information fields in OAuth2 and the user information fields in Nightingale are not 100% one-to-one
# So the following configures: which fields in OAuth2 each Nightingale field corresponds to
# Username, Nickname, Phone, Email are the user information fields in Nightingale
# The following sub, nickname, phone_number, email are the user field names in OAuth2
# Please adjust according to the user information fields of your OAuth2 server
[Attributes]
Username = 'sub'
Nickname = 'nickname'
Phone = 'phone_number'
Email = 'email'
Authing Integration Demo
Using Authing as the OAuth2 SSO server for demonstration. First, enable OAuth2 on Authing. The configuration example is as follows:

Then configure OAuth2 information in Nightingale:
Enable = true
DisplayName = 'OAuth2'
RedirectURL = 'http://192.168.127.151:17000/callback/oauth'
SsoAddr = 'https://n9e.authing.cn/oauth/auth'
SsoLogoutAddr = 'https://n9e.authing.cn/oauth/session/end'
TokenAddr = 'https://n9e.authing.cn/oauth/token'
UserInfoAddr = 'https://n9e.authing.cn/oauth/me'
TranTokenMethod = 'header'
ClientId = '65befb5b452d4854f9731b9b'
ClientSecret = '0af4...'
CoverAttributes = true
DefaultRoles = ['Standard']
UserinfoIsArray = false
UserinfoPrefix = ''
Scopes = ['profile', 'username', 'email', 'phone']
[Attributes]
Username = 'username'
Nickname = 'nickname'
Phone = 'phone'
Email = 'email'
The 192.168.127.151:17000 above is the Nightingale address for my test environment. You need to replace it with your own Nightingale address.
Configure CAS
Nightingale also supports single sign-on with the CAS protocol. Compared with OIDC, there are more pitfalls. Use with caution.
Configuration Item Description
# Whether to enable CAS single sign-on. Nightingale can enable multiple SSO methods simultaneously
Enable = false
# The login page will display a hyperlink to the SSO login address. DisplayName is used to configure the text content of the hyperlink
DisplayName = 'CAS'
# After CAS login verification passes, you need to redirect to Nightingale. Below is the callback address used by Nightingale for CAS
# You need to replace n9e.com with your Nightingale address. /callback/cas is the fixed path
RedirectURL = 'http://n9e.com/callback/cas'
# CAS SSO server root address. Replace with your CAS server address
SsoAddr = 'https://cas.example.com/cas'
# CAS SSO server logout address. When the user clicks logout in Nightingale, it will redirect to this address to complete the synchronized logout of Nightingale and SSO
SsoLogoutAddr = 'https://cas.example.com/cas/session/end'
# The LoginPath configuration item is for compatibility with different CAS versions, because login addresses may differ between CAS versions
# If you configure LoginPath, Nightingale will concatenate LoginPath on top of SsoAddr as the login address
# If you do not configure LoginPath, Nightingale's logic is:
# 1. If it finds that SsoAddr contains the p3 keyword, it sets LoginPath = '/login'
# 2. If it does not contain the p3 keyword, it sets LoginPath = '/cas/login'
LoginPath = ''
# When a user logs into Nightingale via SSO and Nightingale finds that the user does not exist in the Nightingale user table, a user will be automatically created
# When creating a user, a role needs to be assigned to the user. Below is the list of default roles
DefaultRoles = ['Standard']
# When a user logs into Nightingale via SSO, Nightingale will request user information from the SSO server and write the user information to the Nightingale user table
# If CoverAttributes = true, the existing user information in Nightingale will be overwritten, such as phone number, email, etc. Usually configured as true
CoverAttributes = true
# The user information fields in CAS and the user information fields in Nightingale are not 100% one-to-one
# So the following configures: which fields in CAS each Nightingale field corresponds to
# Username, Nickname, Phone, Email are the user information fields in Nightingale
# The following sub, nickname, phone_number, email are the user field names in CAS
# Please adjust according to the user information fields of your CAS server
[Attributes]
Username = 'sub'
Nickname = 'nickname'
Phone = 'phone_number'
Email = 'email'
Authing Integration Demo
Using Authing as the CAS SSO server for demonstration. First, enable CAS on Authing. The configuration example is as follows:

Then configure CAS information in Nightingale:
Enable = true
DisplayName = 'CAS'
RedirectURL = 'http://192.168.127.151:17000/callback/cas'
SsoAddr = 'https://n9e.authing.cn/cas-idp/65befb5b452d4854f9731b9b'
SsoLogoutAddr = 'https://n9e.authing.cn/cas-idp/65befb5b452d4854f9731b9b/logout'
LoginPath = '/login'
CoverAttributes = true
DefaultRoles = ['Standard']
[Attributes]
Username = 'username'
Nickname = 'nickname'
Phone = 'phone_number'
Email = 'email'
The 192.168.127.151:17000 above is the Nightingale address for my test environment. You need to replace it with your own Nightingale address.
Configure LDAP
Nightingale also supports authentication login with the LDAP protocol. LDAP is a lightweight directory access protocol commonly used for user authentication and authorization within enterprises. The SSO mechanisms mentioned earlier (OIDC, OAuth2, CAS) cannot periodically sync user information in full to Nightingale, but LDAP can.
LDAP does not have a separate login hyperlink entry on the page. When the user enters the username and password to log into Nightingale, Nightingale first queries user information in the DB. If not found, it automatically checks whether LDAP is enabled. If enabled, it directly uses LDAP for authentication login.
Configuration Item Description
# Whether to enable LDAP single sign-on. Nightingale can enable multiple SSO methods simultaneously
Enable = false
# LDAP server address and port, TLS, StartTLS, etc. configurations
# Please configure according to your own environment
Host = 'ldap.example.org'
Port = 389
TLS = false
StartTLS = true
# Root DN of the LDAP server. You can Google or ask GPT for more information
BaseDn = 'dc=example,dc=org'
# Administrator information. This account needs to have permission to query information for all users
BindUser = 'cn=manager,dc=example,dc=org'
BindPass = '*******'
# Whether to sync the creation of users in LDAP to Nightingale
SyncAddUsers = false
# Whether to sync the deletion of users in LDAP to Nightingale
SyncDelUsers = false
# Sync frequency, unit: seconds
SyncInterval = 86400
# When the user logs in, the filter condition for checking whether the user exists in LDAP
# openldap and AD usually have different filter formats
# The format for openldap may be: (&(uid=%s))
# The format for AD may be (&(sAMAccountName=%s))
# You need to adjust according to your LDAP server type
AuthFilter = '(&(uid=%s))'
# Filter condition for querying all users in LDAP
# Adjust according to your LDAP server type
UserFilter = '(&(uid=*))'
# When a user logs into Nightingale via LDAP and Nightingale finds that the user does not exist in the Nightingale user table, a user will be automatically created
# When creating a user, a role needs to be assigned to the user. Below is the list of default roles
DefaultRoles = ['Standard']
# When a user logs into Nightingale via LDAP, Nightingale will request user information from the LDAP server and write the user information to the Nightingale user table
# If CoverAttributes = true, the existing user information in Nightingale will be overwritten, such as phone number, email, etc. Usually configured as true
CoverAttributes = true
# The user information fields in LDAP and the user information fields in Nightingale are not 100% one-to-one
# So the following configures: which fields in LDAP each Nightingale field corresponds to
# Username, Nickname, Phone, Email are the user information fields in Nightingale
# The following uid, cn, mobile, mail are the user field names in LDAP
# Please adjust according to the user information fields of your LDAP server
[Attributes]
Username = 'uid'
Nickname = 'cn'
Phone = 'mobile'
Email = 'mail'
If you still don’t know how to configure after reading the comments above, you can consult your company’s LDAP administrator, who is likely to know.
Common Questions
Q1: Which SSO protocol should I choose?
A:
- Modern IDPs such as Keycloak / Auth0 / Okta → use OIDC;
- Company self-built AD / LDAP → use LDAP;
- Legacy systems / government SSO → use CAS;
- DingTalk / Feishu enterprise → use their respective dedicated SSO;
- GitHub / Google / self-developed OAuth2 services → use OAuth2.
Q2: Can multiple SSOs be enabled simultaneously?
A: Yes. The n9e login page will display all enabled SSO entries, and users can choose the login method they are accustomed to. However, it is recommended to enable only 1-2 to avoid user confusion.