Problem/Motivation

The assurance gate method pins exactly one issuer and one audience per gated field: AssuranceVerifier::verify() compares iss byte-exact against a single configured issuer and requires a single configured audience, and the field-level required_acr list applies to whatever token passed. A deployment with more than one trusted identity provider — for example a staff realm plus a customer realm, or environment-qualified audiences on a shared realm — cannot express "accept tokens from these issuers, each with its own audience and its own accepted acr values".

Anything other than "everyone authenticates in one realm" needs a list.

Proposed resolution

Add a trusted_issuers list to the assurance method settings. Each entry carries issuer, audience, and required_acr. Matching rules, all fail-closed:

- An incoming token selects exactly one entry by byte-exact iss. No cross-matching: a token from issuer A can never satisfy issuer B's audience or acr list.
- No laxer fallback: an unknown iss is rejected, before any JWKS discovery request is made (the unverified iss only selects among admin-configured entries, never supplies a URL, so the existing SSRF property is preserved).
- Signature verification still uses the configured entry's JWKS via OIDC discovery; iss is re-checked byte-exact after verification.
- Two entries with the same issuer are a configuration error; the set is invalid and verification fails closed.
- The matched entry's required_acr drives the acr decision. The flat field-level list survives only to advertise acr_values in challenges (the union across entries).

Backwards compatibility: the existing single-issuer settings shape (issuer, audience, required_acr) keeps working, treated as a one-entry list at read time. No update hook.

Remaining tasks

Development happens on the project's GitHub repository (Wilkes-Liberty/file_gate, issue #60); the merge request / PR will be cross-linked here for review.

Comments

jmcerda created an issue. See original summary.

jmcerda’s picture

Status: Active » Fixed

Implemented and released in 1.6.0 (https://www.drupal.org/project/file_gate/releases/1.6.0).

The assurance method accepts a trusted_issuers list — each entry with its own issuer, audience, and accepted acr values. Matching is exactly-one by iss, byte-exact, with no cross-matching between entries and no fallback; an unknown issuer is denied before any discovery or JWKS request. Duplicate issuers invalidate the whole set (fail closed, configuration error logged). The legacy single-issuer keys keep working as a one-entry list with no update hook; saving the field settings form migrates them.

Development PR with the full test coverage (35 kernel cases including the cross-matching denials, plus a 9-case unit suite for the set normalization): https://github.com/Wilkes-Liberty/file_gate/pull/64

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.