From f4f951e5aba5bc4f271dfd997360c31b234eeb4f Mon Sep 17 00:00:00 2001 From: karansoni15-create Date: Sun, 30 Aug 2026 13:56:51 +1000 Subject: [PATCH 01/16] test: add CIS 1.1.3 global admin count tests --- .../test_cis_1_1_3_global_admin_count.rego | 158 ++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 engine/tests/test_cis_1_1_3_global_admin_count.rego diff --git a/engine/tests/test_cis_1_1_3_global_admin_count.rego b/engine/tests/test_cis_1_1_3_global_admin_count.rego new file mode 100644 index 000000000..9300ca5d3 --- /dev/null +++ b/engine/tests/test_cis_1_1_3_global_admin_count.rego @@ -0,0 +1,158 @@ +package cis.microsoft_365_foundations.v6_0_0.test_control_1_1_3 + +import rego.v1 + +test_compliant_two_global_admins if { + result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { + "global_admin_count": 2, + "global_admins": [ + "admin1@contoso.com", + "admin2@contoso.com", + ], + } + + result.compliant == true + result.message == "2 global admins configured (within recommended range of 2-4)" + result.details.global_admin_count == 2 + result.details.recommended_min == 2 + result.details.recommended_max == 4 + count(result.affected_resources) == 2 +} + +test_compliant_three_global_admins if { + result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { + "global_admin_count": 3, + "global_admins": [ + "admin1@contoso.com", + "admin2@contoso.com", + "admin3@contoso.com", + ], + } + + result.compliant == true + result.details.global_admin_count == 3 + count(result.affected_resources) == 3 +} + +test_compliant_four_global_admins if { + result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { + "global_admin_count": 4, + "global_admins": [ + "admin1@contoso.com", + "admin2@contoso.com", + "admin3@contoso.com", + "admin4@contoso.com", + ], + } + + result.compliant == true + result.message == "4 global admins configured (within recommended range of 2-4)" + result.details.global_admin_count == 4 + count(result.affected_resources) == 4 +} + +test_non_compliant_zero_global_admins if { + result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { + "global_admin_count": 0, + "global_admins": [], + } + + result.compliant == false + result.message == "Only 0 global admin(s) found. Minimum 2 recommended for continuity." + result.details.global_admin_count == 0 + count(result.affected_resources) == 0 +} + +test_non_compliant_one_global_admin if { + result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { + "global_admin_count": 1, + "global_admins": [ + "admin1@contoso.com", + ], + } + + result.compliant == false + result.message == "Only 1 global admin(s) found. Minimum 2 recommended for continuity." + result.details.global_admin_count == 1 + count(result.affected_resources) == 1 +} + +test_non_compliant_five_global_admins if { + result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { + "global_admin_count": 5, + "global_admins": [ + "admin1@contoso.com", + "admin2@contoso.com", + "admin3@contoso.com", + "admin4@contoso.com", + "admin5@contoso.com", + ], + } + + result.compliant == false + result.message == "5 global admins found. Maximum 4 recommended to minimize attack surface." + result.details.global_admin_count == 5 + count(result.affected_resources) == 5 +} + +test_non_compliant_many_global_admins if { + result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { + "global_admin_count": 10, + "global_admins": [ + "admin1@contoso.com", + "admin2@contoso.com", + "admin3@contoso.com", + "admin4@contoso.com", + "admin5@contoso.com", + "admin6@contoso.com", + "admin7@contoso.com", + "admin8@contoso.com", + "admin9@contoso.com", + "admin10@contoso.com", + ], + } + + result.compliant == false + result.details.global_admin_count == 10 + result.details.recommended_min == 2 + result.details.recommended_max == 4 +} + +test_empty_admin_list_with_valid_count if { + result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { + "global_admin_count": 2, + "global_admins": [], + } + + result.compliant == true + result.details.global_admin_count == 2 + count(result.affected_resources) == 0 +} + +test_missing_global_admins_uses_empty_array if { + result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { + "global_admin_count": 3, + } + + result.compliant == true + result.details.global_admin_count == 3 + count(result.affected_resources) == 0 +} + +test_result_structure if { + result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { + "global_admin_count": 3, + "global_admins": [ + "admin1@contoso.com", + "admin2@contoso.com", + "admin3@contoso.com", + ], + } + + _ = result.compliant + _ = result.message + _ = result.affected_resources + _ = result.details.global_admin_count + _ = result.details.recommended_min + _ = result.details.recommended_max +} From 8e60b7c99e043c8386e5ad24ec714e90e05ae526 Mon Sep 17 00:00:00 2001 From: karansoni15-create Date: Thu, 10 Sep 2026 14:39:09 +1000 Subject: [PATCH 02/16] ci(engine): run Rego regression tests and fail on empty suites --- .github/workflows/ci.engine.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.engine.yml b/.github/workflows/ci.engine.yml index 97e066028..e1b5c11ac 100644 --- a/.github/workflows/ci.engine.yml +++ b/.github/workflows/ci.engine.yml @@ -5,10 +5,13 @@ on: branches: [main] paths: - 'engine/**' + - '.github/workflows/ci.engine.yml' pull_request: branches: [main] paths: - 'engine/**' + - '.github/workflows/ci.engine.yml' + workflow_dispatch: schedule: - cron: '32 23 * * 6' @@ -42,7 +45,6 @@ jobs: with: category: "/language:${{matrix.language}}" - run-lint: name: Linting Code runs-on: ubuntu-latest @@ -91,6 +93,15 @@ jobs: working-directory: engine run: pytest --tb=line tests/test_wiring.py + - name: Run OPA policy regression tests + timeout-minutes: 5 + run: | + docker run --rm \ + --mount "type=bind,source=${GITHUB_WORKSPACE},target=/workspace,readonly" \ + openpolicyagent/opa:1.13.1-debug \ + test /workspace/engine/policies /workspace/engine/tests \ + --fail-on-empty -v + report: name: Report PR status needs: [analyze, run-lint, test] @@ -135,4 +146,4 @@ jobs: - uses: ./.github/actions/pr-status-comment with: marker: '' - body: ${{ steps.build.outputs.body }} + body: ${{ steps.build.outputs.body }} \ No newline at end of file From 781cb22ba655ef26bf970ee6975f433a5102aa1d Mon Sep 17 00:00:00 2001 From: karansoni15-create Date: Wed, 23 Sep 2026 19:38:11 +1000 Subject: [PATCH 03/16] chore: remove unrelated engine workflow changes --- .github/workflows/ci.engine.yml | 86 +++++++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci.engine.yml b/.github/workflows/ci.engine.yml index e1b5c11ac..1f31c6e50 100644 --- a/.github/workflows/ci.engine.yml +++ b/.github/workflows/ci.engine.yml @@ -4,16 +4,13 @@ on: push: branches: [main] paths: - - 'engine/**' - - '.github/workflows/ci.engine.yml' + - "engine/**" pull_request: branches: [main] paths: - - 'engine/**' - - '.github/workflows/ci.engine.yml' - workflow_dispatch: + - "engine/**" schedule: - - cron: '32 23 * * 6' + - cron: "32 23 * * 6" permissions: contents: read @@ -30,7 +27,7 @@ jobs: strategy: fail-fast: false matrix: - language: ['python'] + language: ["python"] steps: - name: Checkout repository uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 @@ -58,11 +55,16 @@ jobs: fetch-depth: 0 - name: Lint Code Base - uses: github/super-linter@454ba4482ce2cd0c505bc592e83c06e1e37ade61 # v4 + uses: super-linter/super-linter@b92721f792f381cedc002ecdbb9847a15ece5bb8 # v7.1.0 env: VALIDATE_ALL_CODEBASE: false DEFAULT_BRANCH: "main" GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # .secrets.baseline / .gitleaks-baseline.json are machine-generated security + # baselines whose hash-like fields (hashed_secret / Commit / Fingerprint) trip + # the OTHER tool's generic-secret heuristics; they're already gated by their + # own dedicated jobs (ci.detect-secrets.yml, ci.gitleaks.yml). + FILTER_REGEX_EXCLUDE: .*\.secrets\.baseline|.*gitleaks-baseline\.json VALIDATE_YAML: false VALIDATE_GITHUB_ACTIONS: false VALIDATE_PYTHON_BLACK: false @@ -72,6 +74,23 @@ jobs: VALIDATE_MARKDOWN: false VALIDATE_NATURAL_LANGUAGE: false VALIDATE_MARKDOWN_PRETTIER: false + # Matches ci.backend-api.yml: JSCPD and TS_STANDARD are not enforced + # in this repo. Without these, super-linter's PR-diff mode (VALIDATE_ALL_CODEBASE: + # false) also re-lints frontend/ files changed earlier in the same PR whenever + # this engine/**-triggered workflow runs, even though this job only exists to + # gate engine/ changes. + VALIDATE_JSCPD: false + VALIDATE_TYPESCRIPT_STANDARD: false + VALIDATE_PYTHON_RUFF: false + # mypy isn't a project dependency and there's no mypy config + # anywhere in this repo, so super-linter's mypy step has no + # installed stubs for fastapi/sqlalchemy/pydantic/etc and fails + # on import-not-found for every Python file touched, regardless + # of real type correctness. + VALIDATE_PYTHON_MYPY: false + VALIDATE_PYTHON_PYINK: false + VALIDATE_CHECKOV: false + VALIDATE_YAML_PRETTIER: false test: name: Run Engine Tests @@ -83,7 +102,7 @@ jobs: - name: Set up Python uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: - python-version: '3.12' + python-version: "3.12" - name: Install dependencies working-directory: engine @@ -93,18 +112,45 @@ jobs: working-directory: engine run: pytest --tb=line tests/test_wiring.py - - name: Run OPA policy regression tests - timeout-minutes: 5 + compliance-verification: + name: Compliance Engine Verification + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.12" + + - name: Install engine dependencies + working-directory: engine + run: pip install -e ".[dev]" + + - name: Install OPA CLI + run: | + curl -fsSL -o /tmp/opa \ + https://openpolicyagent.org/downloads/v1.13.1/opa_linux_amd64_static + chmod +x /tmp/opa + sudo mv /tmp/opa /usr/local/bin/opa + opa version + + - name: Run verification framework unit tests + working-directory: engine run: | - docker run --rm \ - --mount "type=bind,source=${GITHUB_WORKSPACE},target=/workspace,readonly" \ - openpolicyagent/opa:1.13.1-debug \ - test /workspace/engine/policies /workspace/engine/tests \ - --fail-on-empty -v + pytest --tb=line \ + tests/test_compliance_validator.py \ + tests/test_compliance_coverage.py + + - name: Run compliance engine verification + working-directory: engine + run: python -m scripts.validate_engine report: name: Report PR status - needs: [analyze, run-lint, test] + needs: [analyze, run-lint, test, compliance-verification] if: always() && github.event_name == 'pull_request' runs-on: ubuntu-latest permissions: @@ -121,9 +167,10 @@ jobs: const analyze = '${{ needs.analyze.result }}'; const lint = '${{ needs.run-lint.result }}'; const test = '${{ needs.test.result }}'; + const verify = '${{ needs.compliance-verification.result }}'; const icon = r => ({ success: '✅', failure: '❌', cancelled: '🚫', skipped: '⏭️' }[r] ?? '❓'); - const allPassed = [analyze, lint, test].every(r => ['success', 'skipped'].includes(r)); + const allPassed = [analyze, lint, test, verify].every(r => ['success', 'skipped'].includes(r)); const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; const body = [ @@ -135,6 +182,7 @@ jobs: `| Security analysis (CodeQL) | ${icon(analyze)} \`${analyze}\` |`, `| Lint | ${icon(lint)} \`${lint}\` |`, `| Tests | ${icon(test)} \`${test}\` |`, + `| Compliance verification | ${icon(verify)} \`${verify}\` |`, ``, allPassed ? `All checks passed.` @@ -146,4 +194,4 @@ jobs: - uses: ./.github/actions/pr-status-comment with: marker: '' - body: ${{ steps.build.outputs.body }} \ No newline at end of file + body: ${{ steps.build.outputs.body }} From 8b3290ecab01f75933dd52fdeb8764a9c0d2ffd7 Mon Sep 17 00:00:00 2001 From: karansoni15-create Date: Wed, 23 Sep 2026 19:39:56 +1000 Subject: [PATCH 04/16] test: move CIS 1.1.3 coverage to CI behavioural fixtures --- .../test_cis_1_1_3_global_admin_count.rego | 158 ------------------ 1 file changed, 158 deletions(-) delete mode 100644 engine/tests/test_cis_1_1_3_global_admin_count.rego diff --git a/engine/tests/test_cis_1_1_3_global_admin_count.rego b/engine/tests/test_cis_1_1_3_global_admin_count.rego deleted file mode 100644 index 9300ca5d3..000000000 --- a/engine/tests/test_cis_1_1_3_global_admin_count.rego +++ /dev/null @@ -1,158 +0,0 @@ -package cis.microsoft_365_foundations.v6_0_0.test_control_1_1_3 - -import rego.v1 - -test_compliant_two_global_admins if { - result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { - "global_admin_count": 2, - "global_admins": [ - "admin1@contoso.com", - "admin2@contoso.com", - ], - } - - result.compliant == true - result.message == "2 global admins configured (within recommended range of 2-4)" - result.details.global_admin_count == 2 - result.details.recommended_min == 2 - result.details.recommended_max == 4 - count(result.affected_resources) == 2 -} - -test_compliant_three_global_admins if { - result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { - "global_admin_count": 3, - "global_admins": [ - "admin1@contoso.com", - "admin2@contoso.com", - "admin3@contoso.com", - ], - } - - result.compliant == true - result.details.global_admin_count == 3 - count(result.affected_resources) == 3 -} - -test_compliant_four_global_admins if { - result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { - "global_admin_count": 4, - "global_admins": [ - "admin1@contoso.com", - "admin2@contoso.com", - "admin3@contoso.com", - "admin4@contoso.com", - ], - } - - result.compliant == true - result.message == "4 global admins configured (within recommended range of 2-4)" - result.details.global_admin_count == 4 - count(result.affected_resources) == 4 -} - -test_non_compliant_zero_global_admins if { - result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { - "global_admin_count": 0, - "global_admins": [], - } - - result.compliant == false - result.message == "Only 0 global admin(s) found. Minimum 2 recommended for continuity." - result.details.global_admin_count == 0 - count(result.affected_resources) == 0 -} - -test_non_compliant_one_global_admin if { - result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { - "global_admin_count": 1, - "global_admins": [ - "admin1@contoso.com", - ], - } - - result.compliant == false - result.message == "Only 1 global admin(s) found. Minimum 2 recommended for continuity." - result.details.global_admin_count == 1 - count(result.affected_resources) == 1 -} - -test_non_compliant_five_global_admins if { - result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { - "global_admin_count": 5, - "global_admins": [ - "admin1@contoso.com", - "admin2@contoso.com", - "admin3@contoso.com", - "admin4@contoso.com", - "admin5@contoso.com", - ], - } - - result.compliant == false - result.message == "5 global admins found. Maximum 4 recommended to minimize attack surface." - result.details.global_admin_count == 5 - count(result.affected_resources) == 5 -} - -test_non_compliant_many_global_admins if { - result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { - "global_admin_count": 10, - "global_admins": [ - "admin1@contoso.com", - "admin2@contoso.com", - "admin3@contoso.com", - "admin4@contoso.com", - "admin5@contoso.com", - "admin6@contoso.com", - "admin7@contoso.com", - "admin8@contoso.com", - "admin9@contoso.com", - "admin10@contoso.com", - ], - } - - result.compliant == false - result.details.global_admin_count == 10 - result.details.recommended_min == 2 - result.details.recommended_max == 4 -} - -test_empty_admin_list_with_valid_count if { - result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { - "global_admin_count": 2, - "global_admins": [], - } - - result.compliant == true - result.details.global_admin_count == 2 - count(result.affected_resources) == 0 -} - -test_missing_global_admins_uses_empty_array if { - result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { - "global_admin_count": 3, - } - - result.compliant == true - result.details.global_admin_count == 3 - count(result.affected_resources) == 0 -} - -test_result_structure if { - result := data.cis.microsoft_365_foundations.v6_0_0.control_1_1_3.result with input as { - "global_admin_count": 3, - "global_admins": [ - "admin1@contoso.com", - "admin2@contoso.com", - "admin3@contoso.com", - ], - } - - _ = result.compliant - _ = result.message - _ = result.affected_resources - _ = result.details.global_admin_count - _ = result.details.recommended_min - _ = result.details.recommended_max -} From 0dbd6ebf8f3a17f5f73c55f5e99cd877e162fc98 Mon Sep 17 00:00:00 2001 From: karansoni15-create Date: Wed, 23 Sep 2026 19:39:59 +1000 Subject: [PATCH 05/16] test: add CI behavioural fixtures for CIS 1.1.3 --- .../compliance/cis_1_1_3/boundary_two_admins.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 engine/tests/fixtures/compliance/cis_1_1_3/boundary_two_admins.json diff --git a/engine/tests/fixtures/compliance/cis_1_1_3/boundary_two_admins.json b/engine/tests/fixtures/compliance/cis_1_1_3/boundary_two_admins.json new file mode 100644 index 000000000..4796e2a27 --- /dev/null +++ b/engine/tests/fixtures/compliance/cis_1_1_3/boundary_two_admins.json @@ -0,0 +1,15 @@ +{ + "framework": "cis", + "benchmark": "microsoft-365-foundations", + "version": "v6.0.0", + "control_id": "1.1.3", + "scenario": "Two global administrators configured", + "input": { + "global_admin_count": 2, + "global_admins": [ + {"id": "admin-001", "display_name": "Global Admin 1"}, + {"id": "admin-002", "display_name": "Global Admin 2"} + ] + }, + "expected": {"compliant": true} +} From 375bd7f8980b77142ca96b018a8b95c0197f6521 Mon Sep 17 00:00:00 2001 From: karansoni15-create Date: Wed, 23 Sep 2026 19:40:01 +1000 Subject: [PATCH 06/16] test: add CI behavioural fixtures for CIS 1.1.3 --- .../cis_1_1_3/boundary_four_admins.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 engine/tests/fixtures/compliance/cis_1_1_3/boundary_four_admins.json diff --git a/engine/tests/fixtures/compliance/cis_1_1_3/boundary_four_admins.json b/engine/tests/fixtures/compliance/cis_1_1_3/boundary_four_admins.json new file mode 100644 index 000000000..27e03b51f --- /dev/null +++ b/engine/tests/fixtures/compliance/cis_1_1_3/boundary_four_admins.json @@ -0,0 +1,17 @@ +{ + "framework": "cis", + "benchmark": "microsoft-365-foundations", + "version": "v6.0.0", + "control_id": "1.1.3", + "scenario": "Four global administrators configured", + "input": { + "global_admin_count": 4, + "global_admins": [ + {"id": "admin-001", "display_name": "Global Admin 1"}, + {"id": "admin-002", "display_name": "Global Admin 2"}, + {"id": "admin-003", "display_name": "Global Admin 3"}, + {"id": "admin-004", "display_name": "Global Admin 4"} + ] + }, + "expected": {"compliant": true} +} From 4d1cc7f29ea5a0799cbf6a36ba44f920d074b3e6 Mon Sep 17 00:00:00 2001 From: karansoni15-create Date: Wed, 23 Sep 2026 19:40:04 +1000 Subject: [PATCH 07/16] test: add CI behavioural fixtures for CIS 1.1.3 --- .../fixtures/compliance/cis_1_1_3/zero_admins.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 engine/tests/fixtures/compliance/cis_1_1_3/zero_admins.json diff --git a/engine/tests/fixtures/compliance/cis_1_1_3/zero_admins.json b/engine/tests/fixtures/compliance/cis_1_1_3/zero_admins.json new file mode 100644 index 000000000..f908edf97 --- /dev/null +++ b/engine/tests/fixtures/compliance/cis_1_1_3/zero_admins.json @@ -0,0 +1,12 @@ +{ + "framework": "cis", + "benchmark": "microsoft-365-foundations", + "version": "v6.0.0", + "control_id": "1.1.3", + "scenario": "No global administrators configured", + "input": { + "global_admin_count": 0, + "global_admins": [] + }, + "expected": {"compliant": false} +} From 1784bca497c2b1da76695b9f69742e35bb91eb5d Mon Sep 17 00:00:00 2001 From: karansoni15-create Date: Wed, 23 Sep 2026 19:40:07 +1000 Subject: [PATCH 08/16] test: add CI behavioural fixtures for CIS 1.1.3 --- .../compliance/cis_1_1_3/many_admins.json | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 engine/tests/fixtures/compliance/cis_1_1_3/many_admins.json diff --git a/engine/tests/fixtures/compliance/cis_1_1_3/many_admins.json b/engine/tests/fixtures/compliance/cis_1_1_3/many_admins.json new file mode 100644 index 000000000..4a69e87f5 --- /dev/null +++ b/engine/tests/fixtures/compliance/cis_1_1_3/many_admins.json @@ -0,0 +1,23 @@ +{ + "framework": "cis", + "benchmark": "microsoft-365-foundations", + "version": "v6.0.0", + "control_id": "1.1.3", + "scenario": "Ten global administrators configured", + "input": { + "global_admin_count": 10, + "global_admins": [ + {"id": "admin-001", "display_name": "Global Admin 1"}, + {"id": "admin-002", "display_name": "Global Admin 2"}, + {"id": "admin-003", "display_name": "Global Admin 3"}, + {"id": "admin-004", "display_name": "Global Admin 4"}, + {"id": "admin-005", "display_name": "Global Admin 5"}, + {"id": "admin-006", "display_name": "Global Admin 6"}, + {"id": "admin-007", "display_name": "Global Admin 7"}, + {"id": "admin-008", "display_name": "Global Admin 8"}, + {"id": "admin-009", "display_name": "Global Admin 9"}, + {"id": "admin-010", "display_name": "Global Admin 10"} + ] + }, + "expected": {"compliant": false} +} From 332e62092653212925920e480d85ab1febd83ee8 Mon Sep 17 00:00:00 2001 From: karansoni15-create Date: Wed, 23 Sep 2026 19:40:10 +1000 Subject: [PATCH 09/16] test: add CI behavioural fixtures for CIS 1.1.3 --- .../cis_1_1_3/empty_admin_list_with_valid_count.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 engine/tests/fixtures/compliance/cis_1_1_3/empty_admin_list_with_valid_count.json diff --git a/engine/tests/fixtures/compliance/cis_1_1_3/empty_admin_list_with_valid_count.json b/engine/tests/fixtures/compliance/cis_1_1_3/empty_admin_list_with_valid_count.json new file mode 100644 index 000000000..3d5b7a09b --- /dev/null +++ b/engine/tests/fixtures/compliance/cis_1_1_3/empty_admin_list_with_valid_count.json @@ -0,0 +1,12 @@ +{ + "framework": "cis", + "benchmark": "microsoft-365-foundations", + "version": "v6.0.0", + "control_id": "1.1.3", + "scenario": "Valid count with empty administrator resource list", + "input": { + "global_admin_count": 2, + "global_admins": [] + }, + "expected": {"compliant": true} +} From 31b0f69acfa2816f69bc1b7827b4dd53a8d4eae1 Mon Sep 17 00:00:00 2001 From: karansoni15-create Date: Wed, 23 Sep 2026 19:40:14 +1000 Subject: [PATCH 10/16] test: add CI behavioural fixtures for CIS 1.1.3 --- .../missing_admin_list_with_valid_count.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 engine/tests/fixtures/compliance/cis_1_1_3/missing_admin_list_with_valid_count.json diff --git a/engine/tests/fixtures/compliance/cis_1_1_3/missing_admin_list_with_valid_count.json b/engine/tests/fixtures/compliance/cis_1_1_3/missing_admin_list_with_valid_count.json new file mode 100644 index 000000000..cf07af45d --- /dev/null +++ b/engine/tests/fixtures/compliance/cis_1_1_3/missing_admin_list_with_valid_count.json @@ -0,0 +1,11 @@ +{ + "framework": "cis", + "benchmark": "microsoft-365-foundations", + "version": "v6.0.0", + "control_id": "1.1.3", + "scenario": "Valid count with administrator resource list omitted", + "input": { + "global_admin_count": 3 + }, + "expected": {"compliant": true} +} From 344b8f8acfd043be955f40e915a33365e5a2bd56 Mon Sep 17 00:00:00 2001 From: karansoni15-create Date: Wed, 23 Sep 2026 20:02:00 +1000 Subject: [PATCH 11/16] style: format CIS 1.1.3 behavioural fixtures --- .../compliance/cis_1_1_3/boundary_two_admins.json | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/engine/tests/fixtures/compliance/cis_1_1_3/boundary_two_admins.json b/engine/tests/fixtures/compliance/cis_1_1_3/boundary_two_admins.json index 4796e2a27..3cf7cd77e 100644 --- a/engine/tests/fixtures/compliance/cis_1_1_3/boundary_two_admins.json +++ b/engine/tests/fixtures/compliance/cis_1_1_3/boundary_two_admins.json @@ -7,9 +7,17 @@ "input": { "global_admin_count": 2, "global_admins": [ - {"id": "admin-001", "display_name": "Global Admin 1"}, - {"id": "admin-002", "display_name": "Global Admin 2"} + { + "id": "admin-001", + "display_name": "Global Admin 1" + }, + { + "id": "admin-002", + "display_name": "Global Admin 2" + } ] }, - "expected": {"compliant": true} + "expected": { + "compliant": true + } } From 339977e8ff4f6800c1330779f591d34a8251e1eb Mon Sep 17 00:00:00 2001 From: karansoni15-create Date: Wed, 23 Sep 2026 20:02:03 +1000 Subject: [PATCH 12/16] style: format CIS 1.1.3 behavioural fixtures --- .../cis_1_1_3/boundary_four_admins.json | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/engine/tests/fixtures/compliance/cis_1_1_3/boundary_four_admins.json b/engine/tests/fixtures/compliance/cis_1_1_3/boundary_four_admins.json index 27e03b51f..90f4adc2a 100644 --- a/engine/tests/fixtures/compliance/cis_1_1_3/boundary_four_admins.json +++ b/engine/tests/fixtures/compliance/cis_1_1_3/boundary_four_admins.json @@ -7,11 +7,25 @@ "input": { "global_admin_count": 4, "global_admins": [ - {"id": "admin-001", "display_name": "Global Admin 1"}, - {"id": "admin-002", "display_name": "Global Admin 2"}, - {"id": "admin-003", "display_name": "Global Admin 3"}, - {"id": "admin-004", "display_name": "Global Admin 4"} + { + "id": "admin-001", + "display_name": "Global Admin 1" + }, + { + "id": "admin-002", + "display_name": "Global Admin 2" + }, + { + "id": "admin-003", + "display_name": "Global Admin 3" + }, + { + "id": "admin-004", + "display_name": "Global Admin 4" + } ] }, - "expected": {"compliant": true} + "expected": { + "compliant": true + } } From c8ab6c10da35cd0cd4c4584f90691440cc911823 Mon Sep 17 00:00:00 2001 From: karansoni15-create Date: Wed, 23 Sep 2026 20:02:06 +1000 Subject: [PATCH 13/16] style: format CIS 1.1.3 behavioural fixtures --- engine/tests/fixtures/compliance/cis_1_1_3/zero_admins.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/engine/tests/fixtures/compliance/cis_1_1_3/zero_admins.json b/engine/tests/fixtures/compliance/cis_1_1_3/zero_admins.json index f908edf97..093f1105a 100644 --- a/engine/tests/fixtures/compliance/cis_1_1_3/zero_admins.json +++ b/engine/tests/fixtures/compliance/cis_1_1_3/zero_admins.json @@ -8,5 +8,7 @@ "global_admin_count": 0, "global_admins": [] }, - "expected": {"compliant": false} + "expected": { + "compliant": false + } } From 9a9682e7ee277504bcde346ced58ff1721f200ef Mon Sep 17 00:00:00 2001 From: karansoni15-create Date: Wed, 23 Sep 2026 20:02:09 +1000 Subject: [PATCH 14/16] style: format CIS 1.1.3 behavioural fixtures --- .../compliance/cis_1_1_3/many_admins.json | 54 +++++++++++++++---- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/engine/tests/fixtures/compliance/cis_1_1_3/many_admins.json b/engine/tests/fixtures/compliance/cis_1_1_3/many_admins.json index 4a69e87f5..16af272be 100644 --- a/engine/tests/fixtures/compliance/cis_1_1_3/many_admins.json +++ b/engine/tests/fixtures/compliance/cis_1_1_3/many_admins.json @@ -7,17 +7,49 @@ "input": { "global_admin_count": 10, "global_admins": [ - {"id": "admin-001", "display_name": "Global Admin 1"}, - {"id": "admin-002", "display_name": "Global Admin 2"}, - {"id": "admin-003", "display_name": "Global Admin 3"}, - {"id": "admin-004", "display_name": "Global Admin 4"}, - {"id": "admin-005", "display_name": "Global Admin 5"}, - {"id": "admin-006", "display_name": "Global Admin 6"}, - {"id": "admin-007", "display_name": "Global Admin 7"}, - {"id": "admin-008", "display_name": "Global Admin 8"}, - {"id": "admin-009", "display_name": "Global Admin 9"}, - {"id": "admin-010", "display_name": "Global Admin 10"} + { + "id": "admin-001", + "display_name": "Global Admin 1" + }, + { + "id": "admin-002", + "display_name": "Global Admin 2" + }, + { + "id": "admin-003", + "display_name": "Global Admin 3" + }, + { + "id": "admin-004", + "display_name": "Global Admin 4" + }, + { + "id": "admin-005", + "display_name": "Global Admin 5" + }, + { + "id": "admin-006", + "display_name": "Global Admin 6" + }, + { + "id": "admin-007", + "display_name": "Global Admin 7" + }, + { + "id": "admin-008", + "display_name": "Global Admin 8" + }, + { + "id": "admin-009", + "display_name": "Global Admin 9" + }, + { + "id": "admin-010", + "display_name": "Global Admin 10" + } ] }, - "expected": {"compliant": false} + "expected": { + "compliant": false + } } From bf364bc3948aa60250ba7355f71336e051a02e61 Mon Sep 17 00:00:00 2001 From: karansoni15-create Date: Wed, 23 Sep 2026 20:02:23 +1000 Subject: [PATCH 15/16] style: format CIS 1.1.3 behavioural fixtures --- .../cis_1_1_3/empty_admin_list_with_valid_count.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/engine/tests/fixtures/compliance/cis_1_1_3/empty_admin_list_with_valid_count.json b/engine/tests/fixtures/compliance/cis_1_1_3/empty_admin_list_with_valid_count.json index 3d5b7a09b..ef181c993 100644 --- a/engine/tests/fixtures/compliance/cis_1_1_3/empty_admin_list_with_valid_count.json +++ b/engine/tests/fixtures/compliance/cis_1_1_3/empty_admin_list_with_valid_count.json @@ -8,5 +8,7 @@ "global_admin_count": 2, "global_admins": [] }, - "expected": {"compliant": true} + "expected": { + "compliant": true + } } From 4234744c42c3fed6a0d645a4cf075cc5d9284d3d Mon Sep 17 00:00:00 2001 From: karansoni15-create Date: Wed, 23 Sep 2026 20:02:27 +1000 Subject: [PATCH 16/16] style: format CIS 1.1.3 behavioural fixtures --- .../cis_1_1_3/missing_admin_list_with_valid_count.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/engine/tests/fixtures/compliance/cis_1_1_3/missing_admin_list_with_valid_count.json b/engine/tests/fixtures/compliance/cis_1_1_3/missing_admin_list_with_valid_count.json index cf07af45d..91f52547d 100644 --- a/engine/tests/fixtures/compliance/cis_1_1_3/missing_admin_list_with_valid_count.json +++ b/engine/tests/fixtures/compliance/cis_1_1_3/missing_admin_list_with_valid_count.json @@ -7,5 +7,7 @@ "input": { "global_admin_count": 3 }, - "expected": {"compliant": true} + "expected": { + "compliant": true + } }