[GH-ISSUE #1991] Better error message when OAuth provider responds with access denied #1237

Open
opened 2026-03-02 11:55:59 +03:00 by kerem · 1 comment
Owner

Originally created by @ibizaman on GitHub (Sep 29, 2025).
Original GitHub issue: https://github.com/karakeep-app/karakeep/issues/1991

Describe the feature you'd like

Since Karakeep does not (yet?) implement #1525 , I resorted to configure the OAuth provider (Authelia) to return an access denied response whenever a user which is not part of a specific group tries to login. Although the implementation works and the user is not logged in, the user sees a confusing message OAuth login failed: Callback. There is no callback error, the user simply does not have access to the app. Karakeep should at least simply forward the error message coming from the provider.

Describe the benefits this would bring to existing Karakeep users

The benefit is less confusion. There's a big difference in saying the oauth login failed because of a callback issue and the oauth login failed because I don't have access.

Can the goal of this request already be achieved via other means?

I'm not aware of any other way.

Have you searched for an existing open/closed issue?

  • I have searched for existing issues and none cover my fundamental request

Additional context

Karakeep relevant config:

NEXTAUTH_URL=https://k.example.com
OAUTH_CLIENT_ID=karakeep
OAUTH_PROVIDER_NAME=Single Sign-On
OAUTH_SCOPE=openid email profile
OAUTH_WELLKNOWN_URL=https://auth.example.com/.well-known/openid-configuration

Relevant Authelia config:

identity_providers:
  oidc:
    authorization_policies:
      karakeep:
        default_policy: deny
        rules:
        - policy: one_factor
          subject:
          - group:user_group
  clients:
    - authorization_policy: karakeep
      claims_policy: default
      client_id: karakeep
      client_name: null
      client_secret: %SECRET%
      public: false
      redirect_uris:
        - https://k.example.com/api/auth/callback/custom
      scopes:
        -  openid
        -  email
        -  profile

These are the relevant logs and requests happening:

  1. Right after the user successfully logs in to Authelia, Authelia prints this log message:

    {
      "level": "error",
      "method": "GET",
      "msg": "Authorization Request with id 'aeaf4f29-f2f3-4ce2-9336-2d1e1e1c73fc' on client with id 'karakeep' using policy 'karakeep' could not be processed: the user 'charlie' is not authorized to use this client",
      "path": "/api/oidc/authorization",
      "remote_ip": "192.168.1.1",
      "time": "2025-09-29T13:00:05Z"
    }
    
  2. The response headers of the corresponding request is:

    Location: https://k.example.com/api/auth/callback/custom?error=access_denied
    &error_description=The+resource+owner+or+authorization+server+denied+the+request.+The+user+was+denied+access+to+this+client.
    &iss=https%3A%2F%2Fauth.example.com
    &state=_QmYSt7JvkGBrQEIwpiu8qycM9il1VsMoWAl3jgboQc}
    
  3. Then, Nextauth sees the error as it's printing in the logs:

    [next-auth][error][OAUTH_CALLBACK_HANDLER_ERROR]
    https://next-auth.js.org/errors#oauth_callback_handler_error access_denied {
      error: {
        message: 'access_denied',
        stack: 'Error: access_denied\n' +
          '    at c (/nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/apps/web/.next/server/chunks/8169.js:3:31307)\n' +
          '    at Object.l (/nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/apps/web/.next/server/chunks/8169.js:27:802)\n' +
          '    at g (/nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/apps/web/.next/server/chunks/8169.js:3:14953)\n' +
          '    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n' +
          '    at async a (/nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/apps/web/.next/server/chunks/8169.js:27:19776)\n' +
          '    at async e.length.t (/nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/apps/web/.next/server/chunks/8169.js:27:21265)\n' +
          '    at async /nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:38411\n' +
          '    at async e_.execute (/nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:27880)\n' +
          '    at async e_.handle (/nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:39943)\n' +
          '    at async doRender (/nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/node_modules/next/dist/server/base-server.js:1366:42)',
        name: 'Error'
      },
      error_description: 'The resource owner or authorization server denied the request. The user was denied access to this client.',
      providerId: 'custom',
      message: 'access_denied'
    }}
    

But then this is what the user sees:

Image
Originally created by @ibizaman on GitHub (Sep 29, 2025). Original GitHub issue: https://github.com/karakeep-app/karakeep/issues/1991 ### Describe the feature you'd like Since Karakeep does not (yet?) implement #1525 , I resorted to configure the OAuth provider (Authelia) to return an access denied response whenever a user which is not part of a specific group tries to login. Although the implementation works and the user is not logged in, the user sees a confusing message `OAuth login failed: Callback`. There is no callback error, the user simply does not have access to the app. Karakeep should at least simply forward the error message coming from the provider. ### Describe the benefits this would bring to existing Karakeep users The benefit is less confusion. There's a big difference in saying the oauth login failed because of a callback issue and the oauth login failed because I don't have access. ### Can the goal of this request already be achieved via other means? I'm not aware of any other way. ### Have you searched for an existing open/closed issue? - [x] I have searched for existing issues and none cover my fundamental request ### Additional context Karakeep relevant config: ``` NEXTAUTH_URL=https://k.example.com OAUTH_CLIENT_ID=karakeep OAUTH_PROVIDER_NAME=Single Sign-On OAUTH_SCOPE=openid email profile OAUTH_WELLKNOWN_URL=https://auth.example.com/.well-known/openid-configuration ``` Relevant Authelia config: ```yaml identity_providers: oidc: authorization_policies: karakeep: default_policy: deny rules: - policy: one_factor subject: - group:user_group clients: - authorization_policy: karakeep claims_policy: default client_id: karakeep client_name: null client_secret: %SECRET% public: false redirect_uris: - https://k.example.com/api/auth/callback/custom scopes: - openid - email - profile ``` These are the relevant logs and requests happening: 1. Right after the user successfully logs in to Authelia, Authelia prints this log message: ``` { "level": "error", "method": "GET", "msg": "Authorization Request with id 'aeaf4f29-f2f3-4ce2-9336-2d1e1e1c73fc' on client with id 'karakeep' using policy 'karakeep' could not be processed: the user 'charlie' is not authorized to use this client", "path": "/api/oidc/authorization", "remote_ip": "192.168.1.1", "time": "2025-09-29T13:00:05Z" } ``` 2. The response headers of the corresponding request is: ``` Location: https://k.example.com/api/auth/callback/custom?error=access_denied &error_description=The+resource+owner+or+authorization+server+denied+the+request.+The+user+was+denied+access+to+this+client. &iss=https%3A%2F%2Fauth.example.com &state=_QmYSt7JvkGBrQEIwpiu8qycM9il1VsMoWAl3jgboQc} ``` 3. Then, Nextauth sees the error as it's printing in the logs: ``` [next-auth][error][OAUTH_CALLBACK_HANDLER_ERROR] https://next-auth.js.org/errors#oauth_callback_handler_error access_denied { error: { message: 'access_denied', stack: 'Error: access_denied\n' + ' at c (/nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/apps/web/.next/server/chunks/8169.js:3:31307)\n' + ' at Object.l (/nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/apps/web/.next/server/chunks/8169.js:27:802)\n' + ' at g (/nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/apps/web/.next/server/chunks/8169.js:3:14953)\n' + ' at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n' + ' at async a (/nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/apps/web/.next/server/chunks/8169.js:27:19776)\n' + ' at async e.length.t (/nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/apps/web/.next/server/chunks/8169.js:27:21265)\n' + ' at async /nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:38411\n' + ' at async e_.execute (/nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:27880)\n' + ' at async e_.handle (/nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:39943)\n' + ' at async doRender (/nix/store/a1dxaiiqlzb2zca8cwwckmcq0qs8s1f7-karakeep-0.26.0/lib/karakeep/apps/web/.next/standalone/node_modules/next/dist/server/base-server.js:1366:42)', name: 'Error' }, error_description: 'The resource owner or authorization server denied the request. The user was denied access to this client.', providerId: 'custom', message: 'access_denied' }} ``` But then this is what the user sees: <img width="667" height="386" alt="Image" src="https://github.com/user-attachments/assets/a4934061-b88d-4099-88b5-ef4a73746eba" />
Author
Owner

@simono41 commented on GitHub (Oct 3, 2025):

I have the same Problem, but with OAuthCallbackError:

error: Error [OAuthCallbackError]: id_token detected in the response, you must use client.callback() instead of client.oauthCallback()

<!-- gh-comment-id:3367572516 --> @simono41 commented on GitHub (Oct 3, 2025): I have the same Problem, but with OAuthCallbackError: error: Error [OAuthCallbackError]: id_token detected in the response, you must use client.callback() instead of client.oauthCallback()
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/karakeep#1237
No description provided.