From e7c3e1083760b126da10e12c76274e777a3af5cf Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 13 Apr 2025 10:05:49 +0200 Subject: [PATCH 1/3] Update input structure --- example-data/testorg-unremediated.json | 120 ++++++++++++------------- example-data/testorg.json | 120 ++++++++++++------------- 2 files changed, 118 insertions(+), 122 deletions(-) diff --git a/example-data/testorg-unremediated.json b/example-data/testorg-unremediated.json index 3d938b9..bbf4c67 100644 --- a/example-data/testorg-unremediated.json +++ b/example-data/testorg-unremediated.json @@ -1,63 +1,61 @@ { - "organization": { - "login": "test-org", - "id": 1234567, - "node_id": "O_abcdefg", - "url": "https://api.github.com/orgs/test-org", - "repos_url": "https://api.github.com/orgs/test-org/repos", - "events_url": "https://api.github.com/orgs/test-org/events", - "hooks_url": "https://api.github.com/orgs/test-org/hooks", - "issues_url": "https://api.github.com/orgs/test-org/issues", - "members_url": "https://api.github.com/orgs/test-org/members{/member}", - "public_members_url": "https://api.github.com/orgs/test-org/public_members{/member}", - "avatar_url": "https://avatars.githubusercontent.com/u/1234567?v=4", - "description": null, - "is_verified": false, - "has_organization_projects": true, - "has_repository_projects": true, - "public_repos": 0, - "public_gists": 0, - "followers": 0, - "following": 0, - "html_url": "https://github.com/test-org", - "created_at": "2025-04-09T15:36:21Z", - "updated_at": "2025-04-09T15:38:25Z", - "archived_at": null, - "type": "Organization", - "total_private_repos": 0, - "owned_private_repos": 0, - "private_gists": 0, - "disk_usage": 0, - "collaborators": 0, - "billing_email": "test@example.com", - "default_repository_permission": "read", - "members_can_create_repositories": true, - "two_factor_requirement_enabled": false, - "members_allowed_repository_creation_type": "all", - "members_can_create_public_repositories": true, - "members_can_create_private_repositories": true, - "members_can_create_internal_repositories": false, - "members_can_create_pages": true, - "members_can_fork_private_repositories": false, - "web_commit_signoff_required": false, - "deploy_keys_enabled_for_repositories": false, - "members_can_create_public_pages": true, - "members_can_create_private_pages": true, - "plan": { - "name": "free", - "space": 976562499, - "private_repos": 10000, - "filled_seats": 2, - "seats": 1 - }, - "advanced_security_enabled_for_new_repositories": false, - "dependabot_alerts_enabled_for_new_repositories": false, - "dependabot_security_updates_enabled_for_new_repositories": false, - "dependency_graph_enabled_for_new_repositories": false, - "secret_scanning_enabled_for_new_repositories": false, - "secret_scanning_push_protection_enabled_for_new_repositories": false, - "secret_scanning_push_protection_custom_link_enabled": false, - "secret_scanning_push_protection_custom_link": null, - "secret_scanning_validity_checks_enabled": false - } + "login": "test-org", + "id": 1234567, + "node_id": "O_abcdefg", + "url": "https://api.github.com/orgs/test-org", + "repos_url": "https://api.github.com/orgs/test-org/repos", + "events_url": "https://api.github.com/orgs/test-org/events", + "hooks_url": "https://api.github.com/orgs/test-org/hooks", + "issues_url": "https://api.github.com/orgs/test-org/issues", + "members_url": "https://api.github.com/orgs/test-org/members{/member}", + "public_members_url": "https://api.github.com/orgs/test-org/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/1234567?v=4", + "description": null, + "is_verified": false, + "has_organization_projects": true, + "has_repository_projects": true, + "public_repos": 0, + "public_gists": 0, + "followers": 0, + "following": 0, + "html_url": "https://github.com/test-org", + "created_at": "2025-04-09T15:36:21Z", + "updated_at": "2025-04-09T15:38:25Z", + "archived_at": null, + "type": "Organization", + "total_private_repos": 0, + "owned_private_repos": 0, + "private_gists": 0, + "disk_usage": 0, + "collaborators": 0, + "billing_email": "test@example.com", + "default_repository_permission": "read", + "members_can_create_repositories": true, + "two_factor_requirement_enabled": false, + "members_allowed_repository_creation_type": "all", + "members_can_create_public_repositories": true, + "members_can_create_private_repositories": true, + "members_can_create_internal_repositories": false, + "members_can_create_pages": true, + "members_can_fork_private_repositories": false, + "web_commit_signoff_required": false, + "deploy_keys_enabled_for_repositories": false, + "members_can_create_public_pages": true, + "members_can_create_private_pages": true, + "plan": { + "name": "free", + "space": 976562499, + "private_repos": 10000, + "filled_seats": 2, + "seats": 1 + }, + "advanced_security_enabled_for_new_repositories": false, + "dependabot_alerts_enabled_for_new_repositories": false, + "dependabot_security_updates_enabled_for_new_repositories": false, + "dependency_graph_enabled_for_new_repositories": false, + "secret_scanning_enabled_for_new_repositories": false, + "secret_scanning_push_protection_enabled_for_new_repositories": false, + "secret_scanning_push_protection_custom_link_enabled": false, + "secret_scanning_push_protection_custom_link": null, + "secret_scanning_validity_checks_enabled": false } \ No newline at end of file diff --git a/example-data/testorg.json b/example-data/testorg.json index fae5131..776e00f 100644 --- a/example-data/testorg.json +++ b/example-data/testorg.json @@ -1,63 +1,61 @@ { - "organization": { - "login": "test-org", - "id": 1234567, - "node_id": "O_abcdefg", - "url": "https://api.github.com/orgs/test-org", - "repos_url": "https://api.github.com/orgs/test-org/repos", - "events_url": "https://api.github.com/orgs/test-org/events", - "hooks_url": "https://api.github.com/orgs/test-org/hooks", - "issues_url": "https://api.github.com/orgs/test-org/issues", - "members_url": "https://api.github.com/orgs/test-org/members{/member}", - "public_members_url": "https://api.github.com/orgs/test-org/public_members{/member}", - "avatar_url": "https://avatars.githubusercontent.com/u/1234567?v=4", - "description": null, - "is_verified": false, - "has_organization_projects": true, - "has_repository_projects": true, - "public_repos": 0, - "public_gists": 0, - "followers": 0, - "following": 0, - "html_url": "https://github.com/test-org", - "created_at": "2025-04-09T15:36:21Z", - "updated_at": "2025-04-09T15:38:25Z", - "archived_at": null, - "type": "Organization", - "total_private_repos": 0, - "owned_private_repos": 0, - "private_gists": 0, - "disk_usage": 0, - "collaborators": 0, - "billing_email": "test@example.com", - "default_repository_permission": "read", - "members_can_create_repositories": true, - "two_factor_requirement_enabled": true, - "members_allowed_repository_creation_type": "all", - "members_can_create_public_repositories": false, - "members_can_create_private_repositories": true, - "members_can_create_internal_repositories": true, - "members_can_create_pages": false, - "members_can_fork_private_repositories": false, - "web_commit_signoff_required": true, - "deploy_keys_enabled_for_repositories": true, - "members_can_create_public_pages": false, - "members_can_create_private_pages": true, - "plan": { - "name": "free", - "space": 976562499, - "private_repos": 10000, - "filled_seats": 2, - "seats": 1 - }, - "advanced_security_enabled_for_new_repositories": true, - "dependabot_alerts_enabled_for_new_repositories": true, - "dependabot_security_updates_enabled_for_new_repositories": true, - "dependency_graph_enabled_for_new_repositories": true, - "secret_scanning_enabled_for_new_repositories": true, - "secret_scanning_push_protection_enabled_for_new_repositories": true, - "secret_scanning_push_protection_custom_link_enabled": true, - "secret_scanning_push_protection_custom_link": null, - "secret_scanning_validity_checks_enabled": true - } + "login": "test-org", + "id": 1234567, + "node_id": "O_abcdefg", + "url": "https://api.github.com/orgs/test-org", + "repos_url": "https://api.github.com/orgs/test-org/repos", + "events_url": "https://api.github.com/orgs/test-org/events", + "hooks_url": "https://api.github.com/orgs/test-org/hooks", + "issues_url": "https://api.github.com/orgs/test-org/issues", + "members_url": "https://api.github.com/orgs/test-org/members{/member}", + "public_members_url": "https://api.github.com/orgs/test-org/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/1234567?v=4", + "description": null, + "is_verified": false, + "has_organization_projects": true, + "has_repository_projects": true, + "public_repos": 0, + "public_gists": 0, + "followers": 0, + "following": 0, + "html_url": "https://github.com/test-org", + "created_at": "2025-04-09T15:36:21Z", + "updated_at": "2025-04-09T15:38:25Z", + "archived_at": null, + "type": "Organization", + "total_private_repos": 0, + "owned_private_repos": 0, + "private_gists": 0, + "disk_usage": 0, + "collaborators": 0, + "billing_email": "test@example.com", + "default_repository_permission": "read", + "members_can_create_repositories": true, + "two_factor_requirement_enabled": true, + "members_allowed_repository_creation_type": "all", + "members_can_create_public_repositories": false, + "members_can_create_private_repositories": true, + "members_can_create_internal_repositories": true, + "members_can_create_pages": false, + "members_can_fork_private_repositories": false, + "web_commit_signoff_required": true, + "deploy_keys_enabled_for_repositories": true, + "members_can_create_public_pages": false, + "members_can_create_private_pages": true, + "plan": { + "name": "free", + "space": 976562499, + "private_repos": 10000, + "filled_seats": 2, + "seats": 1 + }, + "advanced_security_enabled_for_new_repositories": true, + "dependabot_alerts_enabled_for_new_repositories": true, + "dependabot_security_updates_enabled_for_new_repositories": true, + "dependency_graph_enabled_for_new_repositories": true, + "secret_scanning_enabled_for_new_repositories": true, + "secret_scanning_push_protection_enabled_for_new_repositories": true, + "secret_scanning_push_protection_custom_link_enabled": true, + "secret_scanning_push_protection_custom_link": null, + "secret_scanning_validity_checks_enabled": true } \ No newline at end of file From 14fc18a887c96339845ce5a563d5a90bcdab0dd1 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 13 Apr 2025 10:09:02 +0200 Subject: [PATCH 2/3] Update plugin structures for flat org structure --- policies/gh_org_mfa_enabled.rego | 10 +--------- policies/gh_org_mfa_enabled_test.rego | 8 ++------ policies/gh_org_public_repos.rego | 16 +++------------- policies/gh_org_public_repos_test.rego | 12 ++++-------- policies/gh_org_secret_dependabot_alerts.rego | 10 +--------- .../gh_org_secret_dependabot_alerts_test.rego | 8 ++------ policies/gh_org_secret_scanning_enabled.rego | 10 +--------- .../gh_org_secret_scanning_enabled_test.rego | 10 +++------- 8 files changed, 17 insertions(+), 67 deletions(-) diff --git a/policies/gh_org_mfa_enabled.rego b/policies/gh_org_mfa_enabled.rego index 26e1731..5dc9e57 100644 --- a/policies/gh_org_mfa_enabled.rego +++ b/policies/gh_org_mfa_enabled.rego @@ -1,15 +1,7 @@ package compliance_framework.mfa_enabled -# METADATA -# title: Github Settings - Organizations - Two Factor Authentication Required -# description: Ensure that 2FA is enabled for all users within the organization, making it harder for TAs to gain access to the organization's repos and settings -# custom: -# controls: -# - -# schedule: "* * * * *" - violation[{}] if { - input.organization.two_factor_requirement_enabled == false + input.two_factor_requirement_enabled == false } title := "Two Factor Authentication is required at an organization level" diff --git a/policies/gh_org_mfa_enabled_test.rego b/policies/gh_org_mfa_enabled_test.rego index d9a4d8d..ca33023 100644 --- a/policies/gh_org_mfa_enabled_test.rego +++ b/policies/gh_org_mfa_enabled_test.rego @@ -2,16 +2,12 @@ package compliance_framework.mfa_enabled test_mfa_enabled if { count(violation) == 0 with input as { - "organization": { - "two_factor_requirement_enabled": true - } + "two_factor_requirement_enabled": true } } test_mfa_violate_if_disabled if { count(violation) > 0 with input as { - "organization": { - "two_factor_requirement_enabled": false - } + "two_factor_requirement_enabled": false } } \ No newline at end of file diff --git a/policies/gh_org_public_repos.rego b/policies/gh_org_public_repos.rego index e7f91f5..ce2db50 100644 --- a/policies/gh_org_public_repos.rego +++ b/policies/gh_org_public_repos.rego @@ -1,21 +1,11 @@ - package compliance_framework.public_repos -# METADATA -# title: Github Settings - Organizations - Public Repos and Gists -# description: "The organization should not have any public repos or gists if it is a sensitive organization" -# custom: -# controls: -# - -# schedule: "* * * * *" - - checks["repos"] if { - input.organization.public_repos > 0 + input.public_repos > 0 } checks["gists"] if { - input.organization.public_gists > 0 + input.public_gists > 0 } violation[{}] if { @@ -29,4 +19,4 @@ description := "The Organization should not have any public repositories or gist # No direct controls in the frameworks at the moment # But will be useful when we are mapping ISO 27001, data privacy or custom # IPR frameworks generated either as a standard or a custom catalog -controls := [] \ No newline at end of file +controls := [] diff --git a/policies/gh_org_public_repos_test.rego b/policies/gh_org_public_repos_test.rego index 91de60c..962561d 100644 --- a/policies/gh_org_public_repos_test.rego +++ b/policies/gh_org_public_repos_test.rego @@ -2,18 +2,14 @@ package compliance_framework.public_repos test_public_repos_is_zero if { count(violation) == 0 with input as { - "organization": { - "pubic_repos": 0, - "public_gists": 0 - } + "pubic_repos": 0, + "public_gists": 0 } } test_public_repos_violate_when_higher if { count(violation) > 0 with input as { - "organization": { - "public_repos": 10, - "public_gists": 0 - } + "public_repos": 10, + "public_gists": 0 } } \ No newline at end of file diff --git a/policies/gh_org_secret_dependabot_alerts.rego b/policies/gh_org_secret_dependabot_alerts.rego index 52a02e3..a25d322 100644 --- a/policies/gh_org_secret_dependabot_alerts.rego +++ b/policies/gh_org_secret_dependabot_alerts.rego @@ -1,15 +1,7 @@ package compliance_framework.dependabot_alerts -# METADATA -# title: Github Settings - Organizations - Dependabot alerts enabled for new repos -# description: "All new repositories should be set up for Dependabot alerts as the default. Note: Endpoint is closing down at some point and moving to code security configurations: See https://docs.github.com/rest/code-security/configurations" -# custom: -# controls: -# - -# schedule: "* * * * *" - violation[{}] if { - input.organization.dependabot_alerts_enabled_for_new_repositories == false + input.dependabot_alerts_enabled_for_new_repositories == false } title := "Dependabot alerts enabled for new repositories" diff --git a/policies/gh_org_secret_dependabot_alerts_test.rego b/policies/gh_org_secret_dependabot_alerts_test.rego index 4253e90..a555075 100644 --- a/policies/gh_org_secret_dependabot_alerts_test.rego +++ b/policies/gh_org_secret_dependabot_alerts_test.rego @@ -2,16 +2,12 @@ package compliance_framework.dependabot_alerts test_scanning_enabled_new_repos if { count(violation) == 0 with input as { - "organization": { - "dependabot_alerts_enabled_for_new_repositories": true - } + "dependabot_alerts_enabled_for_new_repositories": true } } test_secret_scanning_enabled_new_repos_violate_if_disabled if { count(violation) > 0 with input as { - "organization": { - "dependabot_alerts_enabled_for_new_repositories": false - } + "dependabot_alerts_enabled_for_new_repositories": false } } \ No newline at end of file diff --git a/policies/gh_org_secret_scanning_enabled.rego b/policies/gh_org_secret_scanning_enabled.rego index a0bba6d..2dccad6 100644 --- a/policies/gh_org_secret_scanning_enabled.rego +++ b/policies/gh_org_secret_scanning_enabled.rego @@ -1,15 +1,7 @@ package compliance_framework.secret_scanning -# METADATA -# title: Github Settings - Organizations - Secret Scanning enabled for new repos -# description: "All new repositories should be set up for secret scanning as the default. Note: Endpoint is closing down at some point and moving to code security configurations: See https://docs.github.com/rest/code-security/configurations" -# custom: -# controls: -# - -# schedule: "* * * * *" - violation[{}] if { - input.organization.secret_scanning_enabled_for_new_repositories == false + input.secret_scanning_enabled_for_new_repositories == false } title := "Secret Scanning is enabled for new repositories in the organization" diff --git a/policies/gh_org_secret_scanning_enabled_test.rego b/policies/gh_org_secret_scanning_enabled_test.rego index a347011..05d2a63 100644 --- a/policies/gh_org_secret_scanning_enabled_test.rego +++ b/policies/gh_org_secret_scanning_enabled_test.rego @@ -2,16 +2,12 @@ package compliance_framework.secret_scanning test_scanning_enabled_new_repos if { count(violation) == 0 with input as { - "organization": { - "secret_scanning_enabled_for_new_repositories": true - } + "secret_scanning_enabled_for_new_repositories": true } } test_secret_scanning_enabled_new_repos_violate_if_disabled if { count(violation) > 0 with input as { - "organization": { - "secret_scanning_enabled_for_new_repositories": false - } + "secret_scanning_enabled_for_new_repositories": false } -} \ No newline at end of file +} From a55e32b5e5208a4161fb97c3bc133de81e390927 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 13 Apr 2025 10:34:34 +0200 Subject: [PATCH 3/3] Update policies --- policies/gh_org_mfa_enabled.rego | 8 +++++ policies/gh_org_secret_dependabot_alerts.rego | 35 +++++++++++++++---- policies/gh_org_secret_scanning_enabled.rego | 24 +++++++++++++ 3 files changed, 60 insertions(+), 7 deletions(-) diff --git a/policies/gh_org_mfa_enabled.rego b/policies/gh_org_mfa_enabled.rego index 5dc9e57..84081b7 100644 --- a/policies/gh_org_mfa_enabled.rego +++ b/policies/gh_org_mfa_enabled.rego @@ -36,4 +36,12 @@ controls := [ "class": "SP800-53-enhancement", "control-id": "ia-2.2", # Multi-factor Authentication for Non-privileged Accounts }, + { + "class": "OWASP_DSOMM_3", + "control-id": "IM-3.10", + }, + { + "class": "OWASP_DSOMM_3", + "control-id": "IM-3.11", + }, ] \ No newline at end of file diff --git a/policies/gh_org_secret_dependabot_alerts.rego b/policies/gh_org_secret_dependabot_alerts.rego index a25d322..dcb2609 100644 --- a/policies/gh_org_secret_dependabot_alerts.rego +++ b/policies/gh_org_secret_dependabot_alerts.rego @@ -10,18 +10,39 @@ remarks := "Endpoint is closing down at some point and moving to code security c controls := [ { - "class": "SP800-53", + "class": "SP800-53-enhancement", "control-id": "ra-5.4", # Discoverable Information - "statement-ids": [] }, { "class": "SP800-218", - "control_id": "RV-1.1", - "statement-ids": [] + "control-id": "RV-1.1", + }, + { + "class": "SP800-218", + "control-id": "PW-1.3" + }, + { + "class": "SP800-218", + "control-id": "PW-5.1" + }, + { + "class": "SP800-218", + "control-id": "PW-8.2" + }, + { + "class": "OWASP_DSOMM_3", + "control-id": "IG-3.3", + }, + { + "class": "OWASP_DSOMM_3", + "control-id": "IG-3.4", + }, + { + "class": "OWASP_DSOMM_3", + "control-id": "IG-2.5", }, { "class": "OWASP_DSOMM_3", - "control_id": "IG-3.3", - "statement-ids": [] + "control-id": "TV-6.3", }, -] \ No newline at end of file +] diff --git a/policies/gh_org_secret_scanning_enabled.rego b/policies/gh_org_secret_scanning_enabled.rego index 2dccad6..581cc0b 100644 --- a/policies/gh_org_secret_scanning_enabled.rego +++ b/policies/gh_org_secret_scanning_enabled.rego @@ -22,4 +22,28 @@ controls := [ "TV-6.8_statement" ] }, + { + "class": "SP800-218", + "control-id": "RV-1.1" + }, + { + "class": "SP800-218", + "control-id": "PW-1.3" + }, + { + "class": "SP800-218", + "control-id": "PW-5.1" + }, + { + "class": "SP800-218", + "control-id": "PW-8.2" + }, + { + "class": "OWASP_DSOMM_3", + "control-id": "IG-2.5", + }, + { + "class": "OWASP_DSOMM_3", + "control-id": "TV-6.8", + }, ] \ No newline at end of file