+
+
+
+ }
+ />
+
{enableHttps && (
"
+// }`,
+ },
+};
+
+export const CippDeployCompliancePolicyDrawer = ({
+ mode,
+ buttonText,
+ requiredPermissions = [],
+ PermissionButton = Button,
+}) => {
+ const config = MODE_CONFIG[mode];
+
+ const [drawerVisible, setDrawerVisible] = useState(false);
+
+ const formControl = useForm({
+ mode: "onChange",
+ defaultValues: {
+ selectedTenants: [],
+ TemplateList: null,
+ PowerShellCommand: "",
+ },
+ });
+
+ const { isValid } = useFormState({ control: formControl.control });
+
+ const templateListVal = useWatch({ control: formControl.control, name: "TemplateList" });
+
+ useEffect(() => {
+ if (templateListVal?.value) {
+ formControl.setValue("PowerShellCommand", JSON.stringify(templateListVal.value));
+ }
+ }, [templateListVal, formControl]);
+
+ const deployPolicy = ApiPostCall({
+ urlFromData: true,
+ relatedQueryKeys: config?.relatedQueryKeys ?? [],
+ });
+
+ useEffect(() => {
+ if (deployPolicy.isSuccess) {
+ formControl.reset({
+ selectedTenants: [],
+ TemplateList: null,
+ PowerShellCommand: "",
+ });
+ }
+ }, [deployPolicy.isSuccess, formControl]);
+
+ if (!config) {
+ return null;
+ }
+
+ const handleSubmit = () => {
+ formControl.trigger();
+ if (!isValid) return;
+ deployPolicy.mutate({
+ url: config.postUrl,
+ data: formControl.getValues(),
+ });
+ };
+
+ const handleCloseDrawer = () => {
+ setDrawerVisible(false);
+ formControl.reset({
+ selectedTenants: [],
+ TemplateList: null,
+ PowerShellCommand: "",
+ });
+ };
+
+ return (
+ <>
+ setDrawerVisible(true)}
+ startIcon={}
+ >
+ {buttonText ?? config.buttonLabel}
+
+
+
+
+
+ }
+ >
+
+
+
+
+
+
+
+
+ option,
+ url: config.listTemplatesUrl,
+ }}
+ placeholder="Select a template or enter PowerShell JSON manually"
+ />
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/src/components/CippComponents/CippIntunePolicyDetails.jsx b/src/components/CippComponents/CippIntunePolicyDetails.jsx
index ca822e61739a..064230da3e18 100644
--- a/src/components/CippComponents/CippIntunePolicyDetails.jsx
+++ b/src/components/CippComponents/CippIntunePolicyDetails.jsx
@@ -4,37 +4,41 @@ import CippJsonView from '../CippFormPages/CippJSONView'
export const CippIntunePolicyDetails = ({ row, tenant }) => {
const isConfigurationPolicy = row?.URLName?.toLowerCase() === 'configurationpolicies'
+ const isAdministrativeTemplate = row?.URLName?.toLowerCase() === 'grouppolicyconfigurations'
+ const isSupportedPolicyType = isConfigurationPolicy || isAdministrativeTemplate
+ const urlName = isAdministrativeTemplate ? 'groupPolicyConfigurations' : 'configurationPolicies'
+ const policyTypeLabel = isAdministrativeTemplate ? 'Administrative Template' : 'Settings Catalog'
const tenantFilter = tenant === 'AllTenants' && row?.Tenant ? row.Tenant : tenant
const policyDetails = ApiGetCall({
url: '/api/ListIntunePolicy',
- queryKey: `ListIntunePolicyDetails-${tenantFilter}-${row?.id}`,
+ queryKey: `ListIntunePolicyDetails-${urlName}-${tenantFilter}-${row?.id}`,
data: {
TenantFilter: tenantFilter,
ID: row?.id,
- URLName: 'configurationPolicies',
+ URLName: urlName,
IncludeSettingDefinitions: true,
},
- waiting: Boolean(isConfigurationPolicy && tenantFilter && row?.id),
+ waiting: Boolean(isSupportedPolicyType && tenantFilter && row?.id),
retry: 1,
refetchOnWindowFocus: false,
toast: false,
})
- if (!isConfigurationPolicy) {
+ if (!isSupportedPolicyType) {
return null
}
const details = Array.isArray(policyDetails.data) ? policyDetails.data[0] : policyDetails.data
- const fallbackDetails = row?.settings ? row : null
- const settingsObject = details?.settings ? details : fallbackDetails
+ const fallbackDetails = row?.settings || row?.definitionValues ? row : null
+ const settingsObject = details?.settings || details?.definitionValues ? details : fallbackDetails
if (policyDetails.isLoading || policyDetails.isFetching) {
return (
- Loading policy settings and Microsoft descriptions...
+ Loading policy details and Microsoft descriptions...
)
@@ -43,7 +47,7 @@ export const CippIntunePolicyDetails = ({ row, tenant }) => {
if (policyDetails.isError && !settingsObject) {
return (
- Could not load live Settings Catalog details for this policy.
+ Could not load live {policyTypeLabel} details for this policy.
)
}
@@ -51,7 +55,7 @@ export const CippIntunePolicyDetails = ({ row, tenant }) => {
if (!settingsObject) {
return (
- This Settings Catalog policy did not return any settings.
+ This {policyTypeLabel} policy did not return any settings.
)
}
diff --git a/src/components/CippFormPages/CippJSONView.jsx b/src/components/CippFormPages/CippJSONView.jsx
index cc7fe72e749e..f5044792b149 100644
--- a/src/components/CippFormPages/CippJSONView.jsx
+++ b/src/components/CippFormPages/CippJSONView.jsx
@@ -24,6 +24,12 @@ import { getCippFormatting } from '../../utils/get-cipp-formatting'
import { CippCodeBlock } from '../CippComponents/CippCodeBlock'
import intuneCollection from '../../data/intuneCollection.json'
import { useGuidResolver } from '../../hooks/use-guid-resolver'
+import { useAdminTemplateDefinitions } from '../../hooks/use-admin-template-definitions'
+import {
+ definitionBindPattern,
+ presentationBindPattern,
+ extractBindGuid,
+} from '../../utils/intune-bind-helpers'
const intuneCollectionMap = new Map(
(intuneCollection || []).filter((item) => item?.id).map((item) => [item.id, item])
@@ -250,7 +256,21 @@ function CippJsonView({
// Use the GUID resolver hook
const { guidMapping, isLoadingGuids, resolveGuids, isGuid } = useGuidResolver()
const resolvedType =
- type || (object?.omaSettings || object?.settings || object?.added ? 'intune' : undefined)
+ type ||
+ (object?.omaSettings || object?.settings || object?.definitionValues || object?.added
+ ? 'intune'
+ : undefined)
+ const adminTemplateTenant =
+ object?.Tenant || object?.tenant || object?.TenantFilter || object?.tenantFilter || null
+ const {
+ definitionsMap: addedDefinitionsMap,
+ isLoadingDefinitions,
+ isDefinitionsError,
+ } = useAdminTemplateDefinitions({
+ added: object?.added,
+ manualTenant: adminTemplateTenant,
+ waiting: resolvedType === 'intune',
+ })
const renderIntuneItems = (data) => {
const items = []
@@ -292,7 +312,7 @@ function CippJsonView({
}
const renderDefinitionTooltip = (definition, optionDefinition) => {
- const description = definition?.helpText || definition?.description
+ const description = definition?.helpText || definition?.description || definition?.explainText
const optionDescription = optionDefinition?.helpText || optionDefinition?.description
const infoUrls = Array.isArray(definition?.infoUrls) ? definition.infoUrls : []
@@ -395,6 +415,185 @@ function CippJsonView({
}
}
+ const getDisplayValue = (value) => {
+ if (value === null || value === undefined || value === '') {
+ return ''
+ }
+
+ if (typeof value === 'boolean') {
+ return value ? 'Yes' : 'No'
+ }
+
+ if (typeof value === 'string' || typeof value === 'number') {
+ return value
+ }
+
+ try {
+ return JSON.stringify(value)
+ } catch {
+ return String(value)
+ }
+ }
+
+ const getAdministrativeTemplatePresentationValue = (presentationValue) => {
+ if (!presentationValue || typeof presentationValue !== 'object') {
+ return 'Not configured'
+ }
+
+ if (Object.prototype.hasOwnProperty.call(presentationValue, 'value')) {
+ const displayValue = getDisplayValue(presentationValue.value)
+ if (displayValue !== '') {
+ return displayValue
+ }
+ }
+
+ if (Array.isArray(presentationValue.values)) {
+ const values = presentationValue.values
+ .map((entry) => {
+ if (entry && typeof entry === 'object') {
+ const entryLabel =
+ entry.name ||
+ entry.key ||
+ entry.displayName ||
+ entry.id ||
+ entry.PresentationDefinitionLabel ||
+ ''
+ const entryValue = getDisplayValue(
+ entry.value ?? entry.text ?? entry.Value ?? entry.StringValue ?? entry
+ )
+
+ if (entryLabel && entryValue !== '') {
+ return `${entryLabel}: ${entryValue}`
+ }
+
+ return entryValue
+ }
+
+ return getDisplayValue(entry)
+ })
+ .filter((entry) => entry !== null && entry !== undefined && entry !== '')
+
+ if (values.length > 0) {
+ return values.join(', ')
+ }
+ }
+
+ return 'Not configured'
+ }
+
+ const getStatusText = (enabled) =>
+ enabled === true ? 'Enabled' : enabled === false ? 'Disabled' : 'Configured'
+
+ const addAdministrativeTemplateValue = (
+ value,
+ index,
+ { definition, definitionId, label, keyPrefix, presentationKeyInfix, resolvePresentationLabel }
+ ) => {
+ if (!value || typeof value !== 'object') {
+ return
+ }
+
+ const categoryPath = definition?.categoryPath
+ const presentationValues = Array.isArray(value.presentationValues)
+ ? value.presentationValues
+ : []
+ const itemKey = value.id || definitionId || index
+
+ items.push(
+
+
+ {getStatusText(value.enabled)}
+
+ {categoryPath && (
+
+ {categoryPath}
+
+ )}
+ {!definition && definitionId && (
+
+ Definition ID: {definitionId}
+
+ )}
+ {presentationValues.map((presentationValue, presentationIndex) => {
+ const presentationLabel = resolvePresentationLabel(
+ definition,
+ presentationValue,
+ presentationIndex
+ )
+ const presentationDisplayValue = getAdministrativeTemplatePresentationValue(
+ presentationValue
+ )
+
+ return (
+
+
+ {presentationLabel}:
+ {' '}
+ {renderSettingValue(presentationDisplayValue)}
+
+ )
+ })}
+
+ }
+ />
+ )
+ }
+
+ const getPresentationTypeLabel = (odataType) => {
+ switch (odataType) {
+ case '#microsoft.graph.groupPolicyPresentationValueBoolean':
+ return 'Boolean value'
+ case '#microsoft.graph.groupPolicyPresentationValueDecimal':
+ case '#microsoft.graph.groupPolicyPresentationValueLongDecimal':
+ return 'Numeric value'
+ case '#microsoft.graph.groupPolicyPresentationValueMultiText':
+ return 'Text list'
+ case '#microsoft.graph.groupPolicyPresentationValueList':
+ return 'List value'
+ case '#microsoft.graph.groupPolicyPresentationValueText':
+ return 'Text value'
+ default:
+ return 'Value'
+ }
+ }
+
+ const getAddedPresentationLabel = (definition, presentationValue) => {
+ const presentationId = extractBindGuid(
+ presentationValue?.['presentation@odata.bind'],
+ presentationBindPattern
+ )
+
+ if (presentationId && Array.isArray(definition?.presentations)) {
+ const resolvedPresentation = definition.presentations.find(
+ (presentation) => String(presentation?.id || '').toLowerCase() === presentationId
+ )
+
+ if (resolvedPresentation) {
+ return (
+ resolvedPresentation.label ||
+ resolvedPresentation.displayName ||
+ resolvedPresentation.id ||
+ getPresentationTypeLabel(presentationValue?.['@odata.type'])
+ )
+ }
+ }
+
+ return getPresentationTypeLabel(presentationValue?.['@odata.type'])
+ }
+
+ const resolveLivePresentationLabel = (_definition, presentationValue, presentationIndex) =>
+ presentationValue?.presentation?.label ||
+ presentationValue?.presentation?.displayName ||
+ presentationValue?.presentation?.id ||
+ `Value ${presentationIndex + 1}`
+
const addSettingInstance = (settingInstance, setting, keyPrefix) => {
if (!settingInstance) {
return
@@ -498,14 +697,82 @@ function CippJsonView({
data.settings.forEach((setting, index) => {
addSettingInstance(setting.settingInstance, setting, `setting-${index}`)
})
- } else if (data.added) {
- items.push(
-
- )
+ } else if (Array.isArray(data.definitionValues)) {
+ if (data.definitionValues.length === 0) {
+ items.push(
+
+ )
+ }
+
+ data.definitionValues.forEach((definitionValue, index) => {
+ const definition = definitionValue?.definition
+ addAdministrativeTemplateValue(definitionValue, index, {
+ definition,
+ definitionId: null,
+ label: definition?.displayName || definition?.id || definitionValue?.id || 'Setting',
+ keyPrefix: 'definitionValue',
+ presentationKeyInfix: 'presentation',
+ resolvePresentationLabel: resolveLivePresentationLabel,
+ })
+ })
+ } else if (Array.isArray(data.added)) {
+ const hasResolvedDefinitions = Object.keys(addedDefinitionsMap).length > 0
+
+ if (isLoadingDefinitions && !hasResolvedDefinitions) {
+ items.push(
+
+
+ Resolving administrative template settings...
+
+ }
+ />
+ )
+ return items
+ }
+
+ if (data.added.length === 0) {
+ items.push(
+
+ )
+ }
+
+ if (isDefinitionsError && !hasResolvedDefinitions) {
+ items.push(
+
+ )
+ }
+
+ data.added.forEach((addedValue, index) => {
+ const definitionId = extractBindGuid(
+ addedValue?.['definition@odata.bind'],
+ definitionBindPattern
+ )
+ const definition = definitionId ? addedDefinitionsMap[definitionId] : null
+ addAdministrativeTemplateValue(addedValue, index, {
+ definition,
+ definitionId,
+ label: definition?.displayName || definitionId || `Setting ${index + 1}`,
+ keyPrefix: 'addedDefinition',
+ presentationKeyInfix: 'added-presentation',
+ resolvePresentationLabel: getAddedPresentationLabel,
+ })
+ })
} else {
Object.entries(data).forEach(([key, value]) => {
// Check if value is a GUID that we've resolved
diff --git a/src/components/CippStandards/CippStandardAccordion.jsx b/src/components/CippStandards/CippStandardAccordion.jsx
index 1a2811d462c3..ee2d86b3f78c 100644
--- a/src/components/CippStandards/CippStandardAccordion.jsx
+++ b/src/components/CippStandards/CippStandardAccordion.jsx
@@ -432,7 +432,10 @@ const CippStandardAccordion = ({
(standard.cat && standard.cat.toLowerCase().includes(searchLower)) ||
(standard.tag &&
Array.isArray(standard.tag) &&
- standard.tag.some((tag) => tag.toLowerCase().includes(searchLower)));
+ standard.tag.some((tag) => tag.toLowerCase().includes(searchLower))) ||
+ (standard.appliesToTest &&
+ Array.isArray(standard.appliesToTest) &&
+ standard.appliesToTest.some((testId) => testId.toLowerCase().includes(searchLower)));
const isConfigured = _.get(configuredState, standardName);
const matchesFilter =
diff --git a/src/components/CippStandards/CippStandardDialog.jsx b/src/components/CippStandards/CippStandardDialog.jsx
index 6ebe6362930c..4761ffcab94f 100644
--- a/src/components/CippStandards/CippStandardDialog.jsx
+++ b/src/components/CippStandards/CippStandardDialog.jsx
@@ -788,7 +788,11 @@ const CippStandardDialog = ({
standard.label.toLowerCase().includes(localSearchQuery.toLowerCase()) ||
standard.helpText.toLowerCase().includes(localSearchQuery.toLowerCase()) ||
(standard.tag &&
- standard.tag.some((tag) => tag.toLowerCase().includes(localSearchQuery.toLowerCase())));
+ standard.tag.some((tag) => tag.toLowerCase().includes(localSearchQuery.toLowerCase()))) ||
+ (standard.appliesToTest &&
+ standard.appliesToTest.some((testId) =>
+ testId.toLowerCase().includes(localSearchQuery.toLowerCase())
+ ));
// Category filter
const matchesCategory =
diff --git a/src/components/CippTable/CIPPTableToptoolbar.js b/src/components/CippTable/CIPPTableToptoolbar.js
index 58d8a180813b..232c752bb2c9 100644
--- a/src/components/CippTable/CIPPTableToptoolbar.js
+++ b/src/components/CippTable/CIPPTableToptoolbar.js
@@ -1239,7 +1239,7 @@ export const CIPPTableToptoolbar = React.memo(
)}
{/* Cold start indicator */}
- {getRequestData?.data?.pages?.[0].Metadata?.ColdStart === true && (
+ {getRequestData?.data?.pages?.[0]?.Metadata?.ColdStart === true && (
diff --git a/src/components/CippTestDetail/CippTestDetailOffCanvas.jsx b/src/components/CippTestDetail/CippTestDetailOffCanvas.jsx
index 64abc9b224e4..990ed7472a08 100644
--- a/src/components/CippTestDetail/CippTestDetailOffCanvas.jsx
+++ b/src/components/CippTestDetail/CippTestDetailOffCanvas.jsx
@@ -49,21 +49,15 @@ const getImpactColor = (impact) => {
}
};
-const checkCIPPStandardAvailable = (testName) => {
- if (!testName) return "No";
- console.log(testName);
- // Check if any standard's tag array contains a reference to this test
- const hasStandard = standardsData.some((standard) => {
- if (!standard.tag || !Array.isArray(standard.tag)) return false;
- // Check if any tag matches the test name or contains it
- return standard.tag.some((tag) => {
- const tagLower = tag.toLowerCase();
- const testLower = testName.toLowerCase();
- return tagLower.includes(testLower) || testLower.includes(tagLower);
- });
- });
-
- return hasStandard ? "Yes" : "No";
+// Find every CIPP standard whose appliesToTest array includes this test's RowKey.
+// appliesToTest stores TestIds (e.g. "CIS_1_1_1", "ZTNA21772", "SMB1001_2_5"); the
+// row's RowKey is the same TestId, so this is an exact lookup.
+const getMatchingStandards = (testName) => {
+ if (!testName) return [];
+ return standardsData.filter(
+ (standard) =>
+ Array.isArray(standard.appliesToTest) && standard.appliesToTest.includes(testName)
+ );
};
// Shared markdown styling for consistent rendering
@@ -141,6 +135,8 @@ export const CippTestDetailOffCanvas = ({ row }) => {
const shouldRenderCustomJson = hasRawCustomData && row.ReturnType === "JSON" && !row.ResultMarkdown;
const shouldRenderCustomMarkdown = hasRawCustomData && !shouldRenderCustomJson && !row.ResultMarkdown;
+ const matchingStandards = getMatchingStandards(row.RowKey);
+
return (
@@ -235,8 +231,8 @@ export const CippTestDetailOffCanvas = ({ row }) => {
0 ? `Yes (${matchingStandards.length})` : "No"}
+ color={matchingStandards.length > 0 ? "success" : "default"}
size="small"
/>
@@ -246,6 +242,30 @@ export const CippTestDetailOffCanvas = ({ row }) => {
+ {matchingStandards.length > 0 && (
+
+
+
+ CIPP Standards that satisfy this test
+
+
+ The following CIPP standards can be deployed to remediate or enforce this test.
+
+
+ {matchingStandards.map((standard) => (
+
+ ))}
+
+
+
+ )}
+
{(row.ResultMarkdown || shouldRenderCustomJson || shouldRenderCustomMarkdown) && (
diff --git a/src/components/CippWizard/CippAddTenantTypeSelection.jsx b/src/components/CippWizard/CippAddTenantTypeSelection.jsx
index f8ba6a384884..520d1b978936 100644
--- a/src/components/CippWizard/CippAddTenantTypeSelection.jsx
+++ b/src/components/CippWizard/CippAddTenantTypeSelection.jsx
@@ -1,68 +1,82 @@
-import { Avatar, Card, CardContent, Stack, SvgIcon, Typography } from "@mui/material";
-import { useState, useEffect } from "react";
-import { CippWizardStepButtons } from "./CippWizardStepButtons";
-import { BuildingOfficeIcon, CloudIcon } from "@heroicons/react/24/outline";
+import { Avatar, Card, CardContent, Stack, SvgIcon, Typography } from '@mui/material'
+import { useState, useEffect } from 'react'
+import { CippWizardStepButtons } from './CippWizardStepButtons'
+import { BuildingOfficeIcon, CloudIcon, LinkIcon } from '@heroicons/react/24/outline'
export const CippAddTenantTypeSelection = (props) => {
- const { onNextStep, formControl, currentStep, onPreviousStep } = props;
+ const { onNextStep, formControl, currentStep, onPreviousStep } = props
- const [selectedOption, setSelectedOption] = useState(null);
+ const [selectedOption, setSelectedOption] = useState(null)
// Register the tenantType field in react-hook-form
- formControl.register("tenantType", {
+ formControl.register('tenantType', {
required: true,
- });
+ })
// Restore selection if already set (when navigating back)
useEffect(() => {
- const currentValue = formControl.getValues("tenantType");
+ const currentValue = formControl.getValues('tenantType')
if (currentValue) {
- setSelectedOption(currentValue);
+ setSelectedOption(currentValue)
}
// Restore the form's selectedOption state if navigating back
- const selectedOptionValue = formControl.getValues("selectedOption");
+ const selectedOptionValue = formControl.getValues('selectedOption')
if (selectedOptionValue) {
- formControl.setValue("selectedOption", selectedOptionValue);
+ formControl.setValue('selectedOption', selectedOptionValue)
}
- }, [formControl]);
+ }, [formControl])
const handleOptionClick = (value) => {
- setSelectedOption(value);
- formControl.setValue("tenantType", value);
+ setSelectedOption(value)
+ formControl.setValue('tenantType', value)
// Clear validation fields from other paths when changing selection
// This ensures going back and choosing a different option doesn't keep old validations
- if (value === "GDAP") {
+ if (value === 'GDAP') {
// Clear Direct tenant fields
- formControl.unregister("DirectTenantAuth");
- } else if (value === "Direct") {
+ formControl.unregister('DirectTenantAuth')
+ } else if (value === 'Direct') {
// Clear GDAP fields
- formControl.unregister("GDAPTemplate");
- formControl.unregister("GDAPInviteAccepted");
- formControl.unregister("GDAPRelationshipId");
- formControl.unregister("GDAPOnboardingComplete");
+ formControl.unregister('GDAPTemplate')
+ formControl.unregister('GDAPInviteAccepted')
+ formControl.unregister('GDAPRelationshipId')
+ formControl.unregister('GDAPOnboardingComplete')
+ } else if (value === 'IndirectReseller') {
+ // Clear other paths
+ formControl.unregister('DirectTenantAuth')
+ formControl.unregister('GDAPTemplate')
+ formControl.unregister('GDAPInviteAccepted')
+ formControl.unregister('GDAPRelationshipId')
+ formControl.unregister('GDAPOnboardingComplete')
}
// Trigger validation only for the tenantType field
- formControl.trigger("tenantType");
- };
+ formControl.trigger('tenantType')
+ }
const options = [
{
- value: "GDAP",
- label: "Add GDAP Tenant",
+ value: 'GDAP',
+ label: 'Add GDAP Tenant',
description:
"Select this option to add a new tenant to your Microsoft Partner center environment. We'll walk you through the steps of setting up GDAP.",
icon: ,
},
{
- value: "Direct",
- label: "Add Direct Tenant",
+ value: 'Direct',
+ label: 'Add Direct Tenant',
description:
- "Select this option if you are not a Microsoft partner, or want to add a tenant outside of the scope of your partner center.",
+ 'Select this option if you are not a Microsoft partner, or want to add a tenant outside of the scope of your partner center.',
icon: ,
},
- ];
+ {
+ value: 'IndirectReseller',
+ label: 'Get Reseller Invite Link',
+ description:
+ 'Generate a reseller relationship invite link to send to a customer. This does not add the tenant to CIPP, but may be used by other vendors to populate their customer list.',
+ icon: ,
+ },
+ ]
return (
@@ -74,7 +88,7 @@ export const CippAddTenantTypeSelection = (props) => {
{options.map((option) => {
- const isSelected = selectedOption === option.value;
+ const isSelected = selectedOption === option.value
return (
{
onClick={() => handleOptionClick(option.value)}
variant="outlined"
sx={{
- cursor: "pointer",
+ cursor: 'pointer',
...(isSelected && {
boxShadow: (theme) => `0px 0px 0px 2px ${theme.palette.primary.main}`,
}),
- "&:hover": {
+ '&:hover': {
...(isSelected ? {} : { boxShadow: 8 }),
},
}}
@@ -96,9 +110,9 @@ export const CippAddTenantTypeSelection = (props) => {
@@ -111,7 +125,7 @@ export const CippAddTenantTypeSelection = (props) => {
- );
+ )
})}
{
formControl={formControl}
/>
- );
-};
+ )
+}
-export default CippAddTenantTypeSelection;
+export default CippAddTenantTypeSelection
diff --git a/src/components/CippWizard/CippIndirectResellerLink.jsx b/src/components/CippWizard/CippIndirectResellerLink.jsx
new file mode 100644
index 000000000000..991e18683f34
--- /dev/null
+++ b/src/components/CippWizard/CippIndirectResellerLink.jsx
@@ -0,0 +1,133 @@
+import { useEffect, useMemo } from 'react'
+import { Alert, Box, Skeleton, Stack, TextField, Typography } from '@mui/material'
+import { ApiGetCall } from '../../api/ApiCall'
+import { CippWizardStepButtons } from './CippWizardStepButtons'
+import { CippCopyToClipBoard } from '../CippComponents/CippCopyToClipboard'
+import CippFormComponent from '../CippComponents/CippFormComponent'
+import { useWatch } from 'react-hook-form'
+
+export const CippIndirectResellerLink = (props) => {
+ const { formControl, currentStep, onPreviousStep, onNextStep } = props
+
+ const linkData = ApiGetCall({
+ url: '/api/ListResellerRelationshipLink',
+ queryKey: 'ListResellerRelationshipLink',
+ })
+
+ const inviteUrl = linkData.data?.inviteUrl ?? null
+ const indirectProviders = linkData.data?.indirectProviders ?? []
+ const inviteUrlError = linkData.data?.inviteUrlError ?? null
+
+ const noneOption = { label: 'None (no indirect provider)', value: null }
+
+ const providerOptions = useMemo(() => {
+ const providers = indirectProviders.map((p) => ({
+ label: `${p.name} — MPN: ${p.mpnId} (${p.location})`,
+ value: p.id,
+ }))
+ return [noneOption, ...providers]
+ }, [indirectProviders])
+
+ useEffect(() => {
+ if (!linkData.isFetching && providerOptions.length > 0) {
+ const current = formControl.getValues('indirectProviderId')
+ if (!current) {
+ formControl.setValue('indirectProviderId', noneOption)
+ }
+ }
+ }, [linkData.isFetching, providerOptions])
+
+ const selectedProvider = useWatch({ control: formControl.control, name: 'indirectProviderId' })
+
+ const finalUrl = useMemo(() => {
+ if (!inviteUrl) return null
+ if (!selectedProvider?.value) return inviteUrl
+ const hashIndex = inviteUrl.indexOf('#')
+ const base = hashIndex !== -1 ? inviteUrl.slice(0, hashIndex) : inviteUrl
+ const hash = hashIndex !== -1 ? inviteUrl.slice(hashIndex) : ''
+ return `${base}&indirectCSPId=${selectedProvider.value}${hash}`
+ }, [inviteUrl, selectedProvider])
+
+ return (
+
+
+
+ Indirect Reseller Relationship Link
+
+
+ Generate an invite link to send to a customer so they can authorize you as their indirect
+ reseller. This does not add the tenant to CIPP — it only provides the
+ Microsoft Admin Portal invitation link.
+
+
+
+ {linkData.isFetching && (
+
+
+
+
+
+
+
+
+ )}
+
+ {linkData.isError && (
+
+ Failed to load relationship link from the Partner Center API. Ensure your CIPP application
+ has the required Partner Center permissions.
+
+ )}
+
+ {inviteUrlError && !linkData.isError && {inviteUrlError}}
+
+ {!linkData.isFetching && !linkData.isError && inviteUrl && (
+ <>
+
+
+
+
+ Invite Link
+
+
+
+
+
+
+ Send this link to your customer. When they follow it, they will be linked to your
+ reseller account in the Microsoft Admin Portal.
+
+
+
+
+ There is no automatic confirmation when the customer accepts this invite. You can verify
+ the relationship in Partner Center once the customer has completed the process.
+
+ >
+ )}
+
+
+
+ )
+}
diff --git a/src/components/CippWizard/OnboardingWizardPage.jsx b/src/components/CippWizard/OnboardingWizardPage.jsx
index c80416dc8622..6b0876ad9a58 100644
--- a/src/components/CippWizard/OnboardingWizardPage.jsx
+++ b/src/components/CippWizard/OnboardingWizardPage.jsx
@@ -10,6 +10,7 @@ import { CippAlertsStep } from './CippAlertsStep.jsx'
import { CippAddTenantTypeSelection } from './CippAddTenantTypeSelection.jsx'
import { CippDirectTenantDeploy } from './CippDirectTenantDeploy.jsx'
import { CippGDAPTenantSetup } from './CippGDAPTenantSetup.jsx'
+import { CippIndirectResellerLink } from './CippIndirectResellerLink.jsx'
import { CippGDAPTenantOnboarding } from './CippGDAPTenantOnboarding.jsx'
import { BuildingOfficeIcon, CloudIcon, CpuChipIcon } from '@heroicons/react/24/outline'
import { useRouter } from 'next/router'
@@ -103,6 +104,12 @@ const OnboardingWizardPage = () => {
showStepWhen: (values) =>
values?.selectedOption === 'AddTenant' && values?.tenantType === 'GDAP',
},
+ {
+ description: 'Reseller Link',
+ component: CippIndirectResellerLink,
+ showStepWhen: (values) =>
+ values?.selectedOption === 'AddTenant' && values?.tenantType === 'IndirectReseller',
+ },
{
description: 'GDAP Onboarding',
component: CippGDAPTenantOnboarding,
diff --git a/src/data/AuditLogTemplates.json b/src/data/AuditLogTemplates.json
index 051f0dc16283..1762fb2eb7bb 100644
--- a/src/data/AuditLogTemplates.json
+++ b/src/data/AuditLogTemplates.json
@@ -420,5 +420,39 @@
}
]
}
+ },
+ {
+ "value": "TAPCreated",
+ "name": "A Temporary Access Pass has been created for a user",
+ "template": {
+ "preset": {
+ "value": "TAPCreated",
+ "label": "A Temporary Access Pass has been created for a user"
+ },
+ "logbook": { "value": "Audit.AzureActiveDirectory", "label": "Azure AD" },
+ "conditions": [
+ {
+ "Property": { "value": "List:Operation", "label": "Operation" },
+ "Operator": { "value": "EQ", "label": "Equals to" },
+ "Input": {
+ "value": "Update user.",
+ "label": "updated user"
+ }
+ },
+ {
+ "Property": { "value": "String", "label": "SecuredAccessPassData" },
+ "Operator": { "value": "ne", "label": "Not Equals to" },
+ "Input": {
+ "value": "[]",
+ "label": "[]"
+ }
+ },
+ {
+ "Property": { "value": "String", "label": "SecuredAccessPassData" },
+ "Operator": { "value": "like", "label": "Like" },
+ "Input": { "value": "*" }
+ }
+ ]
+ }
}
]
diff --git a/src/data/portals.json b/src/data/portals.json
index 3d9cdb73b85a..a4402305faca 100644
--- a/src/data/portals.json
+++ b/src/data/portals.json
@@ -81,14 +81,23 @@
"icon": "ShieldMoon"
},
{
- "label": "Power Platform",
- "name": "Power_Platform_Portal",
+ "label": "Power Platform (Admin)",
+ "name": "Power_Platform_Portal_Admin",
"url": "https://admin.powerplatform.microsoft.com/account/login/customerId",
"variable": "customerId",
"target": "_blank",
"external": true,
"icon": "PrecisionManufacturing"
},
+ {
+ "label": "Power Platform (Maker)",
+ "name": "Power_Platform_Portal_Maker",
+ "url": "https://make.powerapps.com/home?tenant=customerId",
+ "variable": "customerId",
+ "target": "_blank",
+ "external": true,
+ "icon": "PrecisionManufacturing"
+ },
{
"label": "Power BI",
"name": "Power_BI_Portal",
diff --git a/src/data/standards.json b/src/data/standards.json
index 6edccf01a6eb..cc708f747177 100644
--- a/src/data/standards.json
+++ b/src/data/standards.json
@@ -129,9 +129,12 @@
"tag": [
"CIS M365 6.0.1 (3.1.1)",
"mip_search_auditlog",
- "NIST CSF 2.0 (DE.CM-09)",
+ "NIST CSF 2.0 (DE.CM-09)"
+ ],
+ "appliesToTest": [
"CISAMSEXO171",
- "CISAMSEXO173"
+ "CISAMSEXO173",
+ "CIS_3_1_1"
],
"helpText": "Enables the Unified Audit Log for tracking and auditing activities. Also runs Enable-OrganizationCustomization if necessary.",
"executiveText": "Activates comprehensive activity logging across Microsoft 365 services to track user actions, system changes, and security events. This provides essential audit trails for compliance requirements, security investigations, and regulatory reporting.",
@@ -154,6 +157,7 @@
"name": "standards.RestrictThirdPartyStorageServices",
"cat": "Global Standards",
"tag": ["CIS M365 6.0.1 (1.3.7)"],
+ "appliesToTest": ["CIS_1_3_7"],
"helpText": "Restricts third-party storage services in Microsoft 365 on the web by managing the Microsoft 365 on the web service principal. This disables integrations with services like Dropbox, Google Drive, Box, and other third-party storage providers.",
"docsDescription": "Third-party storage can be enabled for users in Microsoft 365, allowing them to store and share documents using services such as Dropbox, alongside OneDrive and team sites. This standard ensures Microsoft 365 on the web third-party storage services are restricted by creating and disabling the Microsoft 365 on the web service principal (appId: c1f33bc0-bdb4-4248-ba9b-096807ddb43e). By using external storage services an organization may increase the risk of data breaches and unauthorized access to confidential information. Additionally, third-party services may not adhere to the same security standards as the organization, making it difficult to maintain data privacy and security. Impact is highly dependent upon current practices - if users do not use other storage providers, then minimal impact is likely. However, if users regularly utilize providers outside of the tenant this will affect their ability to continue to do so.",
"executiveText": "Prevents employees from using external cloud storage services like Dropbox, Google Drive, and Box within Microsoft 365, reducing data security risks and ensuring all company data remains within controlled corporate systems. This helps maintain data governance and prevents potential data leaks to unauthorized platforms.",
@@ -272,6 +276,7 @@
"name": "standards.EnableCustomerLockbox",
"cat": "Global Standards",
"tag": ["CIS M365 6.0.1 (1.3.6)", "CustomerLockBoxEnabled"],
+ "appliesToTest": ["CIS_1_3_6"],
"helpText": "**Requires Entra ID P2.** Enables Customer Lockbox that offers an approval process for Microsoft support to access organization data",
"docsDescription": "**Requires Entra ID P2.** Customer Lockbox ensures that Microsoft can't access your content to do service operations without your explicit approval. Customer Lockbox ensures only authorized requests allow access to your organizations data.",
"executiveText": "Requires explicit organizational approval before Microsoft support staff can access company data for service operations. This provides an additional layer of data protection and ensures the organization maintains control over who can access sensitive business information, even during technical support scenarios.",
@@ -337,10 +342,16 @@
"EIDSCA.ST08",
"EIDSCA.ST09",
"NIST CSF 2.0 (PR.AA-05)",
+ "SMB1001 (2.8)"
+ ],
+ "appliesToTest": [
+ "CIS_5_1_6_2",
"EIDSCAAP07",
+ "EIDSCAAP14",
"EIDSCAST08",
"EIDSCAST09",
- "SMB1001 (2.8)"
+ "SMB1001_2_8",
+ "ZTNA21792"
],
"helpText": "Disables Guest access to enumerate directory objects. This prevents guest users from seeing other users or guests in the directory.",
"docsDescription": "Sets it so guests can view only their own user profile. Permission to view other users isn't allowed. Also restricts guest users from seeing the membership of groups they're in. See exactly what get locked down in the [Microsoft documentation.](https://learn.microsoft.com/en-us/entra/fundamentals/users-default-permissions)",
@@ -356,7 +367,12 @@
{
"name": "standards.DisableBasicAuthSMTP",
"cat": "Global Standards",
- "tag": ["CIS M365 6.0.1 (6.5.4)", "NIST CSF 2.0 (PR.IR-01)", "ZTNA21799", "CISAMSEXO51"],
+ "tag": ["CIS M365 6.0.1 (6.5.4)", "NIST CSF 2.0 (PR.IR-01)"],
+ "appliesToTest": [
+ "CISAMSEXO51",
+ "CIS_6_5_4",
+ "ZTNA21799"
+ ],
"helpText": "Disables SMTP AUTH organization-wide, impacting POP and IMAP clients that rely on SMTP for sending emails. Default for new tenants. For more information, see the [Microsoft documentation](https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/authenticated-client-smtp-submission)",
"docsDescription": "Disables tenant-wide SMTP basic authentication, including for all explicitly enabled users, impacting POP and IMAP clients that rely on SMTP for sending emails. For more information, see the [Microsoft documentation](https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/authenticated-client-smtp-submission).",
"executiveText": "Disables outdated email authentication methods that are vulnerable to security attacks, forcing applications and devices to use modern, more secure authentication protocols. This reduces the risk of email-based security breaches and credential theft.",
@@ -381,7 +397,10 @@
"tag": [
"CIS M365 6.0.1 (1.3.2)",
"spo_idle_session_timeout",
- "NIST CSF 2.0 (PR.AA-03)",
+ "NIST CSF 2.0 (PR.AA-03)"
+ ],
+ "appliesToTest": [
+ "CIS_1_3_2",
"ZTNA21813",
"ZTNA21814",
"ZTNA21815"
@@ -419,9 +438,15 @@
"EIDSCA.AG01",
"EIDSCA.AG02",
"EIDSCA.AG03",
+ "SMB1001 (2.8)"
+ ],
+ "appliesToTest": [
+ "CIS_5_2_3_6",
+ "EIDSCAAG01",
"EIDSCAAG02",
"EIDSCAAG03",
- "SMB1001 (2.8)"
+ "SMB1001_2_8",
+ "ZTNA21841"
],
"helpText": "Configures the report suspicious activity settings and system credential preferences in the authentication methods policy.",
"docsDescription": "Controls the authentication methods policy settings for reporting suspicious activity and system credential preferences. These settings help enhance the security of authentication in your organization.",
@@ -464,7 +489,11 @@
{
"name": "standards.AdminSSPR",
"cat": "Entra (AAD) Standards",
- "tag": ["EIDSCA.AP01", "EIDSCAAP01", "ZTNA21842"],
+ "tag": ["EIDSCA.AP01"],
+ "appliesToTest": [
+ "EIDSCAAP01",
+ "ZTNA21842"
+ ],
"helpText": "Controls whether administrators are allowed to use Self-Service Password Reset through the Microsoft Entra authorization policy.",
"docsDescription": "Configures the allowedToUseSSPR property on the Microsoft Entra authorization policy. Microsoft documents this property as controlling whether administrators of the tenant can use Self-Service Password Reset. Use this standard to explicitly enable or disable administrator SSPR based on your security policy.",
"executiveText": "Controls whether tenant administrators can reset their own passwords through Self-Service Password Reset. Disabling this capability forces privileged accounts through more controlled recovery processes and reduces the risk of self-service recovery being misused on administrative identities.",
@@ -491,7 +520,8 @@
{
"name": "standards.AuthMethodsPolicyMigration",
"cat": "Entra (AAD) Standards",
- "tag": ["EIDSCAAG01"],
+ "tag": [],
+ "appliesToTest": ["EIDSCAAG01"],
"helpText": "Completes the migration of authentication methods policy to the new format",
"docsDescription": "Sets the authentication methods policy migration state to complete. This is required when migrating from legacy authentication policies to the new unified authentication methods policy.",
"executiveText": "Completes the transition from legacy authentication policies to Microsoft's modern unified authentication methods policy, ensuring the organization benefits from the latest security features and management capabilities. This migration enables enhanced security controls and simplified policy management.",
@@ -562,7 +592,14 @@
{
"name": "standards.laps",
"cat": "Entra (AAD) Standards",
- "tag": ["CIS M365 6.0.1 (5.1.4.5)", "ZTNA21953", "ZTNA21955", "ZTNA24560", "SMB1001 (2.2)"],
+ "tag": ["CIS M365 6.0.1 (5.1.4.5)", "SMB1001 (2.2)"],
+ "appliesToTest": [
+ "CIS_5_1_4_5",
+ "SMB1001_2_2",
+ "ZTNA21953",
+ "ZTNA21955",
+ "ZTNA24560"
+ ],
"helpText": "Enables the tenant to use LAPS. You must still create a policy for LAPS to be active on all devices. Use the template standards to deploy this by default.",
"docsDescription": "Enables the LAPS functionality on the tenant. Prerequisite for using Windows LAPS via Azure AD.",
"executiveText": "Enables Local Administrator Password Solution (LAPS) capability, which automatically manages and rotates local administrator passwords on company computers. This significantly improves security by preventing the use of shared or static administrator passwords that could be exploited by attackers.",
@@ -585,7 +622,10 @@
"EIDSCA.AM07",
"EIDSCA.AM09",
"EIDSCA.AM10",
- "NIST CSF 2.0 (PR.AA-03)",
+ "NIST CSF 2.0 (PR.AA-03)"
+ ],
+ "appliesToTest": [
+ "CIS_5_2_3_1",
"EIDSCAAM01",
"EIDSCAAM03",
"EIDSCAAM04",
@@ -608,7 +648,8 @@
{
"name": "standards.allowOTPTokens",
"cat": "Entra (AAD) Standards",
- "tag": ["EIDSCA.AM02", "EIDSCAAM02"],
+ "tag": ["EIDSCA.AM02"],
+ "appliesToTest": ["EIDSCAAM02"],
"helpText": "Allows you to use MS authenticator OTP token generator",
"docsDescription": "Allows you to use Microsoft Authenticator OTP token generator. Useful for using the NPS extension as MFA on VPN clients.",
"executiveText": "Enables one-time password generation through Microsoft Authenticator app, providing an additional secure authentication method for employees. This is particularly useful for secure VPN access and other systems requiring multi-factor authentication.",
@@ -624,6 +665,7 @@
"name": "standards.PWcompanionAppAllowedState",
"cat": "Entra (AAD) Standards",
"tag": ["EIDSCA.AM01"],
+ "appliesToTest": ["EIDSCAAM01"],
"helpText": "Sets the state of Authenticator Lite, Authenticator lite is a companion app for passwordless authentication.",
"docsDescription": "Sets the Authenticator Lite state to enabled. This allows users to use the Authenticator Lite built into the Outlook app instead of the full Authenticator app.",
"executiveText": "Enables a simplified authentication experience by allowing users to authenticate directly through Outlook without requiring a separate authenticator app. This improves user convenience while maintaining security standards for passwordless authentication.",
@@ -659,15 +701,22 @@
"EIDSCA.AF05",
"EIDSCA.AF06",
"NIST CSF 2.0 (PR.AA-03)",
+ "SMB1001 (2.5)",
+ "SMB1001 (2.6)",
+ "SMB1001 (2.9)"
+ ],
+ "appliesToTest": [
"EIDSCAAF01",
"EIDSCAAF02",
"EIDSCAAF03",
"EIDSCAAF04",
"EIDSCAAF05",
"EIDSCAAF06",
- "SMB1001 (2.5)",
- "SMB1001 (2.6)",
- "SMB1001 (2.9)"
+ "SMB1001_2_5",
+ "SMB1001_2_6",
+ "SMB1001_2_9",
+ "ZTNA21838",
+ "ZTNA21839"
],
"helpText": "Enables the FIDO2 authenticationMethod for the tenant",
"docsDescription": "Enables FIDO2 capabilities for the tenant. This allows users to use FIDO2 keys like a Yubikey for authentication.",
@@ -684,6 +733,11 @@
"name": "standards.EnableHardwareOAuth",
"cat": "Entra (AAD) Standards",
"tag": ["SMB1001 (2.5)", "SMB1001 (2.6)", "SMB1001 (2.9)"],
+ "appliesToTest": [
+ "SMB1001_2_5",
+ "SMB1001_2_6",
+ "SMB1001_2_9"
+ ],
"helpText": "Enables the HardwareOath authenticationMethod for the tenant. This allows you to use hardware tokens for generating 6 digit MFA codes.",
"docsDescription": "Enables Hardware OAuth tokens for the tenant. This allows users to use hardware tokens like a Yubikey for authentication.",
"executiveText": "Enables physical hardware tokens that generate secure authentication codes, providing an alternative to smartphone-based authentication. This is particularly valuable for employees who cannot use mobile devices or require the highest security standards for accessing sensitive systems.",
@@ -699,6 +753,10 @@
"name": "standards.allowOAuthTokens",
"cat": "Entra (AAD) Standards",
"tag": ["EIDSCA.AT01", "EIDSCA.AT02"],
+ "appliesToTest": [
+ "EIDSCAAT01",
+ "EIDSCAAT02"
+ ],
"helpText": "Allows you to use any software OAuth token generator",
"docsDescription": "Enables OTP Software OAuth tokens for the tenant. This allows users to use OTP codes generated via software, like a password manager to be used as an authentication method.",
"executiveText": "Allows employees to use third-party authentication apps and password managers to generate secure login codes, providing flexibility in authentication methods while maintaining security standards. This accommodates diverse user preferences and existing security tools.",
@@ -714,6 +772,7 @@
"name": "standards.FormsPhishingProtection",
"cat": "Global Standards",
"tag": ["CIS M365 6.0.1 (1.3.5)", "Security", "PhishingProtection"],
+ "appliesToTest": ["CIS_1_3_5"],
"helpText": "Enables internal phishing protection for Microsoft Forms to help prevent malicious forms from being created and shared within the organization. This feature scans forms created by internal users for potential phishing content and suspicious patterns.",
"docsDescription": "Enables internal phishing protection for Microsoft Forms by setting the isInOrgFormsPhishingScanEnabled property to true. This security feature helps protect organizations from internal phishing attacks through Microsoft Forms by automatically scanning forms created by internal users for potential malicious content, suspicious links, and phishing patterns. When enabled, Forms will analyze form content and block or flag potentially dangerous forms before they can be shared within the organization.",
"executiveText": "Automatically scans Microsoft Forms created by employees for malicious content and phishing attempts, preventing the creation and distribution of harmful forms within the organization. This protects against both internal threats and compromised accounts that might be used to distribute malicious content.",
@@ -728,7 +787,13 @@
{
"name": "standards.TAP",
"cat": "Entra (AAD) Standards",
- "tag": ["ZTNA21845", "ZTNA21846", "EIDSCAAT01", "EIDSCAAT02"],
+ "tag": [],
+ "appliesToTest": [
+ "EIDSCAAT01",
+ "EIDSCAAT02",
+ "ZTNA21845",
+ "ZTNA21846"
+ ],
"helpText": "Enables TAP and sets the default TAP lifetime to 1 hour. This configuration also allows you to select if a TAP is single use or multi-logon.",
"docsDescription": "Enables Temporary Password generation for the tenant.",
"executiveText": "Enables temporary access passwords that IT administrators can generate for employees who are locked out or need emergency access to systems. These time-limited passwords provide a secure way to restore access without compromising long-term security policies.",
@@ -756,6 +821,7 @@
"name": "standards.PasswordExpireDisabled",
"cat": "Entra (AAD) Standards",
"tag": ["CIS M365 6.0.1 (1.3.1)", "PWAgePolicyNew"],
+ "appliesToTest": ["CIS_1_3_1", "ZTNA21811"],
"helpText": "Disables the expiration of passwords for the tenant by setting the password expiration policy to never expire for any user.",
"docsDescription": "Sets passwords to never expire for tenant, recommended to use in conjunction with secure password requirements.",
"executiveText": "Eliminates mandatory password expiration requirements, allowing employees to keep strong passwords indefinitely rather than forcing frequent changes that often lead to weaker passwords. This modern security approach reduces help desk calls and improves overall password security when combined with multi-factor authentication.",
@@ -772,15 +838,19 @@
"cat": "Entra (AAD) Standards",
"tag": [
"CIS M365 6.0.1 (5.2.3.2)",
- "ZTNA21848",
- "ZTNA21849",
- "ZTNA21850",
+ "SMB1001 (2.1)"
+ ],
+ "appliesToTest": [
+ "CIS_5_2_3_2",
"EIDSCAPR01",
"EIDSCAPR02",
"EIDSCAPR03",
"EIDSCAPR05",
"EIDSCAPR06",
- "SMB1001 (2.1)"
+ "SMB1001_2_1",
+ "ZTNA21848",
+ "ZTNA21849",
+ "ZTNA21850"
],
"helpText": "**Requires Entra ID P1.** Updates and enables the Entra ID custom banned password list with the supplied words. Enter words separated by commas or semicolons. Each word must be 4-16 characters long. Maximum 1,000 words allowed.",
"docsDescription": "Updates and enables the Entra ID custom banned password list with the supplied words. This supplements the global banned password list maintained by Microsoft. The custom list is limited to 1,000 key base terms of 4-16 characters each. Entra ID will [block variations and common substitutions](https://learn.microsoft.com/en-us/entra/identity/authentication/tutorial-configure-custom-password-protection#configure-custom-banned-passwords) of these words in user passwords. [How are passwords evaluated?](https://learn.microsoft.com/en-us/entra/identity/authentication/concept-password-ban-bad#score-calculation)",
@@ -804,7 +874,11 @@
{
"name": "standards.ExternalMFATrusted",
"cat": "Entra (AAD) Standards",
- "tag": ["ZTNA21803", "ZTNA21804"],
+ "tag": [],
+ "appliesToTest": [
+ "ZTNA21803",
+ "ZTNA21804"
+ ],
"helpText": "Sets the state of the Cross-tenant access setting to trust external MFA. This allows guest users to use their home tenant MFA to access your tenant.",
"executiveText": "Allows external partners and vendors to use their own organization's multi-factor authentication when accessing company resources, streamlining collaboration while maintaining security standards. This reduces friction for external users while ensuring they still meet authentication requirements.",
"addedComponent": [
@@ -833,10 +907,14 @@
"tag": [
"CIS M365 6.0.1 (5.1.2.3)",
"CISA (MS.AAD.6.1v1)",
- "ZTNA21772",
- "ZTNA21787",
"SMB1001 (2.8)"
],
+ "appliesToTest": [
+ "CIS_5_1_2_3",
+ "SMB1001_2_8",
+ "ZTNA21772",
+ "ZTNA21787"
+ ],
"helpText": "Restricts creation of M365 tenants to the Global Administrator or Tenant Creator roles.",
"docsDescription": "Users by default are allowed to create M365 tenants. This disables that so only admins can create new M365 tenants.",
"executiveText": "Prevents regular employees from creating new Microsoft 365 organizations, ensuring all new tenants are properly managed and controlled by IT administrators. This prevents unauthorized shadow IT environments and maintains centralized governance over Microsoft 365 resources.",
@@ -860,12 +938,17 @@
"EIDSCA.CR03",
"EIDSCA.CR04",
"Essential 8 (1507)",
- "NIST CSF 2.0 (PR.AA-05)",
- "ZTNA21869",
+ "NIST CSF 2.0 (PR.AA-05)"
+ ],
+ "appliesToTest": [
+ "CIS_5_1_5_2",
+ "EIDSCACP04",
"EIDSCACR01",
"EIDSCACR02",
"EIDSCACR03",
- "EIDSCACR04"
+ "EIDSCACR04",
+ "ZTNA21809",
+ "ZTNA21869"
],
"helpText": "Enables App consent admin requests for the tenant via the GA role. Does not overwrite existing reviewer settings",
"docsDescription": "Enables the ability for users to request admin consent for applications. Should be used in conjunction with the \"Require admin consent for applications\" standards",
@@ -887,7 +970,11 @@
{
"name": "standards.NudgeMFA",
"cat": "Entra (AAD) Standards",
- "tag": ["ZTNA21889", "SMB1001 (2.5)"],
+ "tag": ["SMB1001 (2.5)"],
+ "appliesToTest": [
+ "SMB1001_2_5",
+ "ZTNA21889"
+ ],
"helpText": "Sets the state of the registration campaign for the tenant",
"docsDescription": "Sets the state of the registration campaign for the tenant. If enabled nudges users to set up the Microsoft Authenticator during sign-in.",
"executiveText": "Prompts employees to set up multi-factor authentication during login, gradually improving the organization's security posture by encouraging adoption of stronger authentication methods. This helps achieve better security compliance without forcing immediate mandatory changes.",
@@ -924,7 +1011,11 @@
{
"name": "standards.DisableM365GroupUsers",
"cat": "Entra (AAD) Standards",
- "tag": ["CISA (MS.AAD.21.1v1)", "ZTNA21868", "SMB1001 (2.8)"],
+ "tag": ["CISA (MS.AAD.21.1v1)", "SMB1001 (2.8)"],
+ "appliesToTest": [
+ "SMB1001_2_8",
+ "ZTNA21868"
+ ],
"helpText": "Restricts M365 group creation to certain admin roles. This disables the ability to create Teams, SharePoint sites, Planner, etc",
"docsDescription": "Users by default are allowed to create M365 groups. This restricts M365 group creation to certain admin roles. This disables the ability to create Teams, SharePoint sites, Planner, etc",
"executiveText": "Restricts the creation of Microsoft 365 groups, Teams, and SharePoint sites to authorized administrators, preventing uncontrolled proliferation of collaboration spaces. This ensures proper governance, naming conventions, and resource management while maintaining oversight of all collaborative environments.",
@@ -953,9 +1044,13 @@
"EIDSCA.AP10",
"Essential 8 (1175)",
"NIST CSF 2.0 (PR.AA-05)",
- "EIDSCAAP10",
"SMB1001 (2.8)"
],
+ "appliesToTest": [
+ "CIS_5_1_2_2",
+ "EIDSCAAP10",
+ "SMB1001_2_8"
+ ],
"helpText": "Disables the ability for users to create App registrations in the tenant.",
"docsDescription": "Disables the ability for users to create applications in Entra. Done to prevent breached accounts from creating an app to maintain access to the tenant, even after the breached account has been secured.",
"executiveText": "Prevents regular employees from creating application registrations that could be used to maintain unauthorized access to company systems. This security measure ensures that only authorized IT personnel can create applications, reducing the risk of persistent security breaches through malicious applications.",
@@ -970,7 +1065,11 @@
{
"name": "standards.BitLockerKeysForOwnedDevice",
"cat": "Entra (AAD) Standards",
- "tag": ["CIS M365 6.0.1 (5.1.4.6)", "ZTNA21954"],
+ "tag": ["CIS M365 6.0.1 (5.1.4.6)"],
+ "appliesToTest": [
+ "CIS_5_1_4_6",
+ "ZTNA21954"
+ ],
"helpText": "Controls whether standard users can recover BitLocker keys for devices they own.",
"docsDescription": "Updates the Microsoft Entra authorization policy that controls whether standard users can read BitLocker recovery keys for devices they own. Choose to restrict access for tighter security or allow self-service recovery when operational needs require it.",
"executiveText": "Gives administrators centralized control over BitLocker recovery secrets—restrict access to ensure IT-assisted recovery flows, or allow self-service when rapid device unlocks are a priority.",
@@ -1001,9 +1100,13 @@
"CIS M365 6.0.1 (5.1.3.2)",
"CISA (MS.AAD.20.1v1)",
"NIST CSF 2.0 (PR.AA-05)",
- "ZTNA21868",
"SMB1001 (2.8)"
],
+ "appliesToTest": [
+ "CIS_5_1_3_2",
+ "SMB1001_2_8",
+ "ZTNA21868"
+ ],
"helpText": "Completely disables the creation of security groups by users. This also breaks the ability to manage groups themselves, or create Teams",
"executiveText": "Restricts the creation of security groups to IT administrators only, preventing employees from creating unauthorized access groups that could bypass security controls. This ensures proper governance of access permissions and maintains centralized control over who can access what resources.",
"addedComponent": [],
@@ -1032,6 +1135,11 @@
"name": "standards.DisableSelfServiceLicenses",
"cat": "Entra (AAD) Standards",
"tag": ["CIS M365 6.0.1 (1.3.4)", "SMB1001 (2.8)"],
+ "appliesToTest": [
+ "CIS_1_3_4",
+ "EIDSCAAP05",
+ "SMB1001_2_8"
+ ],
"helpText": "**Requires 'Billing Administrator' GDAP role.** This standard disables all self service licenses and enables all exclusions",
"executiveText": "Prevents employees from purchasing Microsoft 365 licenses independently, ensuring all software acquisitions go through proper procurement channels. This maintains budget control, prevents unauthorized spending, and ensures compliance with corporate licensing agreements.",
"addedComponent": [
@@ -1057,7 +1165,11 @@
{
"name": "standards.DisableGuests",
"cat": "Entra (AAD) Standards",
- "tag": ["ZTNA21858", "SMB1001 (2.8)"],
+ "tag": ["SMB1001 (2.8)"],
+ "appliesToTest": [
+ "SMB1001_2_8",
+ "ZTNA21858"
+ ],
"helpText": "Blocks login for guest users that have not logged in for a number of days",
"executiveText": "Automatically disables external guest accounts that haven't been used for a number of days, reducing security risks from dormant accounts while maintaining access for active external collaborators. This helps maintain a clean user directory and reduces potential attack vectors.",
"addedComponent": [
@@ -1086,15 +1198,19 @@
"EIDSCA.AP08",
"EIDSCA.AP09",
"Essential 8 (1175)",
- "NIST CSF 2.0 (PR.AA-05)",
- "ZTNA21772",
- "ZTNA21774",
- "ZTNA21807",
+ "NIST CSF 2.0 (PR.AA-05)"
+ ],
+ "appliesToTest": [
+ "CIS_5_1_5_1",
"EIDSCAAP08",
"EIDSCAAP09",
"EIDSCACP01",
"EIDSCACP03",
- "EIDSCACP04"
+ "EIDSCACP04",
+ "ZTNA21772",
+ "ZTNA21774",
+ "ZTNA21807",
+ "ZTNA21810"
],
"helpText": "Disables users from being able to consent to applications, except for those specified in the field below",
"docsDescription": "Requires users to get administrator consent before sharing data with applications. You can preapprove specific applications.",
@@ -1135,9 +1251,14 @@
"CISA (MS.AAD.18.1v1)",
"EIDSCA.AP04",
"EIDSCA.AP07",
+ "SMB1001 (2.8)"
+ ],
+ "appliesToTest": [
+ "CIS_5_1_6_3",
"EIDSCAAP04",
- "SMB1001 (2.8)",
- "ICS M365 6.0.1 (5.1.6.3)"
+ "EIDSCAAP07",
+ "SMB1001_2_8",
+ "ZTNA21791"
],
"helpText": "This setting controls who can invite guests to your directory to collaborate on resources secured by your company, such as SharePoint sites or Azure resources.",
"executiveText": "Controls who within the organization can invite external partners and vendors to access company resources, ensuring proper oversight of external access while enabling necessary business collaboration. This helps maintain security while supporting partnership and vendor relationships.",
@@ -1210,7 +1331,13 @@
{
"name": "standards.SecurityDefaults",
"cat": "Entra (AAD) Standards",
- "tag": ["CISA (MS.AAD.11.1v1)", "ZTNA21843", "SMB1001 (2.5)", "SMB1001 (2.6)", "SMB1001 (2.9)"],
+ "tag": ["CISA (MS.AAD.11.1v1)", "SMB1001 (2.5)", "SMB1001 (2.6)", "SMB1001 (2.9)"],
+ "appliesToTest": [
+ "SMB1001_2_5",
+ "SMB1001_2_6",
+ "SMB1001_2_9",
+ "ZTNA21843"
+ ],
"helpText": "Enables security defaults for the tenant, for newer tenants this is enabled by default. Do not enable this feature if you use Conditional Access.",
"docsDescription": "Enables SD for the tenant, which disables all forms of basic authentication and enforces users to configure MFA. Users are only prompted for MFA when a logon is considered 'suspect' by Microsoft.",
"executiveText": "Activates Microsoft's baseline security configuration that requires multi-factor authentication and blocks legacy authentication methods. This provides essential security protection for organizations without complex conditional access policies, significantly improving security posture with minimal configuration.",
@@ -1229,11 +1356,18 @@
"CIS M365 6.0.1 (5.2.3.5)",
"EIDSCA.AS04",
"NIST CSF 2.0 (PR.AA-03)",
- "EIDSCAAS04",
"SMB1001 (2.5)",
"SMB1001 (2.6)",
"SMB1001 (2.9)"
],
+ "appliesToTest": [
+ "CIS_5_2_3_5",
+ "EIDSCAAS04",
+ "SMB1001_2_5",
+ "SMB1001_2_5_L4",
+ "SMB1001_2_6",
+ "SMB1001_2_9"
+ ],
"helpText": "This blocks users from using SMS as an MFA method. If a user only has SMS as a MFA method, they will be unable to log in.",
"docsDescription": "Disables SMS as an MFA method for the tenant. If a user only has SMS as a MFA method, they will be unable to sign in.",
"executiveText": "Disables SMS text messages as a multi-factor authentication method due to security vulnerabilities like SIM swapping attacks. This forces users to adopt more secure authentication methods like authenticator apps or hardware tokens, significantly improving account security.",
@@ -1252,11 +1386,18 @@
"CIS M365 6.0.1 (5.2.3.5)",
"EIDSCA.AV01",
"NIST CSF 2.0 (PR.AA-03)",
- "EIDSCAAV01",
"SMB1001 (2.5)",
"SMB1001 (2.6)",
"SMB1001 (2.9)"
],
+ "appliesToTest": [
+ "CIS_5_2_3_5",
+ "EIDSCAAV01",
+ "SMB1001_2_5",
+ "SMB1001_2_5_L4",
+ "SMB1001_2_6",
+ "SMB1001_2_9"
+ ],
"helpText": "This blocks users from using Voice call as an MFA method. If a user only has Voice as a MFA method, they will be unable to log in.",
"docsDescription": "Disables Voice call as an MFA method for the tenant. If a user only has Voice call as a MFA method, they will be unable to sign in.",
"executiveText": "Disables voice call authentication due to security vulnerabilities and social engineering risks. This forces users to adopt more secure authentication methods like authenticator apps, improving overall account security by eliminating phone-based attack vectors.",
@@ -1278,6 +1419,13 @@
"SMB1001 (2.6)",
"SMB1001 (2.9)"
],
+ "appliesToTest": [
+ "CIS_5_2_3_7",
+ "SMB1001_2_5",
+ "SMB1001_2_5_L4",
+ "SMB1001_2_6",
+ "SMB1001_2_9"
+ ],
"helpText": "This blocks users from using email as an MFA method. This disables the email OTP option for guest users, and instead prompts them to create a Microsoft account.",
"executiveText": "Disables email-based authentication codes due to security concerns with email interception and account compromise. This forces users to adopt more secure authentication methods, particularly affecting guest users who must use stronger verification methods.",
"addedComponent": [],
@@ -1328,13 +1476,18 @@
"Essential 8 (1173)",
"Essential 8 (1401)",
"NIST CSF 2.0 (PR.AA-03)",
- "ZTNA21780",
- "ZTNA21782",
- "ZTNA21796",
"SMB1001 (2.5)",
"SMB1001 (2.6)",
"SMB1001 (2.9)"
],
+ "appliesToTest": [
+ "SMB1001_2_5",
+ "SMB1001_2_6",
+ "SMB1001_2_9",
+ "ZTNA21780",
+ "ZTNA21782",
+ "ZTNA21796"
+ ],
"helpText": "Enables per user MFA for all users.",
"executiveText": "Requires all employees to use multi-factor authentication for enhanced account security, significantly reducing the risk of unauthorized access from compromised passwords. This fundamental security measure protects against the majority of account-based attacks and is essential for maintaining strong cybersecurity posture.",
"addedComponent": [],
@@ -1418,12 +1571,14 @@
"impactColour": "warning",
"addedDate": "2026-03-13",
"powershellEquivalent": "Graph API",
- "recommendedBy": []
+ "recommendedBy": [],
+ "appliesToTest": ["ZTNA21773", "ZTNA21896", "ZTNA21992"]
},
{
"name": "standards.OutBoundSpamAlert",
"cat": "Exchange Standards",
"tag": ["CIS M365 6.0.1 (2.1.6)"],
+ "appliesToTest": ["CIS_2_1_6"],
"helpText": "Set the Outbound Spam Alert e-mail address",
"docsDescription": "Sets the e-mail address to which outbound spam alerts are sent.",
"addedComponent": [
@@ -1649,6 +1804,7 @@
"name": "standards.EnableOnlineArchiving",
"cat": "Exchange Standards",
"tag": ["Essential 8 (1511)", "NIST CSF 2.0 (PR.DS-11)", "SMB1001 (3.1)"],
+ "appliesToTest": ["SMB1001_3_1"],
"helpText": "Enables the In-Place Online Archive for all UserMailboxes with a valid license.",
"executiveText": "Automatically enables online email archiving for all licensed employees, providing additional storage for older emails while maintaining easy access. This helps manage mailbox sizes, improves email performance, and supports compliance with data retention requirements.",
"addedComponent": [],
@@ -1670,6 +1826,7 @@
"name": "standards.EnableLitigationHold",
"cat": "Exchange Standards",
"tag": ["SMB1001 (3.1)"],
+ "appliesToTest": ["SMB1001_3_1"],
"helpText": "Enables litigation hold for all UserMailboxes with a valid license.",
"executiveText": "Preserves all email content for legal and compliance purposes by preventing permanent deletion of emails, even when users attempt to delete them. This is essential for organizations subject to legal discovery requirements or regulatory compliance mandates.",
"addedComponent": [
@@ -1698,7 +1855,13 @@
{
"name": "standards.SpoofWarn",
"cat": "Exchange Standards",
- "tag": ["CIS M365 6.0.1 (6.2.3)", "ORCA111", "ORCA240", "CISAMSEXO71"],
+ "tag": ["CIS M365 6.0.1 (6.2.3)"],
+ "appliesToTest": [
+ "CISAMSEXO71",
+ "CIS_6_2_3",
+ "ORCA111",
+ "ORCA240"
+ ],
"helpText": "Adds or removes indicators to e-mail messages received from external senders in Outlook. Works on all Outlook clients/OWA",
"docsDescription": "Adds or removes indicators to e-mail messages received from external senders in Outlook. You can read more about this feature on [Microsoft's Exchange Team Blog.](https://techcommunity.microsoft.com/t5/exchange-team-blog/native-external-sender-callouts-on-email-in-outlook/ba-p/2250098)",
"executiveText": "Displays visual warnings in Outlook when emails come from external senders, helping employees identify potentially suspicious messages and reducing the risk of phishing attacks. This security feature makes it easier for staff to distinguish between internal and external communications.",
@@ -1740,6 +1903,7 @@
"name": "standards.EnableMailTips",
"cat": "Exchange Standards",
"tag": ["CIS M365 6.0.1 (6.5.2)", "exo_mailtipsenabled"],
+ "appliesToTest": ["CIS_6_5_2"],
"helpText": "Enables all MailTips in Outlook. MailTips are the notifications Outlook and Outlook on the web shows when an email you create, meets some requirements",
"executiveText": "Enables helpful notifications in Outlook that warn users about potential email issues, such as sending to large groups, external recipients, or invalid addresses. This reduces email mistakes and improves communication efficiency by providing real-time guidance to employees.",
"addedComponent": [
@@ -1817,6 +1981,10 @@
"name": "standards.RotateDKIM",
"cat": "Exchange Standards",
"tag": ["CIS M365 6.0.1 (2.1.9)", "SMB1001 (2.12)"],
+ "appliesToTest": [
+ "CIS_2_1_9",
+ "SMB1001_2_12"
+ ],
"helpText": "Rotate DKIM keys that are 1024 bit to 2048 bit",
"executiveText": "Upgrades email security by replacing older 1024-bit encryption keys with stronger 2048-bit keys for email authentication. This improves the organization's email security posture and helps prevent email spoofing and tampering, maintaining trust with email recipients.",
"addedComponent": [],
@@ -1869,7 +2037,14 @@
{
"name": "standards.AddDKIM",
"cat": "Exchange Standards",
- "tag": ["CIS M365 6.0.1 (2.1.9)", "ORCA108", "CISAMSEXO31", "SMB1001 (2.12)"],
+ "tag": ["CIS M365 6.0.1 (2.1.9)", "SMB1001 (2.12)"],
+ "appliesToTest": [
+ "CISAMSEXO31",
+ "CIS_2_1_9",
+ "ORCA108",
+ "ORCA108_1",
+ "SMB1001_2_12"
+ ],
"helpText": "Enables DKIM for all domains that currently support it",
"executiveText": "Enables email authentication technology that digitally signs outgoing emails to verify they actually came from your organization. This prevents email spoofing, improves email deliverability, and protects the company's reputation by ensuring recipients can trust emails from your domains.",
"addedComponent": [],
@@ -1891,6 +2066,10 @@
"name": "standards.AddDMARCToMOERA",
"cat": "Global Standards",
"tag": ["CIS M365 6.0.1 (2.1.10)", "Security", "PhishingProtection", "SMB1001 (2.12)"],
+ "appliesToTest": [
+ "CIS_2_1_10",
+ "SMB1001_2_12"
+ ],
"helpText": "** Remediation is not available ** Note: requires 'Domain Name Administrator' GDAP role. This should be enabled even if the MOERA (onmicrosoft.com) domains is not used for sending. Enabling this prevents email spoofing. The default value is 'v=DMARC1; p=reject;' recommended because the domain is only used within M365 and reporting is not needed. Omitting pct tag default to 100%",
"docsDescription": "** Remediation is not available ** Note: requires 'Domain Name Administrator' GDAP role. Adds a DMARC record to MOERA (onmicrosoft.com) domains. This should be enabled even if the MOERA (onmicrosoft.com) domains is not used for sending. Enabling this prevents email spoofing. The default record is 'v=DMARC1; p=reject;' recommended because the domain is only used within M365 and reporting is not needed. Omitting pct tag default to 100%",
"executiveText": "Implements advanced email security for Microsoft's default domain names (onmicrosoft.com) to prevent criminals from impersonating your organization. This blocks fraudulent emails that could damage your company's reputation and protects partners and customers from phishing attacks using your domain names.",
@@ -1926,8 +2105,13 @@
"exo_mailboxaudit",
"Essential 8 (1509)",
"Essential 8 (1683)",
- "NIST CSF 2.0 (DE.CM-09)",
- "CISAMSEXO131"
+ "NIST CSF 2.0 (DE.CM-09)"
+ ],
+ "appliesToTest": [
+ "CISAMSEXO131",
+ "CIS_6_1_1",
+ "CIS_6_1_2",
+ "CIS_6_1_3"
],
"helpText": "Enables Mailbox auditing for all mailboxes and on tenant level. Disables audit bypass on all mailboxes. Unified Audit Log needs to be enabled for this standard to function.",
"docsDescription": "Enables mailbox auditing on tenant level and for all mailboxes. Disables audit bypass on all mailboxes. By default Microsoft does not enable mailbox auditing for Resource Mailboxes, Public Folder Mailboxes and DiscoverySearch Mailboxes. Unified Audit Log needs to be enabled for this standard to function.",
@@ -2130,6 +2314,7 @@
"name": "standards.EXOOutboundSpamLimits",
"cat": "Exchange Standards",
"tag": ["CIS M365 6.0.1 (2.1.15)"],
+ "appliesToTest": ["CIS_2_1_15"],
"helpText": "Configures the outbound spam recipient limits (external per hour, internal per hour, per day) and the action to take when a limit is reached. The 'Set Outbound Spam Alert e-mail' standard is recommended to configure together with this one. ",
"docsDescription": "Configures the Exchange Online outbound spam recipient limits for external per hour, internal per hour, and per day, along with the action to take (e.g., BlockUser, Alert) when these limits are exceeded. This helps prevent abuse and manage email flow. Microsoft's recommendations can be found [here.](https://learn.microsoft.com/en-us/defender-office-365/recommended-settings-for-eop-and-office365#eop-outbound-spam-policy-settings) The 'Set Outbound Spam Alert e-mail' standard is recommended to configure together with this one.",
"executiveText": "Sets limits on how many emails employees can send per hour and per day to prevent spam and protect the organization's email reputation. When limits are exceeded, the system can alert administrators or temporarily block the user, helping detect compromised accounts or prevent abuse.",
@@ -2197,7 +2382,12 @@
{
"name": "standards.DisableExternalCalendarSharing",
"cat": "Exchange Standards",
- "tag": ["CIS M365 6.0.1 (1.3.3)", "exo_individualsharing", "ZTNA21803", "CISAMSEXO62"],
+ "tag": ["CIS M365 6.0.1 (1.3.3)", "exo_individualsharing"],
+ "appliesToTest": [
+ "CISAMSEXO62",
+ "CIS_1_3_3",
+ "ZTNA21803"
+ ],
"helpText": "Disables the ability for users to share their calendar with external users. Only for the default policy, so exclusions can be made if needed.",
"docsDescription": "Disables external calendar sharing for the entire tenant. This is not a widely used feature, and it's therefore unlikely that this will impact users. Only for the default policy, so exclusions can be made if needed by making a new policy and assigning it to users.",
"executiveText": "Prevents employees from sharing their calendars with external parties, protecting sensitive meeting information and internal schedules from unauthorized access. This security measure helps maintain confidentiality of business activities while still allowing internal collaboration.",
@@ -2235,7 +2425,11 @@
{
"name": "standards.DisableAdditionalStorageProviders",
"cat": "Exchange Standards",
- "tag": ["CIS M365 6.0.1 (6.5.3)", "exo_storageproviderrestricted", "ZTNA21817"],
+ "tag": ["CIS M365 6.0.1 (6.5.3)", "exo_storageproviderrestricted"],
+ "appliesToTest": [
+ "CIS_6_5_3",
+ "ZTNA21817"
+ ],
"helpText": "Disables the ability for users to open files in Outlook on the Web, from other providers such as Box, Dropbox, Facebook, Google Drive, OneDrive Personal, etc.",
"docsDescription": "Disables additional storage providers in OWA. This is to prevent users from using personal storage providers like Dropbox, Google Drive, etc. Usually this has little user impact.",
"executiveText": "Prevents employees from accessing personal cloud storage services like Dropbox or Google Drive through Outlook on the web, reducing data security risks and ensuring company information stays within approved corporate systems. This helps maintain data governance and prevents accidental data leaks.",
@@ -2258,6 +2452,7 @@
"name": "standards.AntiSpamSafeList",
"cat": "Defender Standards",
"tag": ["CIS M365 6.0.1 (2.1.13)"],
+ "appliesToTest": ["CIS_2_1_13"],
"helpText": "Sets the anti-spam connection filter policy option 'safe list' in Defender.",
"docsDescription": "Sets [Microsoft's built-in 'safe list'](https://learn.microsoft.com/en-us/powershell/module/exchange/set-hostedconnectionfilterpolicy?view=exchange-ps#-enablesafelist) in the anti-spam connection filter policy, rather than setting a custom safe/block list of IPs.",
"executiveText": "Enables Microsoft's pre-approved list of trusted email servers to improve email delivery from legitimate sources while maintaining spam protection. This reduces false positives where legitimate emails might be blocked while still protecting against spam and malicious emails.",
@@ -2339,6 +2534,7 @@
"name": "standards.Bookings",
"cat": "Exchange Standards",
"tag": ["CIS M365 6.0.1 (1.3.9)"],
+ "appliesToTest": ["CIS_1_3_9"],
"helpText": "Sets the state of Bookings on the tenant. Bookings is a scheduling tool that allows users to book appointments with others both internal and external.",
"docsDescription": "",
"executiveText": "Controls whether employees can use Microsoft Bookings to create online appointment scheduling pages for internal and external clients. This feature can improve customer service and streamline appointment management, but may need to be controlled for security or business process reasons.",
@@ -2372,6 +2568,7 @@
"name": "standards.EXODirectSend",
"cat": "Exchange Standards",
"tag": ["CIS M365 6.0.1 (6.5.5)"],
+ "appliesToTest": ["CIS_6_5_5"],
"helpText": "Sets the state of Direct Send in Exchange Online. Direct Send allows applications to send emails directly to Exchange Online mailboxes as the tenants domains, without requiring authentication.",
"docsDescription": "Controls whether applications can use Direct Send to send emails directly to Exchange Online mailboxes as the tenants domains, without requiring authentication. A detailed explanation from Microsoft can be found [here.](https://learn.microsoft.com/en-us/exchange/mail-flow-best-practices/how-to-set-up-a-multifunction-device-or-application-to-send-email-using-microsoft-365-or-office-365)",
"executiveText": "Controls whether business applications and devices (like printers or scanners) can send emails through the company's email system without authentication. While this enables convenient features like scan-to-email, it may pose security risks and should be carefully managed.",
@@ -2402,7 +2599,10 @@
"CIS M365 6.0.1 (6.3.1)",
"exo_outlookaddins",
"NIST CSF 2.0 (PR.AA-05)",
- "NIST CSF 2.0 (PR.PS-05)",
+ "NIST CSF 2.0 (PR.PS-05)"
+ ],
+ "appliesToTest": [
+ "CIS_6_3_1",
"ZTNA21817"
],
"helpText": "Disables the ability for users to install add-ins in Outlook. This is to prevent users from installing malicious add-ins.",
@@ -2511,6 +2711,7 @@
"name": "standards.UserSubmissions",
"cat": "Exchange Standards",
"tag": ["CIS M365 6.0.1 (8.6.1)"],
+ "appliesToTest": ["CIS_8_6_1"],
"helpText": "Set the state of the spam submission button in Outlook",
"docsDescription": "Set the state of the built-in Report button in Outlook. This gives the users the ability to report emails as spam or phish.",
"executiveText": "Enables employees to easily report suspicious emails directly from Outlook, helping improve the organization's spam and phishing detection systems. This crowdsourced approach to security allows users to contribute to threat detection while providing valuable feedback to enhance email security filters.",
@@ -2555,6 +2756,10 @@
"NIST CSF 2.0 (PR.AA-01)",
"SMB1001 (2.3)"
],
+ "appliesToTest": [
+ "CIS_1_2_2",
+ "SMB1001_2_3"
+ ],
"helpText": "Blocks login for all accounts that are marked as a shared mailbox. This is Microsoft best practice to prevent direct logons to shared mailboxes.",
"docsDescription": "Shared mailboxes can be directly logged into if the password is reset, this presents a security risk as do all shared login credentials. Microsoft's recommendation is to disable the user account for shared mailboxes. It would be a good idea to review the sign-in reports to establish potential impact.",
"executiveText": "Prevents direct login to shared mailbox accounts (like info@company.com), ensuring they can only be accessed through authorized users' accounts. This security measure eliminates the risk of shared passwords and unauthorized access while maintaining proper access control and audit trails.",
@@ -2570,6 +2775,7 @@
"name": "standards.DisableResourceMailbox",
"cat": "Exchange Standards",
"tag": ["NIST CSF 2.0 (PR.AA-01)", "SMB1001 (2.3)"],
+ "appliesToTest": ["SMB1001_2_3"],
"helpText": "Blocks login for all accounts that are marked as a resource mailbox and does not have a license assigned. Accounts that are synced from on-premises AD are excluded, as account state is managed in the on-premises AD.",
"docsDescription": "Resource mailboxes can be directly logged into if the password is reset, this presents a security risk as do all shared login credentials. Microsoft's recommendation is to disable the user account for resource mailboxes. Accounts that are synced from on-premises AD are excluded, as account state is managed in the on-premises AD.",
"executiveText": "Prevents direct login to resource mailbox accounts (like conference rooms or equipment), ensuring they can only be managed through proper administrative channels. This security measure eliminates potential unauthorized access to resource scheduling systems while maintaining proper booking functionality.",
@@ -2598,6 +2804,7 @@
"CISA (MS.EXO.4.1v1)",
"NIST CSF 2.0 (PR.DS-02)"
],
+ "appliesToTest": ["CIS_6_2_1"],
"helpText": "Disables the ability for users to automatically forward e-mails to external recipients.",
"docsDescription": "Disables the ability for users to automatically forward e-mails to external recipients. This is to prevent data exfiltration. Please check if there are any legitimate use cases for this feature before implementing, like forwarding invoices and such.",
"executiveText": "Prevents employees from automatically forwarding company emails to external addresses, protecting against data leaks and unauthorized information sharing. This security measure helps maintain control over sensitive business communications while preventing both accidental and intentional data exfiltration.",
@@ -2620,6 +2827,7 @@
"name": "standards.RetentionPolicyTag",
"cat": "Exchange Standards",
"tag": ["SMB1001 (3.1)"],
+ "appliesToTest": ["SMB1001_3_1"],
"helpText": "Creates a CIPP - Deleted Items retention policy tag that permanently deletes items in the Deleted Items folder after X days.",
"docsDescription": "Creates a CIPP - Deleted Items retention policy tag that permanently deletes items in the Deleted Items folder after X days.",
"executiveText": "Automatically and permanently removes deleted emails after a specified number of days, helping manage storage costs and ensuring compliance with data retention policies. This prevents accumulation of unnecessary deleted items while maintaining a reasonable recovery window for accidentally deleted emails.",
@@ -2750,7 +2958,13 @@
"CIS M365 6.0.1 (2.1.1)",
"mdo_safelinksforemail",
"mdo_safelinksforOfficeApps",
- "NIST CSF 2.0 (DE.CM-09)",
+ "NIST CSF 2.0 (DE.CM-09)"
+ ],
+ "appliesToTest": [
+ "CISAMSEXO151",
+ "CISAMSEXO152",
+ "CISAMSEXO153",
+ "CIS_2_1_1",
"ORCA105",
"ORCA106",
"ORCA107",
@@ -2761,13 +2975,11 @@
"ORCA119",
"ORCA156",
"ORCA179",
+ "ORCA189_2",
"ORCA226",
"ORCA236",
"ORCA237",
- "ORCA238",
- "CISAMSEXO151",
- "CISAMSEXO152",
- "CISAMSEXO153"
+ "ORCA238"
],
"helpText": "This creates a Safe Links policy that automatically scans, tracks, and and enables safe links for Email, Office, and Teams for both external and internal senders",
"addedComponent": [
@@ -2828,7 +3040,13 @@
"mdo_antiphishingpolicies",
"mdo_phishthresholdlevel",
"CIS M365 6.0.1 (2.1.7)",
- "NIST CSF 2.0 (DE.CM-09)",
+ "NIST CSF 2.0 (DE.CM-09)"
+ ],
+ "appliesToTest": [
+ "CISAMSEXO111",
+ "CISAMSEXO112",
+ "CISAMSEXO113",
+ "CIS_2_1_7",
"ORCA104",
"ORCA115",
"ORCA180",
@@ -2848,10 +3066,7 @@
"ORCA244",
"ZTNA21784",
"ZTNA21817",
- "ZTNA21819",
- "CISAMSEXO111",
- "CISAMSEXO112",
- "CISAMSEXO113"
+ "ZTNA21819"
],
"helpText": "This creates a Anti-Phishing policy that automatically enables Mailbox Intelligence and spoofing, optional switches for Mail tips.",
"addedComponent": [
@@ -3022,8 +3237,12 @@
"mdo_safedocuments",
"mdo_commonattachmentsfilter",
"mdo_safeattachmentpolicy",
- "NIST CSF 2.0 (DE.CM-09)",
+ "NIST CSF 2.0 (DE.CM-09)"
+ ],
+ "appliesToTest": [
+ "CIS_2_1_4",
"ORCA158",
+ "ORCA189",
"ORCA227"
],
"helpText": "This creates a Safe Attachment policy",
@@ -3092,6 +3311,7 @@
"name": "standards.AtpPolicyForO365",
"cat": "Defender Standards",
"tag": ["CIS M365 6.0.1 (2.1.5)", "NIST CSF 2.0 (DE.CM-09)"],
+ "appliesToTest": ["CIS_2_1_5", "ORCA225"],
"helpText": "This creates a Atp policy that enables Defender for Office 365 for SharePoint, OneDrive and Microsoft Teams.",
"addedComponent": [
{
@@ -3121,6 +3341,10 @@
"name": "standards.PhishingSimulations",
"cat": "Defender Standards",
"tag": ["SMB1001 (1.11)", "SMB1001 (5.1)"],
+ "appliesToTest": [
+ "SMB1001_1_11",
+ "SMB1001_5_1"
+ ],
"helpText": "This creates a phishing simulation policy that enables phishing simulations for the entire tenant.",
"addedComponent": [
{
@@ -3179,16 +3403,23 @@
"mdo_zapspam",
"mdo_zapphish",
"mdo_zapmalware",
- "NIST CSF 2.0 (DE.CM-09)",
+ "NIST CSF 2.0 (DE.CM-09)"
+ ],
+ "appliesToTest": [
+ "CISAMSEXO101",
+ "CISAMSEXO102",
+ "CISAMSEXO103",
+ "CISAMSEXO95",
+ "CIS_2_1_11",
+ "CIS_2_1_2",
+ "CIS_2_1_3",
+ "ORCA120_malware",
"ORCA121",
"ORCA124",
+ "ORCA205",
"ORCA232",
"ZTNA21817",
- "ZTNA21819",
- "CISAMSEXO95",
- "CISAMSEXO101",
- "CISAMSEXO102",
- "CISAMSEXO103"
+ "ZTNA21819"
],
"helpText": "This creates a Malware filter policy that enables the default File filter and Zero-hour auto purge for malware.",
"addedComponent": [
@@ -3318,12 +3549,22 @@
{
"name": "standards.SpamFilterPolicy",
"cat": "Defender Standards",
- "tag": [
+ "tag": [],
+ "appliesToTest": [
+ "CISAMSEXO141",
+ "CISAMSEXO142",
+ "CISAMSEXO143",
"ORCA100",
"ORCA101",
"ORCA102",
"ORCA103",
"ORCA104",
+ "ORCA109",
+ "ORCA110",
+ "ORCA118_1",
+ "ORCA118_3",
+ "ORCA120_phish",
+ "ORCA120_spam",
"ORCA123",
"ORCA139",
"ORCA140",
@@ -3332,10 +3573,7 @@
"ORCA143",
"ORCA224",
"ORCA231",
- "ORCA241",
- "CISAMSEXO141",
- "CISAMSEXO142",
- "CISAMSEXO143"
+ "ORCA241"
],
"helpText": "This standard creates a Spam filter policy similar to the default strict policy.",
"docsDescription": "This standard creates a Spam filter policy similar to the default strict policy, the following settings are configured to on by default: IncreaseScoreWithNumericIps, IncreaseScoreWithRedirectToOtherPort, MarkAsSpamEmptyMessages, MarkAsSpamJavaScriptInHtml, MarkAsSpamSpfRecordHardFail, MarkAsSpamFromAddressAuthFail, MarkAsSpamNdrBackscatter, MarkAsSpamBulkMail, InlineSafetyTipsEnabled, PhishZapEnabled, SpamZapEnabled",
@@ -3842,6 +4080,7 @@
"name": "standards.IntuneComplianceSettings",
"cat": "Intune Standards",
"tag": ["CIS M365 6.0.1 (4.1)"],
+ "appliesToTest": ["CIS_4_1"],
"helpText": "Sets the mark devices with no compliance policy assigned as compliance/non compliant and Compliance status validity period.",
"executiveText": "Configures how the system treats devices that don't have specific compliance policies and sets how often devices must check in to maintain their compliance status. This ensures proper security oversight of all corporate devices and maintains current compliance information.",
"addedComponent": [
@@ -3913,6 +4152,7 @@
"name": "standards.DefaultPlatformRestrictions",
"cat": "Intune Standards",
"tag": ["CIS M365 6.0.1 (4.2)", "CISA (MS.AAD.19.1v1)"],
+ "appliesToTest": ["CIS_4_2"],
"helpText": "Sets the default platform restrictions for enrolling devices into Intune. Note: Do not block personally owned if platform is blocked.",
"executiveText": "Controls which types of devices (iOS, Android, Windows, macOS) and ownership models (corporate vs. personal) can be enrolled in the company's device management system. This helps maintain security standards while supporting necessary business device types and usage scenarios.",
"addedComponent": [
@@ -4131,7 +4371,13 @@
{
"name": "standards.intuneDeviceReg",
"cat": "Intune Standards",
- "tag": ["CIS M365 6.0.1 (5.1.4.2)", "CISA (MS.AAD.17.1v1)", "ZTNA21801", "ZTNA21802"],
+ "tag": ["CIS M365 6.0.1 (5.1.4.2)", "CISA (MS.AAD.17.1v1)"],
+ "appliesToTest": [
+ "CIS_5_1_4_2",
+ "ZTNA21801",
+ "ZTNA21802",
+ "ZTNA21837"
+ ],
"helpText": "Sets the maximum number of devices that can be registered by a user. A value of 0 disables device registration by users",
"executiveText": "Limits how many devices each employee can register for corporate access, preventing excessive device proliferation while accommodating legitimate business needs. This helps maintain security oversight and prevents potential abuse of device registration privileges.",
"addedComponent": [
@@ -4154,6 +4400,11 @@
"name": "standards.intuneDeviceRegLocalAdmins",
"cat": "Entra (AAD) Standards",
"tag": ["CIS M365 6.0.1 (5.1.4.3)", "CIS M365 6.0.1 (5.1.4.4)", "SMB1001 (2.2)"],
+ "appliesToTest": [
+ "CIS_5_1_4_3",
+ "CIS_5_1_4_4",
+ "SMB1001_2_2"
+ ],
"helpText": "Controls whether users who register Microsoft Entra joined devices are granted local administrator rights on those devices and if Global Administrators are added as local admins.",
"docsDescription": "Configures the Device Registration Policy local administrator behavior for registering users. When enabled, users who register devices are not granted local administrator rights, you can also configure if Global Administrators are added as local admins.",
"executiveText": "Controls whether employees who enroll devices automatically receive local administrator access. Disabling registering-user admin rights follows least-privilege principles and reduces security risk from over-privileged endpoints.",
@@ -4182,6 +4433,10 @@
"name": "standards.intuneRestrictUserDeviceRegistration",
"cat": "Entra (AAD) Standards",
"tag": ["CIS M365 6.0.1 (5.1.4.1)", "SMB1001 (2.8)"],
+ "appliesToTest": [
+ "CIS_5_1_4_1",
+ "SMB1001_2_8"
+ ],
"helpText": "Controls whether users can register devices with Entra.",
"docsDescription": "Configures whether users can register devices with Entra. When disabled, users are unable to register devices with Entra.",
"executiveText": "Controls whether employees can register their devices for corporate access. Disabling user device registration prevents unauthorized or unmanaged devices from connecting to company resources, enhancing overall security posture.",
@@ -4203,7 +4458,12 @@
{
"name": "standards.intuneRequireMFA",
"cat": "Intune Standards",
- "tag": ["ZTNA21782", "ZTNA21796", "ZTNA21872"],
+ "tag": [],
+ "appliesToTest": [
+ "ZTNA21782",
+ "ZTNA21796",
+ "ZTNA21872"
+ ],
"helpText": "Requires MFA for all users to register devices with Intune. This is useful when not using Conditional Access.",
"executiveText": "Requires employees to use multi-factor authentication when registering devices for corporate access, adding an extra security layer to prevent unauthorized device enrollment. This helps ensure only legitimate users can connect their devices to company systems.",
"label": "Require Multi-factor Authentication to register or join devices with Microsoft Entra",
@@ -4217,6 +4477,7 @@
"name": "standards.DeletedUserRentention",
"cat": "SharePoint Standards",
"tag": ["SMB1001 (3.1)"],
+ "appliesToTest": ["SMB1001_3_1"],
"helpText": "Sets the retention period for deleted users OneDrive to the specified period of time. The default is 30 days.",
"docsDescription": "When a OneDrive user gets deleted, the personal SharePoint site is saved for selected amount of time that data can be retrieved from it.",
"executiveText": "Preserves departed employees' OneDrive files for a specified period, allowing time to recover important business documents before permanent deletion. This helps prevent data loss while managing storage costs and maintaining compliance with data retention policies.",
@@ -4328,6 +4589,7 @@
"name": "standards.SPAzureB2B",
"cat": "SharePoint Standards",
"tag": ["CIS M365 6.0.1 (7.2.2)"],
+ "appliesToTest": ["CIS_7_2_2"],
"helpText": "Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled",
"executiveText": "Enables secure collaboration with external partners through SharePoint and OneDrive by integrating with Azure B2B guest access. This allows controlled sharing with external organizations while maintaining security oversight and proper access management.",
"addedComponent": [],
@@ -4352,7 +4614,10 @@
"tag": [
"CIS M365 6.0.1 (7.3.1)",
"CISA (MS.SPO.3.1v1)",
- "NIST CSF 2.0 (DE.CM-09)",
+ "NIST CSF 2.0 (DE.CM-09)"
+ ],
+ "appliesToTest": [
+ "CIS_7_3_1",
"ZTNA21817"
],
"helpText": "Ensure Office 365 SharePoint infected files are disallowed for download",
@@ -4420,7 +4685,13 @@
{
"name": "standards.SPExternalUserExpiration",
"cat": "SharePoint Standards",
- "tag": ["CIS M365 6.0.1 (7.2.9)", "CISA (MS.SPO.1.5v1)", "ZTNA21803", "ZTNA21804", "ZTNA21858"],
+ "tag": ["CIS M365 6.0.1 (7.2.9)", "CISA (MS.SPO.1.5v1)"],
+ "appliesToTest": [
+ "CIS_7_2_9",
+ "ZTNA21803",
+ "ZTNA21804",
+ "ZTNA21858"
+ ],
"helpText": "Ensure guest access to a site or OneDrive will expire automatically",
"executiveText": "Automatically expires external user access to SharePoint sites and OneDrive after a specified period, reducing security risks from forgotten or unnecessary guest accounts. This ensures external access is regularly reviewed and maintained only when actively needed.",
"addedComponent": [
@@ -4453,7 +4724,12 @@
{
"name": "standards.SPEmailAttestation",
"cat": "SharePoint Standards",
- "tag": ["CIS M365 6.0.1 (7.2.10)", "CISA (MS.SPO.1.6v1)", "ZTNA21803", "ZTNA21804"],
+ "tag": ["CIS M365 6.0.1 (7.2.10)", "CISA (MS.SPO.1.6v1)"],
+ "appliesToTest": [
+ "CIS_7_2_10",
+ "ZTNA21803",
+ "ZTNA21804"
+ ],
"helpText": "Ensure re-authentication with verification code is restricted",
"executiveText": "Requires external users to periodically re-verify their identity through email verification codes when accessing SharePoint resources, adding an extra security layer for external collaboration. This helps ensure continued legitimacy of external access over time.",
"addedComponent": [
@@ -4489,7 +4765,11 @@
"tag": [
"CIS M365 6.0.1 (7.2.7)",
"CIS M365 6.0.1 (7.2.11)",
- "CISA (MS.SPO.1.4v1)",
+ "CISA (MS.SPO.1.4v1)"
+ ],
+ "appliesToTest": [
+ "CIS_7_2_11",
+ "CIS_7_2_7",
"ZTNA21803",
"ZTNA21804"
],
@@ -4600,7 +4880,10 @@
"CIS M365 6.0.1 (7.2.1)",
"spo_legacy_auth",
"CISA (MS.AAD.3.1v1)",
- "NIST CSF 2.0 (PR.IR-01)",
+ "NIST CSF 2.0 (PR.IR-01)"
+ ],
+ "appliesToTest": [
+ "CIS_7_2_1",
"ZTNA21776",
"ZTNA21797"
],
@@ -4630,7 +4913,11 @@
"CIS M365 6.0.1 (7.2.3)",
"CIS M365 6.0.1 (7.2.4)",
"CISA (MS.AAD.14.1v1)",
- "CISA (MS.SPO.1.1v1)",
+ "CISA (MS.SPO.1.1v1)"
+ ],
+ "appliesToTest": [
+ "CIS_7_2_3",
+ "CIS_7_2_4",
"ZTNA21803",
"ZTNA21804"
],
@@ -4683,7 +4970,10 @@
"tag": [
"CIS M365 6.0.1 (7.2.5)",
"CISA (MS.AAD.14.2v1)",
- "CISA (MS.SPO.1.2v1)",
+ "CISA (MS.SPO.1.2v1)"
+ ],
+ "appliesToTest": [
+ "CIS_7_2_5",
"ZTNA21803",
"ZTNA21804"
],
@@ -4710,6 +5000,7 @@
"name": "standards.DisableUserSiteCreate",
"cat": "SharePoint Standards",
"tag": ["SMB1001 (2.8)"],
+ "appliesToTest": ["SMB1001_2_8"],
"helpText": "Disables users from creating new SharePoint sites",
"docsDescription": "Disables standard users from creating SharePoint sites, also disables the ability to fully create teams",
"executiveText": "Restricts the creation of new SharePoint sites to authorized administrators, preventing uncontrolled proliferation of collaboration spaces and ensuring proper governance. This maintains organized information architecture while requiring approval for new collaborative environments.",
@@ -4785,7 +5076,10 @@
"tag": [
"CIS M365 6.0.1 (7.3.2)",
"CISA (MS.SPO.2.1v1)",
- "NIST CSF 2.0 (PR.AA-05)",
+ "NIST CSF 2.0 (PR.AA-05)"
+ ],
+ "appliesToTest": [
+ "CIS_7_3_2",
"ZTNA24824"
],
"helpText": "Entra P1 required. Block or limit access to SharePoint and OneDrive content from unmanaged devices (those not hybrid AD joined or compliant in Intune). These controls rely on Microsoft Entra Conditional Access policies and can take up to 24 hours to take effect.",
@@ -4819,7 +5113,10 @@
"tag": [
"CIS M365 6.0.1 (7.2.6)",
"CISA (MS.AAD.14.3v1)",
- "CISA (MS.SPO.1.3v1)",
+ "CISA (MS.SPO.1.3v1)"
+ ],
+ "appliesToTest": [
+ "CIS_7_2_6",
"ZTNA21803",
"ZTNA21804"
],
@@ -4873,6 +5170,17 @@
"CIS M365 6.0.1 (8.5.8)",
"CIS M365 6.0.1 (8.5.9)"
],
+ "appliesToTest": [
+ "CIS_8_5_1",
+ "CIS_8_5_2",
+ "CIS_8_5_3",
+ "CIS_8_5_4",
+ "CIS_8_5_5",
+ "CIS_8_5_6",
+ "CIS_8_5_7",
+ "CIS_8_5_8",
+ "CIS_8_5_9"
+ ],
"helpText": "Defines the CIS recommended global meeting policy for Teams. This includes AllowAnonymousUsersToJoinMeeting, AllowAnonymousUsersToStartMeeting, AutoAdmittedUsers, AllowPSTNUsersToBypassLobby, MeetingChatEnabledType, DesignatedPresenterRoleMode, AllowExternalParticipantGiveRequestControl, AllowParticipantGiveRequestControl",
"executiveText": "Establishes security-focused default settings for Teams meetings, controlling who can join meetings, present content, and participate in chats. These policies balance collaboration needs with security requirements, ensuring meetings remain productive while protecting against unauthorized access and disruption.",
"addedComponent": [
@@ -4995,6 +5303,7 @@
"name": "standards.TeamsExternalChatWithAnyone",
"cat": "Teams Standards",
"tag": ["CIS M365 6.0.1 (8.2.3)"],
+ "appliesToTest": ["CIS_8_2_3"],
"helpText": "Controls whether users can start Teams chats with any email address, inviting external recipients as guests via email.",
"docsDescription": "Manages the Teams messaging policy setting UseB2BInvitesToAddExternalUsers. When enabled, users can start chats with any email address and recipients receive an invitation to join the chat as guests. Disabling the setting prevents these external email chats from being created, keeping conversations limited to internal users and approved guests.",
"executiveText": "Allows organizations to decide if employees can launch Microsoft Teams chats with anyone on the internet using just an email address. Disabling the feature keeps conversations inside trusted boundaries and helps prevent accidental data exposure through unexpected external invitations.",
@@ -5038,6 +5347,7 @@
"powershellEquivalent": "Set-CsTeamsClientConfiguration -AllowEmailIntoChannel $false",
"recommendedBy": ["CIS"],
"tag": ["CIS M365 6.0.1 (8.1.2)"],
+ "appliesToTest": ["CIS_8_1_2"],
"requiredCapabilities": ["MCOSTANDARD", "MCOEV", "MCOIMP", "TEAMS1", "Teams_Room_Standard"]
},
{
@@ -5097,6 +5407,7 @@
"name": "standards.TeamsExternalFileSharing",
"cat": "Teams Standards",
"tag": ["CIS M365 6.0.1 (8.1.1)"],
+ "appliesToTest": ["CIS_8_1_1"],
"helpText": "Ensure external file sharing in Teams is enabled for only approved cloud storage services.",
"executiveText": "Controls which external cloud storage services (like Google Drive, Dropbox, Box) employees can access through Teams, ensuring file sharing occurs only through approved and secure platforms. This helps maintain data governance while supporting necessary business integrations.",
"addedComponent": [
@@ -5167,6 +5478,10 @@
"name": "standards.TeamsExternalAccessPolicy",
"cat": "Teams Standards",
"tag": ["CIS M365 6.0.1 (8.2.1)", "CIS M365 6.0.1 (8.2.2)"],
+ "appliesToTest": [
+ "CIS_8_2_1",
+ "CIS_8_2_2"
+ ],
"helpText": "Sets the properties of the Global external access policy.",
"docsDescription": "Sets the properties of the Global external access policy. External access policies determine whether or not your users can: 1) communicate with users who have Session Initiation Protocol (SIP) accounts with a federated organization; 2) communicate with users who are using custom applications built with Azure Communication Services; 3) access Skype for Business Server over the Internet, without having to log on to your internal network; 4) communicate with users who have SIP accounts with a public instant messaging (IM) provider such as Skype; and, 5) communicate with people who are using Teams with an account that's not managed by an organization.",
"executiveText": "Defines the organization's policy for communicating with external users through Teams, including other organizations, Skype users, and unmanaged accounts. This fundamental setting determines the scope of external collaboration while maintaining security boundaries for business communications.",
@@ -5194,6 +5509,7 @@
"name": "standards.TeamsFederationConfiguration",
"cat": "Teams Standards",
"tag": ["CIS M365 6.0.1 (8.2.1)"],
+ "appliesToTest": ["CIS_8_2_1", "CIS_8_2_4"],
"helpText": "Sets the properties of the Global federation configuration.",
"docsDescription": "Sets the properties of the Global federation configuration. Federation configuration settings determine whether or not your users can communicate with users who have SIP accounts with a federated organization.",
"executiveText": "Configures how the organization federates with external organizations for Teams communication, controlling whether employees can communicate with specific external domains or all external organizations. This setting enables secure inter-organizational collaboration while maintaining control over external communications.",
@@ -5269,6 +5585,7 @@
"name": "standards.TeamsMessagingPolicy",
"cat": "Teams Standards",
"tag": ["CIS M365 6.0.1 (8.6.1)"],
+ "appliesToTest": ["CIS_8_6_1"],
"helpText": "Sets the properties of the Global messaging policy.",
"docsDescription": "Sets the properties of the Global messaging policy. Messaging policies control which chat and channel messaging features are available to users in Teams.",
"executiveText": "Defines what messaging capabilities employees have in Teams, including the ability to edit or delete messages, create custom emojis, and report inappropriate content. These policies help maintain professional communication standards while enabling necessary collaboration features.",
@@ -5422,6 +5739,7 @@
"name": "standards.AutopilotProfile",
"cat": "Device Management Standards",
"tag": ["SMB1001 (2.2)"],
+ "appliesToTest": ["SMB1001_2_2"],
"disabledFeatures": { "report": false, "warn": false, "remediate": false },
"helpText": "Assign the appropriate Autopilot profile to streamline device deployment.",
"docsDescription": "This standard allows the deployment of Autopilot profiles to devices, including settings such as unique name templates, language options, and local admin privileges.",
@@ -5532,6 +5850,39 @@
"SMB1001 (2.2)",
"SMB1001 (4.7)"
],
+ "appliesToTest": [
+ "SMB1001_1_10",
+ "SMB1001_1_12",
+ "SMB1001_1_2",
+ "SMB1001_1_3",
+ "SMB1001_1_4",
+ "SMB1001_1_8",
+ "SMB1001_1_9",
+ "SMB1001_2_2",
+ "SMB1001_4_7",
+ "ZTNA24540",
+ "ZTNA24541",
+ "ZTNA24542",
+ "ZTNA24543",
+ "ZTNA24545",
+ "ZTNA24547",
+ "ZTNA24548",
+ "ZTNA24549",
+ "ZTNA24550",
+ "ZTNA24552",
+ "ZTNA24553",
+ "ZTNA24564",
+ "ZTNA24568",
+ "ZTNA24569",
+ "ZTNA24572",
+ "ZTNA24574",
+ "ZTNA24575",
+ "ZTNA24576",
+ "ZTNA24784",
+ "ZTNA24839",
+ "ZTNA24840",
+ "ZTNA24870"
+ ],
"helpText": "Deploy and manage Intune templates across devices.",
"executiveText": "Deploys standardized device management configurations across all corporate devices, ensuring consistent security policies, application settings, and compliance requirements. This template-based approach streamlines device management while maintaining uniform security standards across the organization.",
"addedComponent": [
@@ -5629,6 +5980,21 @@
"SMB1001 (1.10)",
"SMB1001 (1.12)"
],
+ "appliesToTest": [
+ "SMB1001_1_10",
+ "SMB1001_1_12",
+ "SMB1001_1_2",
+ "SMB1001_1_3",
+ "SMB1001_1_4",
+ "SMB1001_1_8",
+ "SMB1001_1_9",
+ "ZTNA24540",
+ "ZTNA24550",
+ "ZTNA24552",
+ "ZTNA24574",
+ "ZTNA24575",
+ "ZTNA24784"
+ ],
"helpText": "Deploy and maintain Intune reusable settings templates that can be referenced by multiple policies.",
"executiveText": "Creates and keeps reusable Intune settings templates consistent so common firewall and configuration blocks can be reused across many policies.",
"addedComponent": [
@@ -5714,6 +6080,36 @@
"SMB1001 (2.8)",
"SMB1001 (2.9)"
],
+ "appliesToTest": [
+ "CIS_5_2_2_1",
+ "CIS_5_2_2_10",
+ "CIS_5_2_2_11",
+ "CIS_5_2_2_12",
+ "CIS_5_2_2_2",
+ "CIS_5_2_2_3",
+ "CIS_5_2_2_4",
+ "CIS_5_2_2_5",
+ "CIS_5_2_2_6",
+ "CIS_5_2_2_7",
+ "CIS_5_2_2_8",
+ "CIS_5_2_2_9",
+ "SMB1001_2_5",
+ "SMB1001_2_6",
+ "SMB1001_2_8",
+ "SMB1001_2_9",
+ "ZTNA21783",
+ "ZTNA21786",
+ "ZTNA21806",
+ "ZTNA21808",
+ "ZTNA21824",
+ "ZTNA21825",
+ "ZTNA21828",
+ "ZTNA21830",
+ "ZTNA21883",
+ "ZTNA21892",
+ "ZTNA21941",
+ "ZTNA24827"
+ ],
"helpText": "Manage conditional access policies for better security.",
"executiveText": "Deploys standardized conditional access policies that automatically enforce security requirements based on user location, device compliance, and risk factors. These templates ensure consistent security controls across the organization while enabling secure access to business resources.",
"addedComponent": [
@@ -5787,6 +6183,7 @@
"multi": true,
"cat": "Templates",
"tag": ["CIS M365 6.0.1 (5.1.3.1)"],
+ "appliesToTest": ["CIS_5_1_3_1"],
"disabledFeatures": { "report": true, "warn": true, "remediate": false },
"impact": "Medium Impact",
"addedDate": "2023-12-30",
@@ -6613,6 +7010,7 @@
"name": "standards.EnforcePrivateGroups",
"cat": "Entra (AAD) Standards",
"tag": ["CIS M365 6.0.1 (1.2.1)"],
+ "appliesToTest": ["CIS_1_2_1"],
"helpText": "Sets all public Microsoft 365 groups to private automatically. Groups can be excluded by display name keyword.",
"docsDescription": "Ensures only organisation-managed or approved public groups exist by automatically switching public Microsoft 365 (Unified) groups to private visibility. Groups whose display name matches any of the configured exclusion keywords are left unchanged. This aligns with CIS M365 6.0.1 benchmark control 1.2.1.",
"executiveText": "Enforces private visibility on all Microsoft 365 groups to prevent unauthorised external access to group resources such as Teams, SharePoint sites, and Planner boards. Approved public groups can be excluded by name, ensuring governance while retaining flexibility for intentionally public collaboration spaces.",
@@ -6646,6 +7044,7 @@
"name": "standards.EmptyFilterIPAllowList",
"cat": "Defender Standards",
"tag": ["CIS M365 6.0.1 (2.1.12)"],
+ "appliesToTest": ["CIS_2_1_12"],
"helpText": "Ensures the connection filter IP allow list is not used. IPs on this list bypass spam, spoof, and authentication checks.",
"docsDescription": "IPs on the connection filter allow list bypass spam, spoof, and authentication checks. CIS recommends keeping this list empty to ensure all inbound email is properly scanned. This standard checks that the IPAllowList on the Default hosted connection filter policy is empty and can remediate by clearing it.",
"executiveText": "Ensures the Exchange Online connection filter IP allow list is empty, preventing any IP addresses from bypassing spam filtering, spoofing checks, and sender authentication. Keeping this list empty ensures all inbound email undergoes full security scanning, reducing the risk of phishing and malware delivery through trusted-but-compromised sources.",
@@ -6668,6 +7067,7 @@
"name": "standards.TeamsZAP",
"cat": "Defender Standards",
"tag": ["CIS M365 6.0.1 (2.4.4)"],
+ "appliesToTest": ["CIS_2_4_4"],
"helpText": "Ensures Zero-hour auto purge (ZAP) is enabled for Microsoft Teams, automatically removing malicious messages after delivery.",
"docsDescription": "Zero-hour auto purge (ZAP) for Microsoft Teams retroactively detects and neutralises malicious messages that have already been delivered in Teams chats. Enabling ZAP ensures that phishing, malware, and high confidence phishing messages are automatically purged even after initial delivery, aligning with CIS M365 6.0.1 benchmark control 2.4.4.",
"executiveText": "Enables Zero-hour auto purge for Microsoft Teams to automatically detect and remove malicious messages after delivery. This provides an additional layer of protection against phishing and malware that may bypass initial scanning, ensuring threats are neutralised even after they reach users.",
@@ -6690,6 +7090,7 @@
"name": "standards.CollaborationDomainRestriction",
"cat": "Entra (AAD) Standards",
"tag": ["CIS M365 6.0.1 (5.1.6.1)"],
+ "appliesToTest": ["CIS_5_1_6_1"],
"helpText": "Restricts B2B collaboration invitations to a specified list of allowed domains. If no domains are provided, the standard will alert and report on whether any domain restrictions are currently configured.",
"docsDescription": "By default, Microsoft Entra ID allows collaboration invitations to be sent to any external domain. CIS recommends restricting B2B collaboration invitations to only approved domains to reduce the risk of data exfiltration and unauthorized access. This standard checks the B2B management policy for an allow list of domains and can remediate by setting the allowed domains list.",
"executiveText": "Restricts external collaboration invitations to approved domains only, preventing users from sharing data with unapproved external organizations. This reduces the risk of data exfiltration and ensures that collaboration occurs only with trusted business partners.",
diff --git a/src/hooks/use-admin-template-definitions.js b/src/hooks/use-admin-template-definitions.js
new file mode 100644
index 000000000000..8b129daeae27
--- /dev/null
+++ b/src/hooks/use-admin-template-definitions.js
@@ -0,0 +1,82 @@
+// Resolves groupPolicyDefinitions metadata per-tenant. Can't be a static JSON:
+// tenants can import custom ADMX files, so the available definitions are
+// tenant-specific.
+import { useMemo } from 'react'
+import { ApiGetCall } from '../api/ApiCall'
+import { useSettings } from './use-settings'
+import { definitionBindPattern, extractBindGuid } from '../utils/intune-bind-helpers'
+
+export const useAdminTemplateDefinitions = ({ added = [], manualTenant = null, waiting = true } = {}) => {
+ const tenantFilter = useSettings().currentTenant
+ const activeTenant = manualTenant || tenantFilter
+
+ const definitionIds = useMemo(() => {
+ if (!Array.isArray(added)) {
+ return []
+ }
+
+ const ids = new Set()
+ added.forEach((item) => {
+ const definitionId = extractBindGuid(item?.['definition@odata.bind'], definitionBindPattern)
+ if (definitionId) {
+ ids.add(definitionId)
+ }
+ })
+
+ return Array.from(ids).sort()
+ }, [added])
+
+ const canResolveDefinitions =
+ waiting && Boolean(activeTenant) && activeTenant !== 'AllTenants' && definitionIds.length > 0
+
+ const definitionsRequest = ApiGetCall({
+ url: '/api/ListIntunePolicy',
+ queryKey: `AdminTemplateDefinitions-${activeTenant}-${definitionIds.join(',') || 'none'}`,
+ data: {
+ TenantFilter: activeTenant,
+ URLName: 'GroupPolicyDefinitions',
+ DefinitionIds: definitionIds.join(','),
+ },
+ waiting: canResolveDefinitions,
+ retry: 1,
+ refetchOnWindowFocus: false,
+ refetchOnMount: false,
+ toast: false,
+ staleTime: 15 * 60 * 1000,
+ })
+
+ const definitions = useMemo(() => {
+ if (Array.isArray(definitionsRequest.data)) {
+ return definitionsRequest.data
+ }
+
+ if (Array.isArray(definitionsRequest.data?.Results)) {
+ return definitionsRequest.data.Results
+ }
+
+ if (Array.isArray(definitionsRequest.data?.value)) {
+ return definitionsRequest.data.value
+ }
+
+ return []
+ }, [definitionsRequest.data])
+
+ const definitionsMap = useMemo(() => {
+ const mapping = {}
+
+ definitions.forEach((definition) => {
+ if (definition?.id) {
+ mapping[String(definition.id).toLowerCase()] = definition
+ }
+ })
+
+ return mapping
+ }, [definitions])
+
+ return {
+ definitionsMap,
+ isLoadingDefinitions:
+ canResolveDefinitions && (definitionsRequest.isLoading || definitionsRequest.isFetching),
+ isDefinitionsError: canResolveDefinitions && definitionsRequest.isError,
+ }
+}
diff --git a/src/layouts/config.js b/src/layouts/config.js
index ec6a017bf71b..c820f5664acc 100644
--- a/src/layouts/config.js
+++ b/src/layouts/config.js
@@ -301,6 +301,11 @@ export const nativeMenuItems = [
'Security.Alert.*',
'Tenant.DeviceCompliance.*',
'Security.SafeLinksPolicy.*',
+ // TEMP: Purview Compliance menu hidden for dev build
+ // 'Security.DlpCompliancePolicy.*',
+ // 'Security.RetentionCompliancePolicy.*',
+ // 'Security.SensitivityLabel.*',
+ // 'Security.SensitiveInfoType.*',
],
items: [
{
@@ -383,6 +388,62 @@ export const nativeMenuItems = [
},
],
},
+ // TEMP: Purview Compliance menu hidden for dev build
+ // {
+ // title: 'Purview Compliance',
+ // permissions: [
+ // 'Security.DlpCompliancePolicy.*',
+ // 'Security.RetentionCompliancePolicy.*',
+ // 'Security.SensitivityLabel.*',
+ // 'Security.SensitiveInfoType.*',
+ // ],
+ // items: [
+ // {
+ // title: 'DLP Policies',
+ // path: '/security/compliance/dlp',
+ // permissions: ['Security.DlpCompliancePolicy.*'],
+ // },
+ // {
+ // title: 'DLP Policy Templates',
+ // path: '/security/compliance/dlp-templates',
+ // permissions: ['Security.DlpCompliancePolicy.*'],
+ // scope: 'global',
+ // },
+ // {
+ // title: 'Retention Policies',
+ // path: '/security/compliance/retention',
+ // permissions: ['Security.RetentionCompliancePolicy.*'],
+ // },
+ // {
+ // title: 'Retention Policy Templates',
+ // path: '/security/compliance/retention-templates',
+ // permissions: ['Security.RetentionCompliancePolicy.*'],
+ // scope: 'global',
+ // },
+ // {
+ // title: 'Sensitivity Labels',
+ // path: '/security/compliance/labels',
+ // permissions: ['Security.SensitivityLabel.*'],
+ // },
+ // {
+ // title: 'Sensitivity Label Templates',
+ // path: '/security/compliance/labels-templates',
+ // permissions: ['Security.SensitivityLabel.*'],
+ // scope: 'global',
+ // },
+ // {
+ // title: 'Sensitive Information Types',
+ // path: '/security/compliance/sit',
+ // permissions: ['Security.SensitiveInfoType.*'],
+ // },
+ // {
+ // title: 'Sensitive Info Type Templates',
+ // path: '/security/compliance/sit-templates',
+ // permissions: ['Security.SensitiveInfoType.*'],
+ // scope: 'global',
+ // },
+ // ],
+ // },
],
},
{
diff --git a/src/pages/email/tools/message-trace/index.js b/src/pages/email/tools/message-trace/index.js
index 56ccf9bcd20a..d5876859b182 100644
--- a/src/pages/email/tools/message-trace/index.js
+++ b/src/pages/email/tools/message-trace/index.js
@@ -347,6 +347,5 @@ const Page = () => {
);
};
-Page.getLayout = (page) => {page};
-
+Page.getLayout = (page) => {page};
export default Page;
diff --git a/src/pages/endpoint/MEM/compare-policies/index.js b/src/pages/endpoint/MEM/compare-policies/index.js
index da74c739462b..80b660e666a1 100644
--- a/src/pages/endpoint/MEM/compare-policies/index.js
+++ b/src/pages/endpoint/MEM/compare-policies/index.js
@@ -4,7 +4,7 @@ import { ApiPostCall } from "../../../../api/ApiCall";
import { CippFormComponent } from "../../../../components/CippComponents/CippFormComponent";
import { CippFormCondition } from "../../../../components/CippComponents/CippFormCondition";
import { CippFormTenantSelector } from "../../../../components/CippComponents/CippFormTenantSelector";
-import { CippCodeBlock } from "../../../../components/CippComponents/CippCodeBlock";
+import CippJsonView from "../../../../components/CippFormPages/CippJSONView";
import {
Box,
Button,
@@ -19,16 +19,12 @@ import {
TableHead,
TableRow,
Paper,
- Accordion,
- AccordionSummary,
- AccordionDetails,
Alert,
Stack,
Chip,
Skeleton,
} from "@mui/material";
import {
- ExpandMore as ExpandMoreIcon,
CompareArrows as CompareArrowsIcon,
CheckCircle as CheckCircleIcon,
Error as ErrorIcon,
@@ -359,14 +355,10 @@ const Page = () => {
return errData?.Results || compareApi.error?.message || "An error occurred";
}, [compareApi.isError, compareApi.error]);
- const sourceAJson = useMemo(
- () => (results?.sourceAData ? JSON.stringify(results.sourceAData, null, 2) : ""),
- [results?.sourceAData],
- );
- const sourceBJson = useMemo(
- () => (results?.sourceBData ? JSON.stringify(results.sourceBData, null, 2) : ""),
- [results?.sourceBData],
- );
+ const comparisonRows = useMemo(() => {
+ if (!Array.isArray(results?.Results)) return [];
+ return results.Results.filter(Boolean);
+ }, [results?.Results]);
return (
@@ -418,14 +410,14 @@ const Page = () => {
>
{results.identical
? "Policies are identical - no differences found."
- : `${results.Results?.length || 0} difference${results.Results?.length === 1 ? "" : "s"} found between policies.`}
+ : `${comparisonRows.length} difference${comparisonRows.length === 1 ? "" : "s"} found between policies.`}
A: {results.sourceALabel} — B:{" "}
{results.sourceBLabel}
- {!results.identical && results.Results?.length > 0 && (
+ {!results.identical && comparisonRows.length > 0 && (