Support additional OIDC audiences #5261

Closed
opened 2026-02-05 09:52:10 +03:00 by OVERLORD · 8 comments
Owner

Originally created by @mfechtner on GitHub (Apr 16, 2025).

Describe the feature you'd like

Some issuer send multiple aud claims, which is allowed according to the rfc.
For example Zitadel sends the the project id along with the client id.

It would be nice to have config parameter for additional aud claims, that are allowed.

Describe the benefits this would bring to existing BookStack users

Support more issuer.

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

No, if the issuer can not remove the additional aud claim, the OIDC in bookstack cannot be used.

Have you searched for an existing open/closed issue?

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

How long have you been using BookStack?

Under 3 months

Additional context

No response

Originally created by @mfechtner on GitHub (Apr 16, 2025). ### Describe the feature you'd like Some issuer send multiple aud claims, which is allowed according to the rfc. For example Zitadel sends the the project id along with the client id. It would be nice to have config parameter for additional aud claims, that are allowed. ### Describe the benefits this would bring to existing BookStack users Support more issuer. ### Can the goal of this request already be achieved via other means? No, if the issuer can not remove the additional aud claim, the OIDC in bookstack cannot be used. ### Have you searched for an existing open/closed issue? - [x] I have searched for existing issues and none cover my fundamental request ### How long have you been using BookStack? Under 3 months ### Additional context _No response_
OVERLORD added the 🔨 Feature Request label 2026-02-05 09:52:10 +03:00
Author
Owner

@ssddanbrown commented on GitHub (Apr 16, 2025):

Hi @mfechtner,
Please see #4147 for a lot of prior context and conversation on this.

My comment in #4200 (second example) provides an example of a workaround that can be use to make zitadel's behaviour compatible.

Otherwise, I wouldn't look to add extra options to support the behaviour of specific auth providers, especially where there's a possible workaround.

@ssddanbrown commented on GitHub (Apr 16, 2025): Hi @mfechtner, Please see #4147 for a lot of prior context and conversation on this. My [comment in #4200](https://github.com/BookStackApp/BookStack/issues/4200#issuecomment-1526681299) (second example) provides an example of a workaround that can be use to make zitadel's behaviour compatible. Otherwise, I wouldn't look to add extra options to support the behaviour of specific auth providers, especially where there's a possible workaround.
Author
Owner

@mfechtner commented on GitHub (Apr 16, 2025):

@ssddanbrown Thanks for the prompt reply and sorry, I didn't see the #4147 and #4200.
I would argue that having multiple audiences is part of the spec and is described in a comment here:

fa566f156a/app/Access/Oidc/OidcIdToken.php (L32C9-L35C48)

  1. The Client MUST validate that the aud (audience) Claim contains its client_id value registered
    at the Issuer identified by the iss (issuer) Claim as an audience. The ID Token MUST be rejected
    if the ID Token does not list the Client as a valid audience, or if it contains additional audiences not trusted by the Client.

The part "if it contains additional audiences not trusted by the Client" made me think that there should be an option to define trusted audiences.

Having muliple audiences is also something you can find in other oauth2 implementations.

But I can understand that this is beyond the scope of BookStack, but this feature would make it easier to deploy it without implementing a workaround.

@mfechtner commented on GitHub (Apr 16, 2025): @ssddanbrown Thanks for the prompt reply and sorry, I didn't see the #4147 and #4200. I would argue that having multiple audiences is part of the spec and is described in a comment here: https://github.com/BookStackApp/BookStack/blob/fa566f156ad8998d67a63be2856dafc7ce277d88/app/Access/Oidc/OidcIdToken.php#L32C9-L35C48 > 2. The Client MUST validate that the aud (audience) Claim **_contains_** its client_id value registered > at the Issuer identified by the iss (issuer) Claim as an audience. The ID Token MUST be rejected > if the ID Token does not list the Client as a valid audience, or **_if it contains additional audiences not trusted by the Client_**. The part "if it contains additional audiences not trusted by the Client" made me think that there should be an option to define trusted audiences. Having muliple audiences is also something you can find in other oauth2 implementations. But I can understand that this is beyond the scope of BookStack, but this feature would make it easier to deploy it without implementing a workaround.
Author
Owner

@ssddanbrown commented on GitHub (Apr 16, 2025):

Sure, I know there can be multiple audiences can exist, but it's not used in the context of BookStack, and I still feel like adding options to pass additional audiences through to the validation is very much just a scenario specific workaround.

From my perspective, our OIDC implementation has been tested against quite a few OIDC auth systems now with only Zitadel being problematic in this way, adding weight to the idea that the auth provider adding extra non-client-relevant audiences is non-typical for OIDC.
It doesn't really make sense to me as an intended function for the client anyway (in terms of considering/managing audiences beyond it's own scope), since you'd have scenarios like needing to manage all your clients to update the audiences if there the auth provider adds or changes audiences values. Just seems backwards and, since all other auth providers don't do this, it feels like this is more of a quirk in how Zitadel has decided to perform the communication with clients.

I respect that I've been quite strict (and stubborn on strictness) in regards to my implementation here though, but I'm hesitant to relax that for a specific single outlier, but we do provide non-official flexibility (the provided logical theme workaround).

