This plugin extends devpi with SAML Single Sign-On authentication.
It also extends devpi by protecting read-only access as well, similarly to devpi-lockdown which does the same for the default password logins.
As SAML authentication can not be used on the command line, it also adds user interface support for devpi-tokens to create tokens that can be used to log into devpi.
devpi-saml
needs to be installed alongside devpi-server
.
You can install it with:
pip install devpi-saml
This package has only been tested with version 6.9 of devpi-server
.
To lock down read access to devpi, you need a proxy in front of devpi which can use the provided views to limit access.
This has been tested with nginx, where the auth_request module is required. The config generation is not yet included in this plugin. Follow the `devpi manual`_ for creating the nginx configuration, and then extend it manually with the following.
# this redirects to the SSO view when not logged in
error_page 401 = @error401;
location @error401 {
return 302 http://$host/sso?redirect=$request_uri;
}
# the location to check whether the provided infos authenticate the user
location = /+authcheck {
internal;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Outside-URL https://$host;
proxy_pass http://localhost:3141;
}
# lock down everything by default
auth_request /+authcheck;
# pass on the various SSO routes without authentication
location /sso {
auth_request off;
proxy_set_header X-Outside-URL https://$host;
proxy_pass http://localhost:3141;
}
location /slo {
auth_request off;
proxy_set_header X-Outside-URL https://$host;
proxy_pass http://localhost:3141;
}
location /acs {
auth_request off;
proxy_set_header X-Outside-URL https://$host;
proxy_pass http://localhost:3141;
}
location /sls {
auth_request off;
proxy_set_header X-Outside-URL https://$host;
proxy_pass http://localhost:3141;
}
location /metadata {
auth_request off;
proxy_set_header X-Outside-URL https://$host;
proxy_pass http://localhost:3141;
}
# pass on /+api without authentication check for URL endpoint discovery
location ~ /\+api$ {
auth_request off;
proxy_set_header X-Outside-URL https://$host;
proxy_pass http://localhost:3141;
}
# pass on /+static without authentication check for browser access to css etc
location /+static/ {
auth_request off;
proxy_set_header X-Outside-URL https://$host;
proxy_pass http://localhost:3141;
}
location = /favicon.ico {
auth_request off;
proxy_set_header X-Outside-URL https://$host;
proxy_pass http://localhost:3141;
}
# try serving static files directly
location ~ /\+f/ {
# workaround to pass non-GET/HEAD requests through to the named location below
error_page 418 = @proxy_to_app;
if ($request_method !~ (GET)|(HEAD)) {
return 418;
}
expires max;
try_files /+files$uri @proxy_to_app;
}
# try serving docs directly
location ~ /\+doc/ {
# if the --documentation-path option of devpi-web is used,
# then the root must be set accordingly here
# root /tmp/home/mydevpiserver;
try_files $uri @proxy_to_app;
}