Skip to content

docs: document the OIDC audience parameter - #137

Draft
oc-tmueller wants to merge 1 commit into
mainfrom
docs/oidc-audience-parameter
Draft

oc-tmueller wants to merge 1 commit into
mainfrom
docs/oidc-audience-parameter

Conversation

@oc-tmueller

Copy link
Copy Markdown
Contributor

Documents the audience key the openidconnect app gains in owncloud/openidconnect#374 (fixes owncloud/openidconnect#373).

Why

An access token is accepted only if it names the ownCloud relying party. Until now the expected value was always the configured client-id — which is the ID token rule (OpenID Connect Core 1.0 §2), not the access-token one. RFC 9068 §3 defines an access token's aud as the resource server, so providers that address the resource send something else entirely and could not authenticate.

Microsoft ADFS is the case that made this necessary. It takes the identifier of the relying party trust and prefixes it with microsoft:identityserver: unless that identifier is already a URL — so an admin whose relying party identifier is their client-id GUID sees aud: "microsoft:identityserver:<guid>" and has nothing to configure. ADFS is already listed as a supported IdP in configuration/user/oidc/oidc.adoc, so this gap was reachable from a documented setup.

What

Adds an audience:: entry to the OIDC parameter reference in config_apps_sample_php_parameters.adoc (the page both oidc.adoc and kopano-setup.adoc xref for the full key list), for the two versions the app change ships on:

  • content/server/11.0/... — app 2.4.2
  • content/server/10.16/... — app 2.3.5

The entry covers the default (client-id), the accepted shapes, that it replaces rather than extends the client-id, and how to find the ADFS value.

It deliberately documents the operational consequences rather than just the syntax, because each one is a way to take an instance offline:

  • Once set, the audience becomes authoritative, so a token issued to a different client of the same IdP is accepted whenever its aud matches — the RFC 7662 client_id check no longer applies. The entry says to pick a value only ownCloud can be issued for, and not to reuse a tenant-wide resource identifier.
  • It must not be set at all if the token introspection response omits aud (which RFC 7662 permits), because every opaque token would then be rejected.
  • With exchange-token-mode-before-introspection, the first usable list entry is also what the token exchange requests from the IdP.
  • Values that cannot be an audience (number, boolean, empty string, empty list) are discarded, and if none is left every access token is rejected.

Two deliberate choices:

Both ADFS cmdlets are named. Get-AdfsWebApiApplication for an OpenID Connect application group, Get-AdfsRelyingPartyTrust for a legacy WS-Federation or SAML trust. Naming only the latter — as the first draft did — would strand admins whose OIDC registration is an application group, which is the modern default on ADFS 2016+.

No app version is claimed. Neither release carrying the fix is tagged yet (tags stop at v2.4.1; the oC11 change sits under ## [Unreleased]), so the entry points at the issue instead of asserting a number that could be off by a release.

Placed alphabetically between allowed-user-backends and auth-params. The two files' entries are byte-identical.

Checks

Full local CI equivalent — npm ci, npm run antora, npm test — all pass, and the built pages carry the entry in both versions.

Rendered output confirms the entry is a proper definition term in the right position:

<dt class="hdlist1">allowed-user-backends</dt>
<dt class="hdlist1">audience</dt>            <- new
<dt class="hdlist1">auth-params</dt>

Note this is the file's first use of + list continuation (the entry needs three paragraphs). Verified in the rendered HTML that all three attach to audience and that every following term still parses as its own <dt>.

Every factual claim was checked line-by-line against the implementation in owncloud/openidconnect#374 rather than against its README alone.

Docs-only; no nav or xref changes.

🤖 Generated with Claude Code

The openidconnect app gains an optional "audience" key naming the value the IdP
puts into the access token's "aud" claim. It defaults to client-id, and is
needed by IdPs that address the resource server instead - RFC 9068 §3 defines
an access token's "aud" that way, and Microsoft ADFS follows it, prefixing the
application identifier with "microsoft:identityserver:" unless that identifier
is already a URL.

Documented for 11.0 and 10.16, the two versions the app change ships on.

The entry covers the operational consequences rather than just the syntax,
because each of them is a way to lock an instance out: the audience becomes
authoritative once set, so a token issued to another client of the same IdP is
accepted when its "aud" matches, an introspection response that omits "aud"
can no longer be used at all, and with token-exchange mode the first list entry
is what gets requested from the IdP. Values that cannot be an audience are
discarded, and if none is left every access token is rejected.

For finding the ADFS value, both cmdlets are named: Get-AdfsWebApiApplication
for an OpenID Connect application group, Get-AdfsRelyingPartyTrust for a legacy
WS-Federation or SAML trust. Naming only the latter would strand admins whose
OIDC registration is an application group, which is the modern default.

No app version numbers are claimed: neither release carrying the fix is tagged
yet, so the entry points at the issue instead.

See owncloud/openidconnect#373 and owncloud/openidconnect#374

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Thomas Müller <323649642+oc-tmueller@users.noreply.github.com>
@oc-tmueller
oc-tmueller marked this pull request as draft September 18, 2026 11:07
@oc-tmueller

Copy link
Copy Markdown
Contributor Author

Converted to draft — do not merge as-is. I authored this by hand, and this page is generated.

config_apps_sample_php_parameters.adoc is produced by config-to-docs from config/config.apps.sample.php in owncloud/core, which says so itself:

This file is also used to generate the configuration documentation using config-to-docs.

// header end do not delete or edit this line on line 25 is the generator's sentinel: everything above it is carried over from the existing file, everything below is rewritten wholesale. My audience:: entry is at line 398, so the next ctd.sh run would silently delete it. That this rendered correctly and passed CI is exactly the problem.

The pipeline is live, not dead — core changelog 11.0.0_2026-07-30/41668 removed the msteamsbridge sample block "so the config-to-docs sync no longer re-adds the parameters to the admin documentation", and the published pages track their core branch exactly (10.16 still has Microsoft Teams Bridge and the older "sub-keys" spelling; 11.0 has neither).

What this PR becomes

  1. The key gets documented in config/config.apps.sample.php on core master and 10.16 — waiting on fix: let the expected access token audience be configured openidconnect#374 merging and a release being cut, so the entry can name a version in that file's own style rather than linking an issue.
  2. This PR is then regenerated, so its diff is byte-for-byte generator output and the next regeneration is a no-op.
  3. The narrative half — the three ways setting audience can lock an instance out, and the exchange-token-mode-before-introspection interaction — moves to hand-authored configuration/user/oidc/oidc.adoc, which can xref properly. The generated entry keeps the inventory: name, default, accepted shapes, the AD FS derivation rule.

Verified in the meantime: both pages here are currently byte-in-sync with core, so the regeneration will add only the new entry and no unrelated drift.

Two side findings, each getting its own PR: 10.16's sibling page config_sample_php_parameters.adoc is stale by a web-updater.enabled block, and ctd.sh still writes to owncloud/docs-server — archived last month — at the pre-monorepo path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AD FS access token audience validation fails with microsoft:identityserver:<client-id>

2 participants