sso
Login server (or identity provider, IDP) using the ai/sso protocol (version 5) for single-sign on and auth-server to authenticate users.
This repository includes a few separate binaries:
- sso-server is the login server / IDP
- saml-server is a SSO-to-SAML bridge (for third-party software)
- sso-proxy is a reverse HTTP proxy that adds single-sign-on access controls to backends
Configuration
The sso-server daemon requires a YAML configuration file, /etc/sso/server.yml by default. It understands the following attributes:
-
secret_key_file
: path to the Ed25519 secret key (should be exactly 64 bytes) -
public_key_file
: path to the Ed25519 public key (should be exactly 32 bytes) -
domain
: SSO domain -
allowed_services
: a list of regular expressions. A request will be allowed only if the target SSO services matches one of these expressions. -
allowed_exchanges
: a list of regular expression source / destination pairs (dictionaries withsrc_regexp
anddst_regexp
attributes). Exchange requests will only be allowed if source and destination SSO services both match one of these pairs. -
service_ttls
: a list of dictionaries used to set time-to-live for SSO tickets for specific services. Each dictionary should have the following attributes:-
regexp
: regular expression that should match the SSO service -
ttl
: TTL in seconds
-
-
auth_session_lifetime
: time-to-live (in seconds) for the sso-server user authentication session. When it expires, the user will have to login again. -
session_secrets
: a list of two (or more, as long as the number is even) secret keys to use for HTTP cookie-based sessions, in authentication-key, encryption-key pairs. Authentication keys can be 32 bytes (SHA128) or 64 bytes (SHA512), encryption keys should be 16 (AES-128), 24 (AES-192) or 32 (AES-256) bytes long. For key rotation, multiple pairs (old, new) can be specified so that sessions are not immediately invalidated. -
csrf_secret
: a secret key used for CSRF protection -
auth_service
: the service name to use for the authentication request sent to auth-server (generally "sso") -
device_manager
: configuration for the device tracking module:-
auth_key
: a long-term key to authenticate HTTP-based cookies -
geo_ip_data_files
: GeoIP databases to use (in mmdb format), if unset the module will use the default GeoLite2-Country db
-
-
keystore
: configures the connection to the keystore service-
url
: URL for the keystore service -
sharded
: if true, requests to the keystore service will be partitioned according to the user's shard attribute -
tls_config
: client TLS configuration-
cert
: path to the client certificate -
key
: path to the private key -
ca
: path to the CA used to validate the server
-
-
-
http_server
: specifies standard parameters for the HTTP server-
tls
: server-side TLS configuration-
cert
: path to the server certificate -
key
: path to the server's private key -
ca
: path to the CA used to validate clients -
acl
: TLS-based access controls, a list of entries with the following attributes:-
path
is a regular expression to match the request URL path -
cn
is a regular expression that must match the CommonName part of the subject of the client certificate
-
-
-
trusted_forwarders
: list of trusted IP addresses (reverse proxies). If a request comes from here, we will trust the X-Forwarded-Proto and X-Real-IP headers when determining the client IP address -
max_inflight_requests
: maximum number of in-flight requests to allow before server-side throttling kicks in
-
Device tracking
The idea is to track a small amount of non-personally-identifying data for each device, and use it to notify users of unexpected accesses. This information is tracked by the user-meta-server.
It is implemented very simply, with a long-term cookie stored in the browser.
Key store
On login, the login server can unlock the user's key store (see keystore). The associated key will be cleared either on logout, or when the login session expires.
API
The sso-server binary serves different types of HTTP traffic:
- the login/logout interface (user-facing)
- the SSO login endpoint (user-facing)
- the SSO ticket exchange endpoint (service-facing)
The ticket exchange API allows a service (the source) to exchange a
valid SSO ticket for itself with a SSO ticket, for the same user,
meant for a third-party service (destination). Its endpoint is
located at the URL /exchange
and it accepts the following query
parameters:
-
cur_tkt
: valid source SSO ticket -
cur_svc
: source SSO service -
cur_nonce
: nonce for cur_tkt -
new_svc
: destination SSO service -
new_nonce
: nonce for the new SSO ticket
Note that annoyingly cur_svc and cur_nonce are redundant, as they are already contained within cur_tkt, but the SSO ticket API won't allow us to decode the ticket without verifying it at the same time.
The new ticket will not be valid any longer than the original one, or the configured TTL for the new service, whichever comes first.
Group membership in the original ticket is passed along unchanged to the new ticket.
Implementation notes
The single-sign-on functionality works using HTTP cookies and redirects between the protected service and the SSO server implemented in this package. This part works without any Javascript, it's just plain old HTTP (the browser must accept cookies though). SSO cookies have a builtin (signed) expiration timestamp, and are set to be automatically deleted on browser exit.
Logout, on the other hand, is more complex: in order to get the browser to delete the cookies from the signed-in services, we use XMLHttpRequests from the logout page, and expect the service logout endpoints to support authenticated CORS. If Javascript is not available, however, we try to clear the cookies using image requests, but this may not work depending on the browser (Safari), or the presence of privacy-protecting extensions meant to block third-party cookies. In this case a message is displayed asking the user to quit the browser, but this isn't really a satisfying solution.