Timshel / vaultwarden

Fork from dani-garcia/vaultwarden to add OpendID support.
GNU Affero General Public License v3.0
76 stars 12 forks source link

Are we sure that Zitadel doesn't support confidential clients and PKCE ? #52

Closed LeVraiRoiDHyrule closed 4 months ago

LeVraiRoiDHyrule commented 5 months ago

Hi,

I am new to SSO on Vaultwarden and I'm looking forward using it with Zitadel. Vaultwarden SSO documentation says this from https://github.com/Timshel/vaultwarden/blob/f72bd26f3ff469a83f477bfab31af9427c25d67a/SSO.md?plain=1#L196

## Zitadel

To obtain a `refresh_token` to be able to extend session you'll need to add the `offline_access` scope.

Additionnaly Zitadel include the `Project id` and the `Client Id` in the audience of the Id Token.
For the validation to work you will need to add the `Project Id` as a trusted audience (`Client Id` is trusted by default).
You can control the trusted audience with the config:

It appears it's not possible to use PKCE with confidential client so it needs to be disabled.

Config will look like:

    - `SSO_AUTHORITY=https://${provider_host}`
    - `SSO_SCOPES="email profile offline_access"`
    - `SSO_CLIENT_ID`
    - `SSO_CLIENT_SECRET`
  - `SSO_AUDIENCE_TRUSTED='^${Project Id}$'`
  - `SSO_PKCE=false`

But the Zitadel documentation says this from https://zitadel.com/docs/guides/integrate/login/oidc/oauth-recommended-flows#different-client-profiles image

"Web" client profile is used by default with PKCE in Zitadel. I can confirm this works with other apps like Oauth2-proxy. I guess it should work with Zitadel and Vaultwarden SSO too. I couldn't test it due to other problems with SSO.

LeVraiRoiDHyrule commented 5 months ago

Hi again,

I am trying to get Vaultwarden OIDC to work with Zitadel and PKCE with the following settings:

  vaultwarden:
    image: ghcr.io/timshel/vaultwarden:latest
    container_name: vaultwarden
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
      - SSO_ONLY=true
      - DOMAIN=https://vault.${DOMAIN}
      - SIGNUPS_ALLOWED=false
      - INVITATIONS_ALLOWED=false
      - SSO_AUTHORITY=https://auth.${DOMAIN}
      - SSO_PKCE=true
      - SSO_ROLES_ENABLED=true
      - SSO_ENABLED=true
      - SSO_AUDIENCE_TRUSTED='^264076946105696259$'
      - SSO_SCOPES="email profile offline_access
      - SSO_FRONTEND=override
      - SSO_CLIENT_ID=redacted
      - SSO_CLIENT_SECRET=dummy
    networks:
      - services
    volumes:
      - ${CONFIG_FOLDER}/vaultwarden:/data
    restart: unless-stopped

It appears to be correctly sending PKCE but I am getting the following error when trying to log in :

auth.mydomain.com CLIENTIPREDACTED - - [23/Apr/2024:21:44:37 +0200] "GET /oauth/v2/authorize?response_type=code&client_id=REDACTED&state=qgqBM4AwMr7BhhdL3kj7EgAsgoxSgmW5Fw36Q7QfxNotBS8VaWUcwpimwaAJkYx2_identifier%3Dundefined&code_challenge=W4AbiB0tG1GzI-xQYR6TDJczWDGrJT2k_HglACayhGc&code_challenge_method=S256&redirect_uri=https%3A%2F%2Fvault.mydomain.com%2Fidentity%2Fconnect%2Foidc-signin&scope=openid+%22email+profile+offline_access&nonce=Av91kk8hE6JjbVrI1jU2vA HTTP/2.0" 400 184161 "https://vault.mydomain.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0"

This 400 error suggests to me that my configuration is incorrect. Would you have an idea about what I could be doing wrong ?

Thanks in advance for any answer and have a great day

Timshel commented 5 months ago

From what I remember of the Zitadel admin it's impossible to obtain a client id / secret while activating the Authorization code flow with PKCE.

Am I misremembering ?

LeVraiRoiDHyrule commented 5 months ago

From what I remember of the Zitadel admin it's impossible to obtain a client id / secret while activating the Authorization code flow with PKCE.

Am I misremembering ?

With PKCE on Zitadel, I get a client id, but I get no client secret (which is useless with PKCE).

Timshel commented 5 months ago

With PKCE on Zitadel, I get a client id, but I get no client secret (which is useless with PKCE).

While PKCE was implemented for use case where client secret was not possible it's a separate mechanism and some Providers support it in addition to client secret.

The client secret is required for the current implementation of OpenID Connect in Vaultwarden.

Timshel commented 4 months ago

It appears you have managed to make it work using a dummy client secret.

Note that I would not recommend doing this since you lose the added security of the client secret.

Sadly Zitadel do not give much information on why they make such a recommendation. My supposition is that it's due to the fact that to protect against code injection then each client need to correctly implements the nonce verification as defined in https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#name-nonce (which I believe is the case for VW cf: https://github.com/Timshel/vaultwarden/issues/33#issuecomment-1962966732 ).

Of course the simplest is to just use PKCE with client secret and nonce as many other providers allow but it appears there is not much interest in supporting the feature at the moment cf: github.com/zitadel/zitadel/issues/7110

LeVraiRoiDHyrule commented 4 months ago

It appears you have managed to make it work using a dummy client secret.

Note that I would not recommend doing this since you lose the added security of the client secret.

Sadly Zitadel do not give much information on why they make such a recommendation. My supposition is that it's due to the fact that to protect against code injection then each client need to correctly implements the nonce verification as defined in https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#name-nonce (which I believe is the case for VW cf: #33 (comment) ).

Of course the simplest is to just use PKCE with client secret and nonce as many other providers allow but it appears there is not much interest in supporting the feature at the moment cf: github.com/zitadel/zitadel/issues/7110

Hi, What would you recommend doing ? If I do not set any client secret, I have the following error:

  `SSO_CLIENT_ID`, `SSO_CLIENT_SECRET` and `SSO_AUTHORITY` must be set for SSO support
Timshel commented 4 months ago

I meant to use confidential with client id and secret when you define your app in authelia instead of pkce.

LeVraiRoiDHyrule commented 4 months ago

Yes, that would work but isn't the point of PKCE to be more secure ?