diff --git a/locales/en-US.yml b/locales/en-US.yml
index 69d6424199..e33999d6d4 100644
--- a/locales/en-US.yml
+++ b/locales/en-US.yml
@@ -922,6 +922,7 @@ recentNHours: "Last {n} hours"
 recentNDays: "Last {n} days"
 noEmailServerWarning: "Email server not configured."
 thereIsUnresolvedAbuseReportWarning: "There are unsolved reports."
+pendingUserApprovals: "There are users awaiting approval."
 recommended: "Recommended"
 check: "Check"
 driveCapOverrideLabel: "Change the drive capacity for this user"
diff --git a/locales/index.d.ts b/locales/index.d.ts
index be6ad77821..93f5e65af0 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -925,6 +925,7 @@ export interface Locale {
     "recentNDays": string;
     "noEmailServerWarning": string;
     "thereIsUnresolvedAbuseReportWarning": string;
+    "pendingUserApprovals": string;
     "recommended": string;
     "check": string;
     "driveCapOverrideLabel": string;
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index e8a9d980be..0d43a5d5a6 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -922,6 +922,7 @@ recentNHours: "直近{n}時間"
 recentNDays: "直近{n}日"
 noEmailServerWarning: "メールサーバーの設定がされていません。"
 thereIsUnresolvedAbuseReportWarning: "未対応の通報があります。"
+pendingUserApprovals: "承認待ちのユーザーがいる。"
 recommended: "推奨"
 check: "チェック"
 driveCapOverrideLabel: "このユーザーのドライブ容量上限を変更"
diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts
index b02b0af234..02fbd50ee4 100644
--- a/packages/backend/src/core/entities/UserEntityService.ts
+++ b/packages/backend/src/core/entities/UserEntityService.ts
@@ -370,6 +370,7 @@ export class UserEntityService implements OnModuleInit {
 			isCat: user.isCat,
 			isSilenced: user.isSilenced || this.roleService.getUserPolicies(user.id).then(r => !r.canPublicNote),
 			speakAsCat: user.speakAsCat ?? falsy,
+			approved: user.approved,
 			instance: user.host ? this.federatedInstanceService.federatedInstanceCache.fetch(user.host).then(instance => instance ? {
 				name: instance.name,
 				softwareName: instance.softwareName,
@@ -489,7 +490,6 @@ export class UserEntityService implements OnModuleInit {
 			...(opts.includeSecrets ? {
 				email: profile!.email,
 				emailVerified: profile!.emailVerified,
-				approved: user.approved,
 				signupReason: user.signupReason,
 				securityKeysList: profile!.twoFactorEnabled
 					? this.userSecurityKeysRepository.find({
diff --git a/packages/frontend/src/components/MkUserCardMini.vue b/packages/frontend/src/components/MkUserCardMini.vue
index 465a109887..70c2a37b53 100644
--- a/packages/frontend/src/components/MkUserCardMini.vue
+++ b/packages/frontend/src/components/MkUserCardMini.vue
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <template>
-<div v-adaptive-bg :class="[$style.root, { yellow: user.isSilenced, red: user.isSuspended, gray: false }]">
+<div v-adaptive-bg :class="[$style.root, { yellow: user.isSilenced, blue: !user.approved, red: user.isSuspended, gray: false }]">
 	<MkAvatar class="avatar" :user="user" indicator/>
 	<div class="body">
 		<span class="name"><MkUserName class="name" :user="user"/></span>
@@ -97,6 +97,12 @@ onMounted(() => {
 		background-size: 16px 16px;
 	}
 
+	&:global(.blue) {
+		--c: rgba(0 153 255 / 15%);
+		background-image: linear-gradient(45deg, var(--c) 16.67%, transparent 16.67%, transparent 50%, var(--c) 50%, var(--c) 66.67%, transparent 66.67%, transparent 100%);
+		background-size: 16px 16px;
+	}
+
 	&:global(.red) {
 		--c: rgb(255 0 0 / 15%);
 		background-image: linear-gradient(45deg, var(--c) 16.67%, transparent 16.67%, transparent 50%, var(--c) 50%, var(--c) 66.67%, transparent 66.67%, transparent 100%);
diff --git a/packages/frontend/src/pages/admin/index.vue b/packages/frontend/src/pages/admin/index.vue
index 768f9fee25..ce608c89ce 100644
--- a/packages/frontend/src/pages/admin/index.vue
+++ b/packages/frontend/src/pages/admin/index.vue
@@ -16,6 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<MkInfo v-if="noMaintainerInformation" warn class="info">{{ i18n.ts.noMaintainerInformationWarning }} <MkA to="/admin/settings" class="_link">{{ i18n.ts.configure }}</MkA></MkInfo>
 				<MkInfo v-if="noBotProtection" warn class="info">{{ i18n.ts.noBotProtectionWarning }} <MkA to="/admin/security" class="_link">{{ i18n.ts.configure }}</MkA></MkInfo>
 				<MkInfo v-if="noEmailServer" warn class="info">{{ i18n.ts.noEmailServerWarning }} <MkA to="/admin/email-settings" class="_link">{{ i18n.ts.configure }}</MkA></MkInfo>
+				<MkInfo v-if="pendingUserApprovals" warn class="info">{{ i18n.ts.pendingUserApprovals }} <MkA to="/admin/users" class="_link">{{ i18n.ts.check }}</MkA></MkInfo>
 
 				<MkSuperMenu :def="menuDef" :grid="narrow"></MkSuperMenu>
 			</div>
@@ -60,6 +61,7 @@ let noMaintainerInformation = isEmpty(instance.maintainerName) || isEmpty(instan
 let noBotProtection = !instance.disableRegistration && !instance.enableHcaptcha && !instance.enableRecaptcha && !instance.enableTurnstile;
 let noEmailServer = !instance.enableEmail;
 let thereIsUnresolvedAbuseReport = $ref(false);
+let pendingUserApprovals = $ref(false);
 let currentPage = $computed(() => router.currentRef.value.child);
 
 os.api('admin/abuse-user-reports', {
@@ -69,6 +71,13 @@ os.api('admin/abuse-user-reports', {
 	if (reports.length > 0) thereIsUnresolvedAbuseReport = true;
 });
 
+os.api('admin/show-users', {
+	state: 'approved',
+	limit: 1,
+}).then(approvals => {
+	if (approvals.length > 0) pendingUserApprovals = true;
+});
+
 const NARROW_THRESHOLD = 600;
 const ro = new ResizeObserver((entries, observer) => {
 	if (entries.length === 0) return;
diff --git a/packages/misskey-js/src/entities.ts b/packages/misskey-js/src/entities.ts
index 4ab57c6409..baf59e7283 100644
--- a/packages/misskey-js/src/entities.ts
+++ b/packages/misskey-js/src/entities.ts
@@ -16,6 +16,7 @@ export type UserLite = {
 	onlineStatus: 'online' | 'active' | 'offline' | 'unknown';
 	avatarUrl: string;
 	avatarBlurhash: string;
+	approved: boolean;
 	emojis: {
 		name: string;
 		url: string;