The custom admin actions for sponsorships and contracts (registered in `apps/sponsors/admin.py` via `self.admin_site.admin_view(...)`) can be tightened in two ways. This was reported privately to the PSF Security Team, who suggested opening a public issue as a hardening opportunity since it requires an existing staff account. ### 1. Custom admin actions don't enforce the per-model permission `AdminSite.admin_view` verifies `is_active` + `is_staff` only, not the model's change permission, so any staff user can drive the sponsorship / contract workflow actions (approve / reject / lock / unlock / send / execute / nullify / ...) regardless of their assigned `sponsors` permissions. ### 2. `lock` mutates on a GET (no confirmation / CSRF token) `views_admin.lock_view` sets `locked = True` and saves on a plain GET, with no method check and no confirmation step — unlike its sibling `unlock_view`, which renders a confirmation page and only mutates on POST. ### Proposed hardening - Require the model change permission on each custom admin action URL. - Give `lock` the same POST + confirmation flow `unlock` already uses. I have a PR ready.