[Security] Decide IS_AUTHENTICATED_RECENTLY through the trust resolver - #66035
Open
nicolas-grekas wants to merge 1 commit into
Open
Conversation
nicolas-grekas
added this pull request to stack #66017
September 13, 2026 08:43
nicolas-grekas
force-pushed
the
is-authenticated-recently-trust-resolver
branch
from
September 13, 2026 08:54
3272500 to
1998c56
Compare
Time is a reasonable default but a poor sole signal: an application may want to weigh whether the IP address changed, how long ago the last activity was, or whether a second factor was confirmed recently. AuthenticationTrustResolver::isAuthenticatedRecently() is where that decision now lives, so overriding it replaces the strategy without touching the attribute it answers. The method is announced with @method on the interface rather than declared on it, so a custom trust resolver keeps working and gets a deprecation until 9.0.
nicolas-grekas
force-pushed
the
is-authenticated-recently-trust-resolver
branch
from
September 13, 2026 09:00
1998c56 to
5c0c26d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part 4 of the sudo mode stack, on top of #66016. This answers the point raised on #66014: time is a reasonable default but a poor sole signal, and an application should be able to weigh other risk factors, such as whether the IP address changed since the last authentication, a last-activity timer, or a recently confirmed second factor.
AuthenticationTrustResolver::isAuthenticatedRecently()is where that decision now lives, so overriding it replaces the whole strategy without touching the attribute it answers:BC
The method is announced with
@methodonAuthenticationTrustResolverInterfacerather than declared on it, soDebugClassLoaderreports a custom resolver that does not implement it, and until the method joins the interface in 9.0AuthenticatedVoterdeniesIS_AUTHENTICATED_RECENTLYfor such a resolver rather than guessing. Failing closed is the right direction for an authorization attribute, and it keeps the voter free of a second copy of the strategy. Covered under#[Group('legacy')].The lifetime and the clock move from
AuthenticatedVotertoAuthenticationTrustResolver, which is where the strategy now is; the voter takes only the trust resolver again. Both arguments were introduced in #66014 in this same stack and have never been released, so nothing is owed for the move.security.recent_authentication_lifetimeis unchanged, it is simply wired to the trust resolver instead.Being full fledged stays an invariant of the attribute
The voter keeps checking
isFullFledged()itself before consulting the strategy. That is not distrust of the resolver: it is that the relationship between the attributes belongs to the attribute, not to the strategy.IS_AUTHENTICATED_RECENTLYis strictly stronger thanIS_AUTHENTICATED_FULLY, and a remember-me cookie is precisely not proof that the user still holds their credentials, so the easiest possible override (returning true from some risk heuristic) must not be able to grant sudo on one. A test pins it.It is not over-restrictive either:
isFullFledged()is itself a method of the trust resolver, so an application that redefines what full fledged means still has that respected. The defaultisAuthenticatedRecently()keeps its own guard as well, because it is public API that can be called on its own; an override does not need to repeat it.Deliberately unchanged
A last-activity timer is the one signal on that list that would be wrong to fold into the default. Refreshing the stamp on activity would make the attribute measure presence rather than possession of credentials, which is the opposite of what sudo mode is for. An application that genuinely wants that can express it in an override, which is exactly why this is an extension point rather than a config flag.