🐛 Bug Report: (Caddy-security + Pocket-Id) Token expiry causes 401 error and needs manual fixing #364

Closed
opened 2025-10-08 00:05:11 +03:00 by OVERLORD · 7 comments
Owner

Originally created by @empressmarissa on GitHub.

Reproduction steps

When a token expires it doesn't seem to redirect to either the login page or auto-renewal of the token. As soon as the token expires I get send to a blank page (I get a 401 back from Caddy, see below for response and log). Manually deleting the cookie and going back to the domain (code.domain.tld) is the only way to get it to work again (it needs me to reauthenticate with pocket-id passkey).

Using Firefox, Caddy (with Caddy Security, both latest) as a proxy for my services and Pocket-Id v0.27.2

After token expiry firefox tries to navigate to this page, returning a 401 and nothing else happening.
GET https://code.domain.tld/auth/oauth2/generic/?login_hint=<EMAIL>&redirect_url=https://code.domain.tld/?folder=/appdata

RESPONSE

HTTP/2 401 
alt-svc: h3=":443"; ma=2592000
server: Caddy
set-cookie: access_token=delete; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT
content-length: 0
date: Sun, 02 Feb 2025 21:04:56 GMT
X-Firefox-Spdy: h2

Caddy Logs:

{
    "level": "error",
    "ts": 1738530296.4880683,
    "logger": "http.handlers.authentication",
    "msg": "auth provider returned error",
    "provider": "authorizer",
    "error": "user authorization failed: src_ip=<PC_IP>, src_conn_ip=<PC_IP>, sub=df5f1f27-ec07-4a19-9d8d-8ba8b668c34c, name=<NAME>, jti=k9Csb5Aorws8szW5fxxHckQ9ffuFTJ3DFsSqR, email=<EMAIL>, reason: keystore: parsed token has expired"
}

Relevant Caddyfile bits:

{
    # Configure caddy-security.
    order authenticate before respond
    security {
        oauth identity provider generic {
            delay_start 3
            realm generic
            driver generic
            client_id {env.CLIENT_ID}
            client_secret {env.CLIENT_SECRET}
            scopes openid email profile
            base_auth_url https://pocket-id.domain.tld/
            metadata_url https://pocket-id.domain.tld/.well-known/openid-configuration
        }

        authentication portal myportal {
            crypto default token lifetime 3600 # Seconds until you have to re-authenticate
            enable identity provider generic
            cookie insecure off # Set to "on" if you're not using HTTPS

            transform user {
                match realm generic
                action add role user
            }
        }

        authorization policy mypolicy {
            set auth url /auth/oauth2/generic
            allow roles user
            inject headers with claims
        }
    }
}

(hyperionauth) {
	@auth {
		path /auth/oauth2/generic
		path /auth/oauth2/generic/authorization-code-callback
	}

	route @auth {
		authenticate with myportal
	}
}

(blockremote) {
	@denied not remote_ip private_ranges
	abort @denied
}

pocket-id.domain.tld {
	import blockremote

	reverse_proxy pocket-id:80
}

