Skip to content

Instantly share code, notes, and snippets.

@col-panic
Last active November 20, 2025 14:00
Show Gist options
  • Select an option

  • Save col-panic/d62f9837b01872ccf8227f28f430f4cf to your computer and use it in GitHub Desktop.

Select an option

Save col-panic/d62f9837b01872ccf8227f28f430f4cf to your computer and use it in GitHub Desktop.
Oauth2-proxy + nginx auth_request + limit location for a specific role

This is a full example for running an oauth2-proxy covered by a nginx as reverse proxy, using the auth_request parameter in combination with a required role to mach a location. See oauth2-proxy/oauth2-proxy#1614 for discussion.

Suppose we have Location (A) that should allow access only to users having role roleA

location ^~ /roleAOnly/ {
    auth_request /oauth2/auth/rolea;
    error_page 401 = /oauth2/sign_in;

    auth_request_set $user $upstream_http_x_auth_request_user;

    proxy_pass http://guacamole-guacamole:8080;
    proxy_buffering off;
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    access_log off;
}

(Remark) auth_request does not accept query parameters, thus we are cloaking the role roleA as part of the url.

Here is the customized oauth2/auth location matching the url and extracting it as query parameter to pass to oauth2-proxy:

location ~ ^/oauth2/auth/(.*)$ {
    internal;
    
    resolver 127.0.0.11 valid=30s ipv6=off;
    set $upstream_oauth2_proxy http://oauth2-proxy:4180;

    set $args $args&allowed_groups=role:$1;
    rewrite ^/oauth2/auth/(.*)$ /oauth2/auth break;

    proxy_pass $upstream_oauth2_proxy;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Scheme $scheme;
    # nginx auth_request includes headers but not body
    proxy_set_header Content-Length "";
    proxy_pass_request_body off;
}

With set $args we are extracting the role and embedding it into $args&allowed_groups=role:$1 to pass to the proxy backend. The following rewrite rule does remove the /roleA part to continue with the rest as expected.

@phiresky
Copy link

phiresky commented Jun 3, 2024

thanks! this is great, especially with your workaround for https://trac.nginx.org/nginx/ticket/761

@TafkaMax
Copy link

Hmm, I don't know if I am doing something wrong. I am getting 403 in my oauth2-proxy.

/oauth2/auth?&allowed_groups=ldap_users" HTTP/1.0 "Mozilla/5.0 (X11; Linux x86_64; rv:144.0) Gecko/20100101 Firefox/144.0" 401 13 0.000

I can't even access my /oauth2/userinfo to see if the groups list it.

@TafkaMax
Copy link

My config for nginx is as follows:


    # Default location when browsing. Search for files in /data/www folder.
    location / {
      root /data/www;
      expires -1;

      error_page 401 = /oauth2/sign_in?rd=$scheme://$host$request_uri;
      auth_request_set $user $upstream_http_x_auth_request_user;
      auth_request_set $token $upstream_http_x_auth_request_access_token;
      auth_request_set $auth_cookie $upstream_http_set_cookie;
      proxy_set_header X-User  $user;
      proxy_set_header X-Access-Token $token;
      add_header Set-Cookie $auth_cookie;

      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-Proto $scheme;
      auth_request /oauth2/auth/ldap_users;
    }

    # The oauth2-proxy location.
    location /oauth2 {
        expires -1;
        proxy_set_header Host       $host;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Auth-Request-Redirect $request_uri;
        proxy_pass http://oauth2-proxy:4180;
    }

    # The oauth2-proxy location for managing group based access.
    location ~ ^/oauth2/auth/(.*)$ {
      set $upstream_oauth2_proxy http://oauth2-proxy:4180;

      set $args $args&allowed_groups=$1;
      rewrite ^/oauth2/auth/(.*)$ /oauth2/auth break;

      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Scheme $scheme;
      # nginx auth_request includes headers but not body
      proxy_set_header Content-Length "";
      proxy_pass_request_body off;
      # Proxy pass to oauth2-proxy
      proxy_pass $upstream_oauth2_proxy;
    }

    # oauth2-proxy logout.
    location = /oauth2/sign_out {
        expires -1;
        proxy_set_header Host       $host;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Auth-Request-Redirect /oauth2/sign_in;
        proxy_pass http://oauth2-proxy:4180;
    }

@TafkaMax
Copy link

Do I have something extra defined?

@TafkaMax
Copy link

NVM, I didnt have groups scope setup in oauth2-proxy config.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment