# Direct OAuth2 Authentication with PocketID and Traefik OIDC Plugin

**URL:** <https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956>\
**Category:** Networking\
**Tags:** oidc, pocketid, traefik\
**Created:** [May 15, 2025, 1:19pm UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956 "2025-05-15T13:19:38Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mattercoder](https://forum.hhf.technology/letter_avatar_proxy/v4/letter/m/54ee81/32.png) [@Mattercoder](https://forum.hhf.technology/u/Mattercoder)\
**Post date:** [May 15, 2025, 1:19pm UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956/1 "2025-05-15T13:19:38Z")

</div>

This guide demonstrates how to implement seamless OAuth2 authentication for your Pangolin resources using PocketID and the Traefik OIDC plugin. Unlike traditional setups that require users to navigate through multiple login pages, this approach redirects users directly to PocketID’s login page where they can authenticate with passkeys.

 ![PocketIdSignInPage](https://forum-cdn.hhf.technology/original/2X/8/8af4b6407964774d5ec536dc7afb1f338004efa2.jpeg)

## ✨ Why This Matters

Traditional authentication flows often require users to:

1. Visit your application
2. Get redirected to Pangolin’s login page
3. Click to authenticate with a third-party provider
4. Complete authentication and return to your app

With this direct OAuth2 implementation:

1. Users visit your protected resource
2. They’re immediately redirected to PocketID
3. They authenticate with passkeys
4. They’re returned directly to your application

This streamlined experience feels more professional and reduces friction for your users.

## 📋 Prerequisites

- Pangolin with Middleware Manager installed
- A domain with DNS properly configured
- Basic understanding of OAuth2/OIDC concepts

## 🚀 Step 1: Set Up PocketID Authentication Server

First, you’ll need a running PocketID instance. You can follow our guide on [Using AWS CloudFormation to Create Test Authentication Servers](https://forum.hhf.technology/t/using-aws-cloudformation-to-create-test-authentication-servers-for-pangolin-and-the-middleware-manager/1961) to quickly deploy PocketID.

Alternatively, you can add the following to your docker compose to run pocketid on your VPS

```auto
    pocketid:
      image: ghcr.io/pocket-id/pocket-id
      container_name: pocketid
      restart: unless-stopped
      env_file: .env
      volumes:
        - "./pocketid:/app/backend/data"

```

and include the following in your dynamic\_config.yml file

```auto
    # Add these lines for pocketid
    # pocketid http redirect router
    pocketid-router-redirect:
      rule: "Host(`pocketid.yourdomain.com`)"
      service: pocketid-service
      entryPoints:
        - web
      middlewares:
        - redirect-to-https

    # pocketid router
    pocketid:
      rule: "Host(`pocketid.yourdomain.com`)"
      service: pocketid-service
      entryPoints:
        - websecure
      tls:
        certResolver: letsencrypt

    pocketid-service:
      loadBalancer:
        servers:
          - url: "http://pocketid:1411"

```

Once deployed, your PocketID instance should be accessible at `https://pocketid.yourdomain.com`.

## 👤 Step 2: Configure PocketID Admin Account

When accessing PocketID for the first time, you’ll need to set up an admin account:

1. Navigate to `https://pocketid.yourdomain.com/setup`
2. Follow the prompts to create your administrator account
3. Register a passkey for secure authentication

## 🔑 Step 3: Create an OIDC Client in PocketID

Now you’ll create an OAuth2/OIDC client that your applications will use:

1. Log in to PocketID admin interface
2. Navigate to the Clients section
3. Create a new client with these settings:
  - **Name** : MyAuth (or any descriptive name)
  - **Callback URL** : `https://*.yourdomain.com/oidc/callback` (wildcard allows any subdomain)

4. Save the client configuration
5. **Important** : Copy the generated **Client ID** and **Client Secret** - you’ll need these later

 ![PocketID-OIDC-Traefik-Plugin1](https://forum-cdn.hhf.technology/original/2X/3/38860cf0946571e4145908495ddce53863ceba2a.png)

## 🔌 Step 4: Add the OIDC Plugin to Traefik

Edit your `config/traefik/traefik_config.yml` file to include the OIDC authentication plugin:

```yaml
experimental:
  plugins:
    traefik-oidc-auth:
      moduleName: "github.com/sevensolutions/traefik-oidc-auth"
      version: "v0.11.0"

```

## ⚙ Step 5: Create the OIDC Middleware

1. Open the Pangolin Middleware Manager
2. Navigate to the **Middlewares** tab
3. Click **Create Middleware**
4. Select **Plugin** as the middleware type
5. Name it “Traefik OIDC Auth” (or similar)
6. Enter the following JSON configuration, replacing the placeholder values with your actual Client ID, Client Secret, and PocketID domain:

```json
{
  "traefik-oidc-auth": {
    "Provider": {
      "ClientId": "ee55e81a-e06f-408a-92cf-5f7dd55a1a70",
      "ClientSecret": "YourClientSecret",
      "TokenValidation": "IdToken",
      "Url": "https://pocketid.yourdomain.com"
    },
    "Scopes": [
      "openid",
      "profile",
      "email"
    ]
  }
}

```

1. Click **Update Middleware**

 ![AddMiddleware](https://forum-cdn.hhf.technology/original/2X/0/006734651e36ee3fa7f0e6217f6c019569eaf899.png)

## 🛡 Step 6: Protect Your Resources

1. From the Middleware Manager dashboard, select the resource you want to protect
2. Click **Manage**
3. Under **Attached Middlewares** , click **Add Middleware**
4. Select your newly created OIDC middleware
5. Click **Add Middlewares**
6. Save your changes

## 🧪 Step 7: Test the Authentication Flow

1. Open an incognito/private browser window
2. Navigate to your protected resource (e.g., `https://app.yourdomain.com`)
3. You should be immediately redirected to the PocketID login page
4. Authenticate using your passkey

 ![PocketIdSignInPage](https://forum-cdn.hhf.technology/original/2X/8/8af4b6407964774d5ec536dc7afb1f338004efa2.jpeg)

## 🔍 Step 8: Consent Screen (First-time Access)

The first time you access a protected resource, PocketID will display a consent screen asking permission to share your information with the application.

1. Review the requested permissions
2. Click **Allow** to proceed

 ![PocketIdConsent](https://forum-cdn.hhf.technology/original/2X/4/4693818afac65b2d030514745a3944ad43c15788.jpeg)

After granting consent, you’ll be redirected to your protected resource, now authenticated!

## 🔄 Troubleshooting

**Issue** : Not being redirected to PocketID when accessing a protected resource after clearing cookies.

**Solution** : Browser caching can sometimes interfere with the authentication flow. Try:

1. Open Developer Tools (F12 or Right-click \> Inspect)
2. Navigate to Application \> Storage
3. Click “Clear site data” to completely remove all stored data for the site
4. Reload the page

## 📌 Summary

This direct OAuth2 authentication approach with PocketID and the Traefik OIDC plugin offers:

- A streamlined, professional user experience
- Secure passkey authentication
- No intermediate login pages
- Simplified user journey

By implementing this solution, you’re providing your users with a modern, frictionless authentication experience while maintaining robust security standards.

## 🙏 Thanks for Reading

We hope this guide helps you implement a smoother authentication flow for your Pangolin resources. If you have questions or need further assistance, please visit our [community forum](https://forum.hhf.technology).

---

<div class="post-metadata">

**Author:** ![gasto](https://forum.hhf.technology/letter_avatar_proxy/v4/letter/g/8e7dd6/32.png) [@gasto](https://forum.hhf.technology/u/gasto)\
**Post date:** [May 21, 2025, 4:24pm UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956/2 "2025-05-21T16:24:10Z")

</div>

Thanks for the tutorial, very easy to follow.

Question, is this one of those implementations where if you for example can’t reach PocketID or PocketID is currently down then you cannot login to the resources? Or can you setup a fallback login?

I recall for example Portainer shows both the oAuth and internal authentication methods in case the first one is down or something.

Thanks

---

<div class="post-metadata">

**Author:** ![Mattercoder](https://forum.hhf.technology/letter_avatar_proxy/v4/letter/m/54ee81/32.png) [@Mattercoder](https://forum.hhf.technology/u/Mattercoder)\
**Post date:** [May 21, 2025, 5:22pm UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956/3 "2025-05-21T17:22:28Z")

</div>

That’s a good question. There isn’t a fall back for now as far as I know but in the case of a failure I recommend using the middleware manager to remove the middleware from the resource and you can login

---

<div class="post-metadata">

**Author:** ![Daniel](https://forum.hhf.technology/user_avatar/forum.hhf.technology/daniel/32/2156_2.png) [@Daniel](https://forum.hhf.technology/u/Daniel)\
**Post date:** [July 15, 2025, 12:54pm UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956/4 "2025-07-15T12:54:01Z")

</div>

For those without AWS accounts (there are such people for sure) is it possible to install PocketID container on same machine as Pangolin is running? Same way that Tinyauth was integrated in " [Implementing External Authentication in Pangolin Using Tinyauth and the Middleware Manager](https://forum.hhf.technology/t/implementing-external-authentication-in-pangolin-using-tinyauth-and-the-middleware-manager/1398)" ?

---

<div class="post-metadata">

**Author:** ![Mattercoder](https://forum.hhf.technology/letter_avatar_proxy/v4/letter/m/54ee81/32.png) [@Mattercoder](https://forum.hhf.technology/u/Mattercoder)\
**Post date:** [July 15, 2025, 2:30pm UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956/5 "2025-07-15T14:30:13Z")

</div>

Try including pocketid in your docker compose and then follow the rest of the instructions in the Aws guide

```auto
pocketid:
              image: ghcr.io/pocket-id/pocket-id
              container_name: pocket-id
              restart: unless-stopped
              env_file: .env
              volumes:
                - "./pocketid:/app/backend/data"
              labels:
                - "traefik.enable=true"
                - "traefik.http.routers.pocket-id.entrypoints=websecure"
                - "traefik.http.routers.pocket-id.rule=Host(`auth.yourdomain.com`)"
                - "traefik.http.routers.pocket-id.tls=true"
                - "traefik.http.routers.pocket-id.tls.certresolver=myresolver"
                - "traefik.http.routers.pocket-id.service=pocket-id"
                - "traefik.http.services.pocket-id.loadbalancer.server.port=80"
                - "traefik.http.routers.pocket-id.middlewares=redirect-to-https"
                - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"          
          

```

---

<div class="post-metadata">

**Author:** ![Daniel](https://forum.hhf.technology/user_avatar/forum.hhf.technology/daniel/32/2156_2.png) [@Daniel](https://forum.hhf.technology/u/Daniel)\
**Post date:** [July 15, 2025, 3:45pm UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956/6 "2025-07-15T15:45:27Z")

</div>

Thanks a million Ivo.

---

<div class="post-metadata">

**Author:** ![Daniel](https://forum.hhf.technology/user_avatar/forum.hhf.technology/daniel/32/2156_2.png) [@Daniel](https://forum.hhf.technology/u/Daniel)\
**Post date:** [July 16, 2025, 2:04pm UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956/7 "2025-07-16T14:04:08Z")

</div>

> [@Mattercoder](#):
>
> ```auto
> pocketid:
> image: ghcr.io/pocket-id/pocket-id
> container_name: pocket-id
> restart: unless-stopped
> env_file: .env
> volumes:
> - "./pocketid:/app/backend/data"
> labels:
> - "traefik.enable=true"
> - "traefik.http.routers.pocket-id.entrypoints=websecure"
> - "traefik.http.routers.pocket-id.rule=Host(`auth.yourdomain.com`)"
> - "traefik.http.routers.pocket-id.tls=true"
> - "traefik.http.routers.pocket-id.tls.certresolver=myresolver"
> - "traefik.http.routers.pocket-id.service=pocket-id"
> - "traefik.http.services.pocket-id.loadbalancer.server.port=80"
> - "traefik.http.routers.pocket-id.middlewares=redirect-to-https"
> - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"   
> 
> ```

I tired to create pocket-id container with provided config. I have changed domain name, certresolver, as in my case it’s letsencrypt and placed fqdn in env file: PUBLIC\_APP\_URL=https://. I’ve also modified volumes to “./config/pocketid:/app/backend/data” and created pocketid folder under config. Entire stack started normally (pocket-id container is up), no errors after running “docker logs pocket-id”. Unfortunately I cannot access the pocket id public url - 404 page not found. I have checked Traefik dashboard but no entries about pocket-id. Any thoughts?

---

<div class="post-metadata">

**Author:** ![Mattercoder](https://forum.hhf.technology/letter_avatar_proxy/v4/letter/m/54ee81/32.png) [@Mattercoder](https://forum.hhf.technology/u/Mattercoder)\
**Post date:** [July 16, 2025, 4:46pm UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956/8 "2025-07-16T16:46:02Z")

</div>

> [@Daniel](#):
>
> pocket id public url

You might not have port 80 exposed in traefik. Try just this in your docker compose and then add more services as you get it working

```auto
          services:
            traefik:
              image: traefik:v3.4.0
              container_name: traefik
              restart: unless-stopped
              ports:
                - "80:80"
                - "443:443"
              command:
                - "--api.insecure=false"
                - "--providers.docker=true"
                - "--providers.docker.exposedbydefault=false"
                - "--entrypoints.web.address=:80"
                - "--entrypoints.websecure.address=:443"
                - "--certificatesresolvers.myresolver.acme.httpchallenge=true"
                - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
                - "--certificatesresolvers.myresolver.acme.email=admin@yourdomain.com"
                - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
              volumes:
                - /var/run/docker.sock:/var/run/docker.sock:ro
                - ./traefik/letsencrypt:/letsencrypt

            pocketid:
              image: ghcr.io/pocket-id/pocket-id
              container_name: pocket-id
              restart: unless-stopped
              env_file: .env
              volumes:
                - "./pocketid:/app/backend/data"
              labels:
                - "traefik.enable=true"
                - "traefik.http.routers.pocket-id.entrypoints=websecure"
                - "traefik.http.routers.pocket-id.rule=Host(`auth.yourdomain.com`)"
                - "traefik.http.routers.pocket-id.tls=true"
                - "traefik.http.routers.pocket-id.tls.certresolver=myresolver"
                - "traefik.http.routers.pocket-id.service=pocket-id"
                - "traefik.http.services.pocket-id.loadbalancer.server.port=80"
                - "traefik.http.routers.pocket-id.middlewares=redirect-to-https"
                - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"      

```

---

<div class="post-metadata">

**Author:** ![Daniel](https://forum.hhf.technology/user_avatar/forum.hhf.technology/daniel/32/2156_2.png) [@Daniel](https://forum.hhf.technology/u/Daniel)\
**Post date:** [July 17, 2025, 2:24pm UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956/9 "2025-07-17T14:24:55Z")

</div>

Thanks and sorry for being a pain.  
The vanilla config you provided does not work for me out of the box. I had to change the fallowing line changing port from 80 to 1411 (default pocket ID port that is being assigned to container).  
`- "traefik.http.services.pocket-id.loadbalancer.server.port=1411"`  
Once applied change, I did get PocketID login page  
Even then, during PocketID initial setup, when I tried to create new passkey on fresh PocketID account I got “An unknown error occurred. Please try again.”  
It also looks like PocketID initial URL has been changed from [https://pocketid.yourdomain.com/login/setup](https://pocketid.yourdomain.com/login/setup) to [https://pocketid.yourdomain.com/setup](https://pocketid.yourdomain.com/setup)  
Not sure why I cannot set new passkey on fresh deployment. Any thoughts?

---

<div class="post-metadata">

**Author:** ![Mattercoder](https://forum.hhf.technology/letter_avatar_proxy/v4/letter/m/54ee81/32.png) [@Mattercoder](https://forum.hhf.technology/u/Mattercoder)\
**Post date:** [July 17, 2025, 7:36pm UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956/10 "2025-07-17T19:36:19Z")

</div>

Maybe things have changed on pocketid side since I wrote the guide. I will be setting up pocketid myself tomorrow so I will let you know

---

<div class="post-metadata">

**Author:** ![Daniel](https://forum.hhf.technology/user_avatar/forum.hhf.technology/daniel/32/2156_2.png) [@Daniel](https://forum.hhf.technology/u/Daniel)\
**Post date:** [July 18, 2025, 9:14am UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956/11 "2025-07-18T09:14:17Z")

</div>

I was able to fix the issue. It was misconfiguration in my .env file. Also config path has been changed on pocketid container. It is now pointing to /app/data instead /app/backend/data. I’m now able to login and set my passkey in pocketID. Thanks

---

<div class="post-metadata">

**Author:** ![E\_Tv](https://forum.hhf.technology/user_avatar/forum.hhf.technology/e_tv/32/2802_2.png) [@E\_Tv](https://forum.hhf.technology/u/E_Tv)\
**Post date:** [July 19, 2025, 7:10pm UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956/12 "2025-07-19T19:10:51Z")

</div>

> [@Mattercoder](#):
>
> `github.com/sevensolutions/traefik-oidc-auth`

Is there any way to make the plugin bypass if you are on local network 192.168.0.0 ?

---

<div class="post-metadata">

**Author:** ![Mattercoder](https://forum.hhf.technology/letter_avatar_proxy/v4/letter/m/54ee81/32.png) [@Mattercoder](https://forum.hhf.technology/u/Mattercoder)\
**Post date:** [July 19, 2025, 8:04pm UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956/13 "2025-07-19T20:04:08Z")

</div>

Configure a different resource in pangolin that doesn’t use oauth and lock that down to an IP address range

---

<div class="post-metadata">

**Author:** ![E\_Tv](https://forum.hhf.technology/user_avatar/forum.hhf.technology/e_tv/32/2802_2.png) [@E\_Tv](https://forum.hhf.technology/u/E_Tv)\
**Post date:** [July 20, 2025, 2:17am UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956/14 "2025-07-20T02:17:16Z")

</div>

So to a different dns name? Or can it be the same?

---

<div class="post-metadata">

**Author:** ![E\_Tv](https://forum.hhf.technology/user_avatar/forum.hhf.technology/e_tv/32/2802_2.png) [@E\_Tv](https://forum.hhf.technology/u/E_Tv)\
**Post date:** [July 20, 2025, 3:56am UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956/15 "2025-07-20T03:56:36Z")

</div>

Nvm, I solved it from the help here:

> <https://github.com/sevensolutions/traefik-oidc-auth/issues/100>
>
> \### Feature description
> 
> I am trying to migrate from \`traefik-forward-auth\` to t…his wonderful plugin (thanks for creating it). I use \`Zitadel\` as IdP.
> 
> I made it work fine, except for one thing:
> 
> \- in my homelab, I want to authenticate only if the request comes from the WAN, I'm using the \`X-Real-Ip\` header to whitelist all local+docker networks. With \`traefik-forward-auth\` I used this rule config file:
> 
> \`\`\`console
> \# Allow LAN1
> rule.Allow-LAN1.action = allow
> rule.Allow-LAN1.rule = HeadersRegexp(\`X-Real-Ip\`, \`^10\\.1\\.\`)
> \# Allow LAN2
> rule.Allow-LAN2.action = allow
> rule.Allow-LAN2.rule = HeadersRegexp(\`X-Real-Ip\`, \`^192\\.168\\.\`)
> \# Allow Docker Containers
> rule.Allow-Docker-Net.action = allow
> rule.Allow-Docker-Net.rule = HeadersRegexp(\`X-Real-Ip\`, \`^172\\.19\\.\`)
> \`\`\`
> 
> Would it be possible to implement something like that? Right now, I'm not able to switch to your plugin because of this missing feature.
> 
> Thanks.
> 
> \### Pitch
> 
> Would be nice to have a config section in which we can configure a whitelist based on rules (headers, etc.)
> 
> \### Doing your homework
> 
> \- \[x\] I have searched for similar feature requests and not found a similar one.

As stated on the github issues, traefik needs to be restarted for the condition to start working.

```auto
{
  "traefik-oidc-auth": {
    "BypassAuthenticationRule": "HeaderRegexp(`X-Real-Ip`, `(^|,\\s*)192\\.168\\.(1|67)\\.[0-9]{1,3}($|,)`)",,
    "Provider": {
      "ClientId": "redacted",
      "ClientSecret": "redacted",
      "TokenValidation": "IdToken",
      "Url": "https://id.redacted.com"
    },
    "Scopes": [
      "openid",
      "profile",
      "email"
    ],
    "Secret": "redacted"
  }
}

```

---

<div class="post-metadata">

**Author:** ![Mattercoder](https://forum.hhf.technology/letter_avatar_proxy/v4/letter/m/54ee81/32.png) [@Mattercoder](https://forum.hhf.technology/u/Mattercoder)\
**Post date:** [July 20, 2025, 6:50am UTC](https://forum.hhf.technology/t/direct-oauth2-authentication-with-pocketid-and-traefik-oidc-plugin/1956/16 "2025-07-20T06:50:18Z")

</div>

Cool. I didn’t know you could do that. Great find. Thanks for sharing
