Problem/Motivation
Split out of #3613761, where the design was settled. Dual-venue record for GitHub #31.
Mint performs no entity or field access check. A back end holding the shared secret can mint for any gated file. This adds an optional way for that back end to say "issue this on behalf of user X", so the grant cannot exceed what X could reach themselves.
Proposed resolution
Accept an optional acting account on the mint payload. When supplied, run the file's own access check (and the referencing entity's, where one applies).
Three constraints on the shape:
- Optional, not mandatory — see below.
- Additive. An extra constraint on top of the front end's own gate, never a replacement. File Gate does not know whether the lead form was filled in; that stays the caller's business.
- Fail closed when supplied. An unresolvable or unknown account must deny. A parameter that silently degrades to "no check" is worse than not having it, because the caller believes a constraint is in force.
Why optional rather than mandatory
It does not fit the module's premise. File Gate exists because Drupal's entity access is too permissive for private files — the README's framing is that private:// means "not guessable", not "gated". Layering entity access back onto mint adds a different and weaker guarantee rather than restoring one.
The headline use case has no user. Lead capture, campaign tokens and OTP are all anonymous. A mandatory check would break the module's primary scenario outright.
And for that scenario it solves nothing about blast radius. With no acting account there is nothing to check, and the secret remains a bearer token for the entire corpus. That problem belongs to the scoped-secrets issue, not this one.
So this is defense in depth for the authenticated subset — real value on the Commerce and Assurance paths, near zero for lead generation. Worth having, and worth not overstating.
Open question: whether the account is identified by uid, uuid or name in the payload. Leaning uuid — it does not leak sequential ids to a front end and it survives content migrations.
API changes
Additive. The mint payload gains an optional field; callers that omit it keep today's behaviour.
Comments
Comment #2
jmcerdaFixed in 1.2.0.
https://www.drupal.org/project/file_gate/releases/1.2.0
Optional mint body account (user UUID) or uid: fail closed unless that account may download the file and view referencing host entities. Omitted for anonymous lead-capture flows.
Comment #4
jmcerdaFixed in 1.2.0.
https://www.drupal.org/project/file_gate/releases/1.2.0
Optional mint body account (user UUID) or uid: fail closed unless that account may download the file and view referencing host entities. Omitted for anonymous lead-capture flows.
Comment #5
jmcerdaClosing as shipped in 1.2.0. (Was Fixed; closed now that the release is public.)