From 021bd5cdc1a33e56a55c820bb0a8ad47ce7896f6 Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Wed, 29 Jul 2026 10:45:02 +0700 Subject: [PATCH 1/2] allow managed rotation as an option --- .../components/rotate-admin-key.client.tsx | 74 +++++++++++++++++-- 1 file changed, 66 insertions(+), 8 deletions(-) diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/rotate-admin-key.client.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/rotate-admin-key.client.tsx index d0610d0d06e..8b71075d6ec 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/rotate-admin-key.client.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/rotate-admin-key.client.tsx @@ -23,6 +23,7 @@ import { DialogHeader, DialogTitle, } from "@/components/ui/dialog"; +import { Input } from "@/components/ui/input"; import { Spinner } from "@/components/ui/Spinner"; import { useDashboardRouter } from "@/lib/DashboardRouter"; import { cn } from "@/lib/utils"; @@ -38,13 +39,17 @@ export default function RotateAdminKeyButton(props: { const [modalOpen, setModalOpen] = useState(false); const [keysConfirmed, setKeysConfirmed] = useState(false); const [keysDownloaded, setKeysDownloaded] = useState(false); + const [stayManaged, setStayManaged] = useState(props.isManagedVault); + const [secretKeyInput, setSecretKeyInput] = useState(""); const router = useDashboardRouter(); + const willStayManaged = stayManaged && secretKeyInput.trim().length > 0; + const rotateAdminKeyMutation = useMutation({ mutationFn: async () => { - // passing no secret key means we're rotating the admin key and deleting any stored keys const result = await rotateVaultAccountAndAccessToken({ project: props.project, + projectSecretKey: willStayManaged ? secretKeyInput.trim() : undefined, }); return { @@ -105,12 +110,12 @@ export default function RotateAdminKeyButton(props: { variant="outline" > {isLoading && } - {!isLoading && props.isManagedVault ? ( - - ) : ( + {!isLoading && !props.isManagedVault ? ( + ) : ( + )} - {props.isManagedVault ? "Eject From Managed Vault" : "Rotate Admin Key"} + Rotate Admin Key @@ -241,13 +246,66 @@ export default function RotateAdminKeyButton(props: {

Revoke your current keys and generates new ones.

+ + {props.isManagedVault && ( +
+
+ { + setStayManaged(checked === true); + if (checked !== true) { + setSecretKeyInput(""); + } + }} + /> + +
+ + {stayManaged ? ( + <> + + setSecretKeyInput(e.target.value)} + placeholder="Your project secret key" + type="password" + value={secretKeyInput} + /> +

+ Used to re-encrypt your new admin key and wallet + access token so your existing backend keeps working + without changes. It is never stored. +

+ + ) : ( +

+ Your vault will be ejected. You will receive the new + admin key to store yourself, and your backend must be + updated to pass a wallet access token directly. +

+ )} +
+ )} + Important - This action will invalidate your current admin key and all - existing access tokens. You will need to update your - backend to use these new access tokens. + {willStayManaged + ? "This will invalidate your current admin key and all existing access tokens. Your stored credentials will be re-encrypted automatically, so your server wallets keep working." + : "This action will invalidate your current admin key and all existing access tokens. You will need to update your backend to use these new access tokens."} From d2dc514ad9e6cb3b46c52dbc51879d002a1276d4 Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Wed, 29 Jul 2026 11:16:51 +0700 Subject: [PATCH 2/2] rev --- .../vault/components/rotate-admin-key.client.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/rotate-admin-key.client.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/rotate-admin-key.client.tsx index 8b71075d6ec..08ccda9f755 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/rotate-admin-key.client.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/rotate-admin-key.client.tsx @@ -44,6 +44,7 @@ export default function RotateAdminKeyButton(props: { const router = useDashboardRouter(); const willStayManaged = stayManaged && secretKeyInput.trim().length > 0; + const missingSecretKey = stayManaged && secretKeyInput.trim().length === 0; const rotateAdminKeyMutation = useMutation({ mutationFn: async () => { @@ -288,6 +289,12 @@ export default function RotateAdminKeyButton(props: { access token so your existing backend keeps working without changes. It is never stored.

+ {missingSecretKey && ( +

+ Enter your project secret key to keep this vault + managed, or uncheck the box above to eject. +

+ )} ) : (

@@ -319,7 +326,7 @@ export default function RotateAdminKeyButton(props: { Cancel