Problem
Browser extensions that inject NIP-98 Authorization headers (e.g. Podkey) break Solid-OIDC flows when they overwrite headers on already-authenticated requests.
Observed flow on solid.social:
- User signs in via Solid-OIDC as WebID
https://test.solid.social/profile/card.jsonld#me
- Pilot (or any OIDC client) makes an authenticated request — session cookie + DPoP token present
- Podkey intercepts and adds an
Authorization: Nostr ... header signed with a random Nostr key it holds
- JSS's auth middleware sees the NIP-98 header first, resolves to
did:nostr:<podkey-random-key>
- ACL grants access to the WebID, not to the random Nostr key → 403 Forbidden
The user is authenticated as the pod owner, but the server reads a different identity and denies writes to their own profile.
Proposed fix
When a request carries multiple credentials, prefer the one associated with the active session over ambient injected headers. Concretely:
- If a valid Solid-OIDC session cookie + DPoP proof are present → resolve identity from OIDC
- Only fall back to NIP-98 Bearer when OIDC is not present
This mirrors how browsers resolve identity for mixed auth layers (cookies + Authorization): the active session takes precedence.
Impact
Without this, any browser extension that auto-signs with NIP-98 effectively breaks Solid-OIDC on JSS pods. Users can't edit their own profiles while the extension is enabled.
Workaround
Disable the injecting extension (or use incognito). Not viable long-term — users shouldn't have to disable Nostr extensions to use their Solid pod.
Reference
Debugged on solid.social with JSS v0.0.149 and pilot. Disabling Podkey fully (all sites) fixed the PUT; toggling it off on one site kept the interception active and preserved the 403.
Problem
Browser extensions that inject NIP-98
Authorizationheaders (e.g. Podkey) break Solid-OIDC flows when they overwrite headers on already-authenticated requests.Observed flow on solid.social:
https://test.solid.social/profile/card.jsonld#meAuthorization: Nostr ...header signed with a random Nostr key it holdsdid:nostr:<podkey-random-key>The user is authenticated as the pod owner, but the server reads a different identity and denies writes to their own profile.
Proposed fix
When a request carries multiple credentials, prefer the one associated with the active session over ambient injected headers. Concretely:
This mirrors how browsers resolve identity for mixed auth layers (cookies + Authorization): the active session takes precedence.
Impact
Without this, any browser extension that auto-signs with NIP-98 effectively breaks Solid-OIDC on JSS pods. Users can't edit their own profiles while the extension is enabled.
Workaround
Disable the injecting extension (or use incognito). Not viable long-term — users shouldn't have to disable Nostr extensions to use their Solid pod.
Reference
Debugged on solid.social with JSS v0.0.149 and pilot. Disabling Podkey fully (all sites) fixed the PUT; toggling it off on one site kept the interception active and preserved the 403.