Resume
Description
Right now most routes are reachable anonymously — /, /assistant/{id},
the catalogue, etc. We want the opposite default: every page requires
an authenticated user, and only a short allow-list is reachable without
signing in.
Allow-list (reachable without authentication):
Everything else (frontpage, catalogue, assistant detail, profile,
admin) is gated behind IS_AUTHENTICATED_FULLY. Anonymous visitors
hitting those routes get the standard 302 to /login with the target
URL preserved so they land back on the page after signing in.
Tasks
Out of scope
- Implementing the new-password / password-reset flow itself.
Reserve the route name and add it to the allow-list when that
PR opens.
- Per-role gating beyond
IS_AUTHENTICATED_FULLY — voters and
ROLE_* checks stay on the controllers that already use them
(admin user-management, etc.).
Details - AI specificities
- Symfony docs:
https://symfony.com/doc/current/security/access_control.html.
- The existing
main firewall in config/packages/security.yaml
already carries form_login + logout config. The
access_control block is what we extend.
- Order matters: the allow-list paths (
/login, /register*) need
to match IS_AUTHENTICATED_ANONYMOUSLY (or PUBLIC_ACCESS)
before the catch-all IS_AUTHENTICATED_FULLY line.
- Don't gate
/_wdt, /_profiler, or asset routes (the existing
dev firewall already excludes them — confirm prod doesn't trip
on them).
- Tests live under
tests/Integration/Controller/ — add a
dedicated AccessControlTest or extend an existing controller
test, whichever reads better.
Resume
Description
Right now most routes are reachable anonymously —
/,/assistant/{id},the catalogue, etc. We want the opposite default: every page requires
an authenticated user, and only a short allow-list is reachable without
signing in.
Allow-list (reachable without authentication):
/login— sign-in form/register— anonymous self-signup (feat: anonymous self-signup with email-domain allow-list #62 / feat(registration): anonymous self-signup with email-domain allow-list (#62) #90)/register/pending— "thanks, awaiting approval" landing pagescope for now beyond reserving a slot.
Everything else (frontpage, catalogue, assistant detail, profile,
admin) is gated behind
IS_AUTHENTICATED_FULLY. Anonymous visitorshitting those routes get the standard 302 to
/loginwith the targetURL preserved so they land back on the page after signing in.
Tasks
access_controlrule inconfig/packages/security.yamlthat denies anonymous access by default, with explicit
allow-list entries for the public routes (
/login,/register,/register/pending, password-reset pages oncethey land).
target URL (Symfony does this by default; verify).
/redirects to for unauthenticated visitors —/loginor a public landing page outside the app shell.anonymously) and at least one gated route (302 to
/login).### Added.Out of scope
Reserve the route name and add it to the allow-list when that
PR opens.
IS_AUTHENTICATED_FULLY— voters andROLE_*checks stay on the controllers that already use them(admin user-management, etc.).
Details - AI specificities
https://symfony.com/doc/current/security/access_control.html.
mainfirewall inconfig/packages/security.yamlalready carries
form_login+logoutconfig. Theaccess_controlblock is what we extend./login,/register*) needto match
IS_AUTHENTICATED_ANONYMOUSLY(orPUBLIC_ACCESS)before the catch-all
IS_AUTHENTICATED_FULLYline./_wdt,/_profiler, or asset routes (the existingdevfirewall already excludes them — confirm prod doesn't tripon them).
tests/Integration/Controller/— add adedicated
AccessControlTestor extend an existing controllertest, whichever reads better.