semaphore icon indicating copy to clipboard operation
semaphore copied to clipboard

Update: proxy authentication

Open till opened this issue 1 year ago • 2 comments

I made a quick pass to enable proxy auth (aka external-auth or forward-auth).

The way this works is, once enabled, it'll listen to the specific headers in the the request and will try to find a user based on that, or create one on the fly.

I made this as a first pass to gather feedback. Any comments appreciated.

Related: ansible-semaphore/semaphore#735

till avatar May 17 '23 12:05 till

Currently using rundeck and would love to switch to semaphore as lightweight alternative. Maybe the approach of rundeck (how I use it right now) can work here too.

Rundeck allows to define in the configuration or via env variable (i.e. for docker) "preauth" settings. These define how the headers get's read for proxy auth. Basically you can configure the header names for all required attributes like username, email, name and groups/roles and a logout url to forward to logout of the proxy auth. It then also creates on the fly the user with the minimal required set of attributes. In case of semaphore, this would require username,name,email and maybe a role header which just has to include "admin" if the user is admin.

example of settings (env vars in this case) for rundeck behind authelia authentification:

RUNDECK_PREAUTH_ENABLED: true
RUNDECK_PREAUTH_DELIMITER: "," # for reading groups
RUNDECK_PREAUTH_USERNAME_HEADER: Remote-User
RUNDECK_PREAUTH_ROLES_HEADER: Remote-Groups
RUNDECK_PREAUTH_USERSYNC_ENABLED: true
RUNDECK_PREAUTH_USERSYNC_EMAIL: Remote-Email
RUNDECK_PREAUTH_REDIRECT_URL: https://myproxyauthdomain/logout

the proxy then sends the following headers to rundeck set by the forward auth:

Remote-User: myuser
Remote-Email: [email protected]
Remote-Groups: admin,user

RUNDECK_PREAUTH_USERSYNC_ENABLED defines if an existing user is updated in case of the headers do not match the existing user. This is for changing any attribute including group/role.

For semaphore I suggest the following extension of config.json:

{
...
  "proxy_auth": {
    "user_header": "Remote-User",
    "name_header": "Remote-Name",
    "mail_header": "Remote-Email",
    "role_header": "Remote-Groups",
    "role_header_sep": ",",
    "role_header_admin_group": "admin", // semaphore should search in the delimited list of `role_header` for this group
    "sync": true // defines if already existing users get's updated
                 // should only support local and not ldap (so this `true` and ldap enabled should fail or silently not sync).
                 // But with "false" I see no reason to not use only the `Remote-User` as authenticated user and use ldap for reading the attributes.
    "logout_url": "https://myauthserver/logout" // optional but nice feature
  }
...
}

spali avatar Jun 20 '23 13:06 spali

Tried to play a bit around, but had the problem, that the authenticationHandler does get called before the first login attempt. I assume because the client side check for a cookie starting with semaphore=.

@till Did you observe the same?

I think any form of "pre-authentication" would first need to let the client side always call the backend to check for authentication and route based on the result not the pure existence of the cookie. I just don't know enough about vue2 to get this "fixed".

spali avatar Jun 26 '23 14:06 spali

Hi @spali Do you still use Rundeck or Semaphore? What you finally choose and why?

fiftin avatar May 21 '24 16:05 fiftin

Hi @spali Do you still use Rundeck or Semaphore? What you finally choose and why?

Switched the few jobs I have to Ofelia with docker.

spali avatar May 21 '24 16:05 spali

I gave up on it a while back. Closing this.

till avatar May 21 '24 18:05 till