homepage.domain.tld {
	import blockremote
	import hyperionauth

	route /* {
		authorize with mypolicy
		reverse_proxy homepage:3000
	}
}

code.domain.tld {
	import blockremote
	import hyperionauth

	route /* {
		authorize with mypolicy
		reverse_proxy code-server:8443
	}
}

Pocket-ID setup:
OIDC Client has a single (wildcard) callback url: https://*.domain.tld/auth/oauth2/generic/authorization-code-callback

Expected behavior

It should redirect me to my pocket-id login page or do a silent renew of my token

Actual Behavior

See above, the page refuses to load (401, access-token cookie doesn't get removed either). Only manually deleting the cookie and navigating to the base domain seems to work. I'm sure I'm missing something incredibly simple here but I'm staring at blanks at the moment.

Version and Environment

v0.27.2

Log Output

No response

Originally created by @empressmarissa on GitHub. ### Reproduction steps When a token expires it doesn't seem to redirect to either the login page or auto-renewal of the token. As soon as the token expires I get send to a blank page (I get a 401 back from Caddy, see below for response and log). Manually deleting the cookie and going back to the domain (code.domain.tld) is the only way to get it to work again (it needs me to reauthenticate with pocket-id passkey). Using Firefox, Caddy (with Caddy Security, both latest) as a proxy for my services and Pocket-Id v0.27.2 After token expiry firefox tries to navigate to this page, returning a 401 and nothing else happening. `GET https://code.domain.tld/auth/oauth2/generic/?login_hint=<EMAIL>&redirect_url=https://code.domain.tld/?folder=/appdata` RESPONSE ``` HTTP/2 401 alt-svc: h3=":443"; ma=2592000 server: Caddy set-cookie: access_token=delete; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT content-length: 0 date: Sun, 02 Feb 2025 21:04:56 GMT X-Firefox-Spdy: h2 ``` Caddy Logs: ``` { "level": "error", "ts": 1738530296.4880683, "logger": "http.handlers.authentication", "msg": "auth provider returned error", "provider": "authorizer", "error": "user authorization failed: src_ip=<PC_IP>, src_conn_ip=<PC_IP>, sub=df5f1f27-ec07-4a19-9d8d-8ba8b668c34c, name=<NAME>, jti=k9Csb5Aorws8szW5fxxHckQ9ffuFTJ3DFsSqR, email=<EMAIL>, reason: keystore: parsed token has expired" } ``` Relevant Caddyfile bits: ``` { # Configure caddy-security. order authenticate before respond security { oauth identity provider generic { delay_start 3 realm generic driver generic client_id {env.CLIENT_ID} client_secret {env.CLIENT_SECRET} scopes openid email profile base_auth_url https://pocket-id.domain.tld/ metadata_url https://pocket-id.domain.tld/.well-known/openid-configuration } authentication portal myportal { crypto default token lifetime 3600 # Seconds until you have to re-authenticate enable identity provider generic cookie insecure off # Set to "on" if you're not using HTTPS transform user { match realm generic action add role user } } authorization policy mypolicy { set auth url /auth/oauth2/generic allow roles user inject headers with claims } } } (hyperionauth) { @auth { path /auth/oauth2/generic path /auth/oauth2/generic/authorization-code-callback } route @auth { authenticate with myportal } } (blockremote) { @denied not remote_ip private_ranges abort @denied } pocket-id.domain.tld { import blockremote reverse_proxy pocket-id:80 } homepage.domain.tld { import blockremote import hyperionauth route /* { authorize with mypolicy reverse_proxy homepage:3000 } } code.domain.tld { import blockremote import hyperionauth route /* { authorize with mypolicy reverse_proxy code-server:8443 } } ``` Pocket-ID setup: OIDC Client has a single (wildcard) callback url: https://*.domain.tld/auth/oauth2/generic/authorization-code-callback ### Expected behavior It should redirect me to my pocket-id login page or do a silent renew of my token ### Actual Behavior See above, the page refuses to load (401, access-token cookie doesn't get removed either). Only manually deleting the cookie and navigating to the base domain seems to work. I'm sure I'm missing something incredibly simple here but I'm staring at blanks at the moment. ### Version and Environment v0.27.2 ### Log Output _No response_
OVERLORD added the bug label 2025-10-08 00:05:11 +03:00
Author
Owner

@TreatnHerRight commented on GitHub:

Happening with me as well. Had to clear the cookie and re authenticate.

Version v0.28.0

@TreatnHerRight commented on GitHub: Happening with me as well. Had to clear the cookie and re authenticate. Version v0.28.0
Author
Owner

@kmendell commented on GitHub:

Ill confirm this issue, Its happened to me as well. I started to look into it , but then got side tracked. Ill see what i can find.

@kmendell commented on GitHub: Ill confirm this issue, Its happened to me as well. I started to look into it , but then got side tracked. Ill see what i can find.
Author
Owner

@stonith404 commented on GitHub:

It's probably not a issue with Pocket ID itself but with the example Caddy configuration from the docs.

@stonith404 commented on GitHub: It's probably not a issue with Pocket ID itself but with the example Caddy configuration from the docs.
Author
Owner

@empressmarissa commented on GitHub:

Upgraded to v0.28.0, issue still persists (didn't expect it to get fixed by that version anyway).

@empressmarissa commented on GitHub: Upgraded to v0.28.0, issue still persists (didn't expect it to get fixed by that version anyway).
Author
Owner

@kmendell commented on GitHub:

@stonith404 Ill try to show you this later tonight, as i have many caddy-security apps setup, so i can try to reproduce it for you to help troubleshoot.

@kmendell commented on GitHub: @stonith404 Ill try to show you this later tonight, as i have many caddy-security apps setup, so i can try to reproduce it for you to help troubleshoot.
Author
Owner

@TreatnHerRight commented on GitHub:

The example was actually wrong. The updated example should now work correctly with re-authentication. See my commit (19ef483) for the necessary changes.

The new config successfully routes correctly. I will report back if i get the 401 error.

@TreatnHerRight commented on GitHub: > The example was actually wrong. The updated example should now work correctly with re-authentication. See my commit ([19ef483](https://github.com/stonith404/pocket-id/commit/19ef4833e927b9bf4984b43913a39ed58a45a98f)) for the necessary changes. The new config successfully routes correctly. I will report back if i get the 401 error.
Author
Owner

@stonith404 commented on GitHub:

The example was actually wrong. The updated example should now work correctly with re-authentication. See my commit (19ef4833e9) for the necessary changes.

@stonith404 commented on GitHub: The example was actually wrong. The updated example should now work correctly with re-authentication. See my commit (https://github.com/stonith404/pocket-id/commit/19ef4833e927b9bf4984b43913a39ed58a45a98f) for the necessary changes.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/pocket-id-pocket-id-1#364