@ssddanbrown commented on GitHub (Apr 16, 2025): Sure, I know there can be multiple audiences can exist, but it's not used in the context of BookStack, and I still feel like adding options to pass additional audiences through to the validation is very much just a scenario specific workaround. From my perspective, our OIDC implementation has been tested against quite a few OIDC auth systems now with only Zitadel being problematic in this way, adding weight to the idea that the auth provider adding extra non-client-relevant audiences is non-typical for OIDC. It doesn't really make sense to me as an intended function for the client anyway (in terms of considering/managing audiences beyond it's own scope), since you'd have scenarios like needing to manage all your clients to update the audiences if there the auth provider adds or changes audiences values. Just seems backwards and, since all other auth providers don't do this, it feels like this is more of a quirk in how Zitadel has decided to perform the communication with clients. I respect that I've been quite strict (and stubborn on strictness) in regards to my implementation here though, but I'm hesitant to relax that for a specific single outlier, but we do provide non-official flexibility (the provided logical theme workaround).
Author
Owner

@mfechtner commented on GitHub (Apr 16, 2025):

I do respect your arguments and do also think it is a quirks of zitadel that it behaves like this by default without the option to alter that behavior.
That said, we will use the provided workaround.

Thanks for your time.

@mfechtner commented on GitHub (Apr 16, 2025): I do respect your arguments and do also think it is a quirks of zitadel that it behaves like this by default without the option to alter that behavior. That said, we will use the provided workaround. Thanks for your time.
Author
Owner

@ssddanbrown commented on GitHub (Apr 16, 2025):

No worries, thank you for your understanding!

@ssddanbrown commented on GitHub (Apr 16, 2025): No worries, thank you for your understanding!
Author
Owner

@dragetd commented on GitHub (Jul 30, 2025):

It would be helpful, if this workaroud was document in the documentation, tho. It is not clear from this issue (if this is found at all), where to patch/hook/extend the theme with that snippet.

The code itself looks sound (using the azp).

@dragetd commented on GitHub (Jul 30, 2025): It would be helpful, if this workaroud was document in the documentation, tho. It is not clear from this issue (if this is found at all), where to patch/hook/extend the theme with that snippet. The code itself looks sound (using the azp).
Author
Owner

@dragetd commented on GitHub (Jul 30, 2025):

For future people:

The theme directory is also mounted in the docker compose example (.../www/themes) where I created 'zitadel_fix/functions.php' with the content as posted in https://github.com/BookStackApp/BookStack/issues/4200 . Then I also set the env var "APP_THEME=zitadel_fix" and this did the trick.

I also wanted to create 'bookstack_xxx' roles in my Zitadel and extended the function to map the roles into the 'groups' claim which is used by default:

<?php

use BookStack\Facades\Theme;
use BookStack\Theming\ThemeEvents;

Theme::listen(ThemeEvents::OIDC_ID_TOKEN_PRE_VALIDATE, function (array $idTokenData, array $accessTokenData) {
    $changes = [];
    if (is_array($idTokenData['aud']) && in_array($idTokenData['azp'], $idTokenData['aud'])) {
        $changes['aud'] = [$idTokenData['azp']];
    }
    if (isset($idTokenData['urn:zitadel:iam:org:project:roles'])) {
        foreach ($idTokenData['urn:zitadel:iam:org:project:roles'] as $role => $v) {
            if (strpos($role, 'bookstack_') === 0) {
                $changes['groups'][] = substr($role, 10);
            }
        }
    }
    return $changes ? array_merge($idTokenData, $changes) : null;
});

Now, setting the env vars "OIDC_USER_TO_GROUPS=true" and "OIDC_ADDITIONAL_SCOPES=urn:zitadel:iam:org:project:roles" made bookstack honor my 'bookstack_admin' role for my user. :)

@dragetd commented on GitHub (Jul 30, 2025): For future people: The theme directory is also mounted in the docker compose example (.../www/themes) where I created 'zitadel_fix/functions.php' with the content as posted in https://github.com/BookStackApp/BookStack/issues/4200 . Then I also set the env var "APP_THEME=zitadel_fix" and this did the trick. I also wanted to create 'bookstack_xxx' roles in my Zitadel and extended the function to map the roles into the 'groups' claim which is used by default: ```php <?php use BookStack\Facades\Theme; use BookStack\Theming\ThemeEvents; Theme::listen(ThemeEvents::OIDC_ID_TOKEN_PRE_VALIDATE, function (array $idTokenData, array $accessTokenData) { $changes = []; if (is_array($idTokenData['aud']) && in_array($idTokenData['azp'], $idTokenData['aud'])) { $changes['aud'] = [$idTokenData['azp']]; } if (isset($idTokenData['urn:zitadel:iam:org:project:roles'])) { foreach ($idTokenData['urn:zitadel:iam:org:project:roles'] as $role => $v) { if (strpos($role, 'bookstack_') === 0) { $changes['groups'][] = substr($role, 10); } } } return $changes ? array_merge($idTokenData, $changes) : null; }); ``` Now, setting the env vars "OIDC_USER_TO_GROUPS=true" and "OIDC_ADDITIONAL_SCOPES=urn:zitadel:iam:org:project:roles" made bookstack honor my 'bookstack_admin' role for my user. :)
Author
Owner

@mreho commented on GitHub (Dec 15, 2025):

Thank you @dragetd !

@mreho commented on GitHub (Dec 15, 2025): Thank you @dragetd !
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/BookStack#5261