diff --git a/.gitignore b/.gitignore index 1d000f4..6c58c78 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea/ data/ dist/ +*.tar.gz \ No newline at end of file diff --git a/Makefile b/Makefile index 5f0cba8..0ea2f07 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,10 @@ # Variables REGISTRY_URL := ghcr.io -NAMESPACE := chris-cmsoft -POLICY_NAME := local-ssh-policies +NAMESPACE := compliance-framework +POLICY_NAME := plugin-github-settings-policies VERSION := latest -POLICY_DIR := ./ssh # Directory containing your .rego files +POLICY_DIR := ./policies # Directory containing your .rego files # Build and Push Commands .PHONY: all build bundle push clean diff --git a/README.md b/README.md index 2267545..f6d6a09 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Template for policies for use in Compliance Framework plugins +# Template for policies for use in the Github Settings plugin ## Testing @@ -19,19 +19,7 @@ make build ## Running policies locally ```shell -opa eval -I -b policies -f pretty data.compliance_framework.local_ssh < -# description: -# custom: -# controls: -# - -# schedule: "" - -package example - -import rego.v1 - -# Your policy code here -# e.g. -allow if { - input.example -} \ No newline at end of file diff --git a/policies/example_test.rego b/policies/example_test.rego deleted file mode 100644 index 402f0b6..0000000 --- a/policies/example_test.rego +++ /dev/null @@ -1,11 +0,0 @@ -package example - -import rego.v1 - -import data.example - -# Your code here -# e.g. -test_something if { - example.allow with input as {"example": true} -} \ No newline at end of file diff --git a/policies/gh_org_mfa_enabled.rego b/policies/gh_org_mfa_enabled.rego new file mode 100644 index 0000000..26e1731 --- /dev/null +++ b/policies/gh_org_mfa_enabled.rego @@ -0,0 +1,47 @@ +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 +} + +title := "Two Factor Authentication is required at an organization level" +description := "Two factor authentication should be enabled and enforced for all users within the Github Organization to make it harder for malicious actors to gain access to the organizations settings and repositories & settings" +remarks := "More information from Github can be found here: https://docs.github.com/en/organizations/keeping-your-organization-secure/managing-two-factor-authentication-for-your-organization/requiring-two-factor-authentication-in-your-organization" + +controls := [ + # SAMA Cyber Security Framework v1.0 + # https://rulebook.sama.gov.sa/en/cyber-security-framework-2 + # Class: SAMA_CSF_1.0 + # + # 3.3: Cyber Security Operations and Technology + # https://rulebook.sama.gov.sa/en/33-cyber-security-operations-and-technology-0 + { + "class": "SAMA_CSF_1.0", + "control-id": "3.3.5", # Identity and Access Management https://rulebook.sama.gov.sa/en/335-identity-and-access-management-0 + "statement-ids": [ + "4.e", + "f.1.a", + ] + }, + + # NIST SP 800-53 v5.1.1 + # https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-53r5.pdf + # Class SP800-53-enhancement + # ia: Identification and Authentication + { + "class": "SP800-53-enhancement", + "control-id": "ia-2.1", # Multi-factor Authentication to Privileged Accounts + }, + { + "class": "SP800-53-enhancement", + "control-id": "ia-2.2", # Multi-factor Authentication for Non-privileged Accounts + }, +] \ No newline at end of file diff --git a/policies/gh_org_mfa_enabled_test.rego b/policies/gh_org_mfa_enabled_test.rego new file mode 100644 index 0000000..d9a4d8d --- /dev/null +++ b/policies/gh_org_mfa_enabled_test.rego @@ -0,0 +1,17 @@ +package compliance_framework.mfa_enabled + +test_mfa_enabled if { + count(violation) == 0 with input as { + "organization": { + "two_factor_requirement_enabled": true + } + } +} + +test_mfa_violate_if_disabled if { + count(violation) > 0 with input as { + "organization": { + "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 new file mode 100644 index 0000000..fae6355 --- /dev/null +++ b/policies/gh_org_public_repos.rego @@ -0,0 +1,31 @@ +# 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: "* * * * *" + + +package compliance_framework.public_repos + +checks["repos"] if { + input.organization.public_repos > 0 +} + +checks["gists"] if { + input.organization.public_gists > 0 +} + +violation[{}] if { + some check in checks +} + + +title := "No Public Repos or Gists" +description := "The Organization should not have any public repositories or gists attached to it" + +# 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 diff --git a/policies/gh_org_public_repos_test.rego b/policies/gh_org_public_repos_test.rego new file mode 100644 index 0000000..91de60c --- /dev/null +++ b/policies/gh_org_public_repos_test.rego @@ -0,0 +1,19 @@ +package compliance_framework.public_repos + +test_public_repos_is_zero if { + count(violation) == 0 with input as { + "organization": { + "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 + } + } +} \ No newline at end of file diff --git a/policies/gh_org_secret_scanning_enabled.rego b/policies/gh_org_secret_scanning_enabled.rego new file mode 100644 index 0000000..a0bba6d --- /dev/null +++ b/policies/gh_org_secret_scanning_enabled.rego @@ -0,0 +1,33 @@ +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 +} + +title := "Secret Scanning is enabled for new repositories in the organization" +description := "All new repositories should be set up for secret scanning as the default." +remarks := "Endpoint is closing down at some point and moving to code security configurations: See https://docs.github.com/rest/code-security/configurations" + +controls := [ + # OWASP DSOMM v3 + # https://dsomm.owasp.org/ + # Class: OWASP_DSOMM_3 + # + # TV: Test and Verification + { + "class": "SAMA_CSF_1.0", + "control-id": "TV-6.8", # Test for stored secrets https://dsomm.owasp.org/activity-description?uuid=c6e3c812-56e2-41b0-ae01-b7afc41a004c&dimension=Test%20and%20Verification&subDimension=Static%20depth%20for%20infrastructure&level=1&activityName=Test%20for%20stored%20secrets + + "statement-ids": [ + "TV-6.8_statement" + ] + }, +] \ No newline at end of file diff --git a/policies/gh_org_secret_scanning_enabled_test.rego b/policies/gh_org_secret_scanning_enabled_test.rego new file mode 100644 index 0000000..a347011 --- /dev/null +++ b/policies/gh_org_secret_scanning_enabled_test.rego @@ -0,0 +1,17 @@ +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 + } + } +} + +test_secret_scanning_enabled_new_repos_violate_if_disabled if { + count(violation) > 0 with input as { + "organization": { + "secret_scanning_enabled_for_new_repositories": false + } + } +} \ No newline at end of file