diff --git a/AGENTS.md b/AGENTS.md
index e7ed193..570a778 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -35,10 +35,28 @@ Rules:
- Status pills and tinted panels: `var(--color-{info,success,warning,danger,primary}-50)` background with the matching `-700` text. These flip per theme; the pale `#eff6ff`/`#fef3c7`/`#fee2e2` hexes do not.
- Solid saturated fills (a colored button background, a status dot, an icon) may stay as a saturated color; those read on both themes. Do not convert those to the `-50` tints.
- Inputs/selects must set both `background` and `color` (a missing `color` shows black text on a dark surface). Prefer `BaseInput`/`BaseSelect`, which handle this.
+- Native form controls are not accepted when a base primitive supports the same control. Theme correctness belongs to the primitive, not each page.
+- Every changed form must be exercised with `data-theme="light"` and `data-theme="dark"`. Check entered text, placeholders, disabled controls, browser autofill, dropdown options, focus rings, and modal surfaces.
+
+## Authorization: permission and resource scope are separate
+
+A module permission answers what kind of operation an actor may perform. A resource grant answers where they may perform it. Features that operate on deployments, buckets, peers, or another owned resource must enforce both.
+
+Rules:
+
+- Define dedicated read and write permissions for each module. Do not reuse an unrelated permission because the feature shares a page or transport.
+- Enforce permissions and resource scope in the agent API. Router guards and hidden buttons improve the experience but are not security boundaries.
+- Filter collection responses to resources the actor may read. Validate every resource referenced by create, update, delete, bulk, and action requests.
+- A bulk update must preserve records outside the actor's scope. Never let a scoped request replace a global collection.
+- Host-wide, fleet-wide, and all-resource operations require an explicit global permission. An empty resource identifier must not silently mean global access.
+- API keys may narrow their user's grants. Use the intersection of user and key access.
+- The UI must hide mutation controls without write permission and exclude read-only resources from target selectors.
+- Tests must call the HTTP endpoint with two actors whose resource grants differ. Prove that each actor sees only allowed records and cannot change the other actor's records.
## Review checklist (UI changes)
- [ ] New inputs/selects/buttons/cards reuse `src/components/base/` rather than bespoke markup. Flag any hand-rolled control that duplicates a primitive.
- [ ] No hardcoded hex/`white`/`black` in `
diff --git a/src/components/StorageBackupsSettings.vue b/src/components/StorageBackupsSettings.vue
index 8751598..74c8e19 100644
--- a/src/components/StorageBackupsSettings.vue
+++ b/src/components/StorageBackupsSettings.vue
@@ -177,8 +177,8 @@ import { useNotificationsStore } from "@/stores/notifications";
const auth = useAuthStore();
const notifications = useNotificationsStore();
-const canWriteCreds = auth.hasPermission("backups:write");
-const canDeleteCreds = auth.hasPermission("backups:delete");
+const canWriteCreds = auth.hasPermission("storage:write");
+const canDeleteCreds = auth.hasPermission("storage:delete");
const canWriteDests = auth.hasPermission("config:write");
const creds = ref([]);
diff --git a/src/layouts/DashboardLayout.vue b/src/layouts/DashboardLayout.vue
index 54311e5..a3ded1c 100644
--- a/src/layouts/DashboardLayout.vue
+++ b/src/layouts/DashboardLayout.vue
@@ -205,7 +205,7 @@