External Authentication
OverviewQuestions:
Objectives:
How can I connect Galaxy with CAS, SAML, etc.
Requirements:
be familiar with configuring Galaxy to use an upstream (proxy) authentication provider
be able to log in to your Galaxy server with a file-configured user.
- Galaxy Server administration
- Ansible: slides slides - tutorial hands-on
- Galaxy Installation with Ansible: slides slides - tutorial hands-on
Time estimation: 30 minutesSupporting Materials:Last modification: Oct 18, 2022License: Tutorial Content is licensed under Creative Commons Attribution 4.0 International License. The GTN Framework is licensed under MITpurlPURL: https://gxy.io/GTN:T00007
Overview
For this exercise we will use a basic password file method for authenticating - this is probably not a very useful method in production, but it demonstrates how the proxy server can be configured to provide the correct header to Galaxy, and how Galaxy integrates with upstream authentication providers. This same method can be used with NGINX and Apache modules for CAS or SAML authentication.
Agenda
Configuring Authentication
Hands-on: Configuring everything
- Edit the galaxy.j2 template file in the templates/nginx directory and update the main location block defined for serving galaxy. Add the parameters:
auth_basic galaxy;
auth_basic_user_file /etc/nginx/passwd;
proxy_set_header HTTP_REMOTE_USER $remote_user;
proxy_set_header HTTP_GX_SECRET SOME_SECRET_STRING;
It should look like:
@@ -14,6 +14,10 @@ + auth_basic galaxy; + auth_basic_user_file /etc/nginx/passwd; + proxy_set_header HTTP_REMOTE_USER $remote_user; + proxy_set_header HTTP_GX_SECRET SOME_SECRET_STRING; } # Static files can be more efficiently served by Nginx. Why send the
If you havenโt worked with diffs before, this can be something quite new or different.
If we have two files, letโs say a grocery list, in two files. Weโll call them โaโ and โbโ.
Input: Old$ cat old
๐
๐
๐
๐
๐
๐ฅOutput: New$ cat new
๐
๐
๐
๐
๐
๐ฅWe can see that they have some different entries. Weโve removed ๐ because theyโre awful, and replaced them with an ๐
Diff lets us compare these files
$ diff old new
5c5
< ๐
---
> ๐Here we see that ๐ is only in a, and ๐ is only in b. But otherwise the files are identical.
There are a couple different formats to diffs, one is the โunified diffโ
$ diff -U2 old new
--- old 2022-02-16 14:06:19.697132568 +0100
+++ new 2022-02-16 14:06:36.340962616 +0100
@@ -3,4 +3,4 @@
๐
๐
-๐
+๐
๐ฅThis is basically what you see in the training materials which gives you a lot of context about the changes:
--- old
is the โoldโ file in our view+++ new
is the โnewโ file- @@ these lines tell us where the change occurs and how many lines are added or removed.
- Lines starting with a - are removed from our โnewโ file
- Lines with a + have been added.
So when you go to apply these diffs to your files in the training:
- Ignore the header
- Remove lines starting with - from your file
- Add lines starting with + to your file
The other lines (๐/๐ and ๐ฅ) above just provide โcontextโ, they help you know where a change belongs in a file, but should not be edited when youโre making the above change. Given the above diff, you would find a line with a ๐, and replace it with a ๐
Added & Removed Lines
Removals are very easy to spot, we just have removed lines
--- old 2022-02-16 14:06:19.697132568 +0100
+++ new 2022-02-16 14:10:14.370722802 +0100
@@ -4,3 +4,2 @@
๐
๐
-๐ฅAnd additions likewise are very easy, just add a new line, between the other lines in your file.
--- old 2022-02-16 14:06:19.697132568 +0100
+++ new 2022-02-16 14:11:11.422135393 +0100
@@ -1,3 +1,4 @@
๐
+๐
๐
๐Completely new files
Completely new files look a bit different, there the โoldโ file is
/dev/null
, the empty file in a Linux machine.$ diff -U2 /dev/null old
--- /dev/null 2022-02-15 11:47:16.100000270 +0100
+++ old 2022-02-16 14:06:19.697132568 +0100
@@ -0,0 +1,6 @@
+๐
+๐
+๐
+๐
+๐
+๐ฅAnd removed files are similar, except with the new file being /dev/null
--- old 2022-02-16 14:06:19.697132568 +0100
+++ /dev/null 2022-02-15 11:47:16.100000270 +0100
@@ -1,6 +0,0 @@
-๐
-๐
-๐
-๐
-๐
-๐ฅAdd the
auth_basic
andauth_basic_user_file
lines to yourlocation /reports/
auth_basic
enables validation of username and password using the โHTTP Basic Authenticationโ protocol. Its valuegalaxy
is used as a realm name to be displayed to the user when prompting for credentials.auth_basic_user_file
specifies the file that keeps usernames and passwords.proxy_set_header
addsHTTP_REMOTE_USER
to the special variables passed by nginx to Galaxy, with value$remote_user
, which is a nginx embedded variable containing the username supplied with the Basic authentication.
GX_SECRET
is added as a header for security purposes, to prevent any other users on the system impersonating nginx and sending requests to Galaxy. NGINX and other webservers like Apache will strip any user-sentREMOTE_USER
headers, as that header defines the authenticated user. If you can talk directly to Galaxy (e.g. via curl) and provide theREMOTE_USER
header, you can impersonate any other use. While having Galaxy listen on127.0.0.1
prevents any requests from outside of the system reaching Galaxy, anyone on the system can still send requests to that port. Here you can choose to switch to a unix socket with permissions only permitting Galaxy and Nginx to connect.GX_SECRET
adds additional security as it needs to matchremote_user_secret
in your galaxy configutation.Users can bypass the authentication only if they can talk directly to the gunicorn processes (if you have socket/http: 0.0.0.0, or if it is directly responsible for serving galaxy, and there is no proxy.) This can happen mostly when some users have command line access to the Galaxy server, which is considered a bad practice.
Add a pre_task using the
pip
module which installs the librarypasslib
, which is required forhtpasswd
.Add a pre_task using the
htpasswd
module which sets up a password file in/etc/nginx/passwd
, with owner and group set to root, and a name and password, and a mode of 0640.QuestionHow does your final configuration look?
@@ -7,6 +7,15 @@ name: galaxy state: restarted pre_tasks: + - pip: + name: passlib + - htpasswd: + path: /etc/nginx/passwd + name: user1 # Pick a username + password: changeme # and a password + owner: www-data # nginx on centos + group: root + mode: 0640 - name: Install Dependencies package: name: ['git', 'make', 'python3-psycopg2', 'virtualenv']
Galaxy needs to be instructed to expect authentication to come from the upstream proxy. In order to do this, set the following two options in your Galaxy group variables:
... galaxy_config: galaxy: ... use_remote_user: true remote_user_maildomain: "{{ inventory_hostname }}" remote_user_secret: SOME_SECRET_STRING
You donโt need to make the above changes for Galaxy then.
Set the
remote_user_maildomain
option to the appropriate domain name for your site.- Run the playbook
Comment: Access deniedIf you see this message, it is because nginx is not correctly sending the
REMOTE_USER
or theGX_SECRET
values.
Testing
You should now be presented with a password dialog when attempting to load the Galaxy UI.
Hands-on: Testing
Log in using the username and password you provided when creating the
passwd
file. If your username and the value ofremote_user_maildomain
match an existing user, you will be logged in to that account. If not, a new account will be created for that user.Click on the โUserโ menu at the top, to see how the username appears.
Note that some user features are not available when remote user support is enabled.
Try logging out by selecting User -> Logout. You will discover that when returning to the user interface, you are still logged in. This is because Galaxy has no way of logging you out of the proxyโs authentication system. Instead, you should set
remote_user_logout_href
ingalaxy.yml
to point to the URL of your authentication systemโs logout page.
API access
If you wish your Galaxy to be accessible to command line clients (e.g. bioblend, blend4j, parsec), you will need to add an exception for authentication on the API. Galaxy will still be secure and protected, but non-browser access will be permitted with an API key.
location /api/ {
satisfy any;
allow all;
}
There is no built-in way to be notified if users are registered, with external authentication or built-in. However, you could automate this easily. There is a gxadmin command we use called
gxadmin query latest-users
which Bjรถrn uses often. Other sites have other methods, e.g. Nicolaโs cron script which runs daily on his server, to add new users to a group according to their email domain name.
Reverting
We donโt want to leave Galaxy this way for the rest of our workshop.
Hands-on: Reverting the changes
Edit your group variables file and comment out:
- the NGINX changes
use_remote_user: true
Run the playbook