From 259d9621ba2d1914c835d213a8ba2490facc2705 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Thu, 13 Aug 2026 09:59:31 -0400 Subject: [PATCH] feat(adminui): gate the Secrets rail link on the page's own policy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The /admin/secrets link was already in the side rail, but ungated — every authenticated user saw it, and a Designer/Operator clicking it was bounced by the page's own [Authorize(Policy = SecretsAuthorization.ManagePolicy)]. Hide the advertised dead end. Gated on that same policy constant rather than Roles="Administrator". The two are equivalent today (the RCL's AdminRole is "Administrator", read off the same ClaimTypes.Role claim FleetAdmin uses), so this is not about reach — it is that the rail cannot drift if the RCL ever changes its policy. Live-gated on docker-dev, both directions, because the positive half alone proves nothing here: the link rendered for an admin BEFORE this change too, so "admin still sees it" is satisfied equally by a working gate and by an inert one. Negative control — gate swapped to Roles="NoSuchRoleFalsifyProbe", rebuilt, item went to 0 while /role-grants and /apikeys stayed at 1 (the item is hidden, not the rail broken). Restored build hashed to the same image ID as the pre-falsification one, proving the restore was byte-exact. This also rules out AuthorizeView being inert inside ThemeShell's