Project: Checkov (Provisioning / Security & Compliance)
File: Contribute New GitHub Policies.md

layout: default published: true title: Contribute New GitHub configuration policy nav_order: 5 In this example, we'll add support for a new GitHub configuration check. We are going to add a new check that will examine how branch protection rules are configured and validate we enforce protection rules on admin users too. First, we will validate if the GitHub API call that GETs the branch protection current state exists in `checkov/github/dal.py`. If not it can be added to that file like the following example: ```python class GitHub(BaseVCSDAL): ... ... def setupconfdir(self) -> None: ... self.githubconffile_paths = { "branchprotectionrules": [Path(self.githubconfdirpath) / "branchprotection_rules.json"], ... } def getbranchprotection_rules(self): if self.currentbranch and self.currentrepository: branchprotectionrules = self._request( endpoint="repos/{}/branches/{}/protection".format(self.currentrepository, self.currentbranch)) return branchprotectionrules return None def persistbranchprotection_rules(self): data = self.getbranchprotection_rules() if data: BaseVCSDAL.persist(path=self.githubconffile_paths, conf=data) def persistallconfs(self): if strtobool(os.getenv("CKVGITHUBCONFIGFETCHDATA", "True")): self.persistorganizationsecurity() self.persistbranchprotection_rules() ``` Go to `checkov/github/checks` and add `enforcebranchprotectiononadmins.py`: ```python from checkov.github.basegithubbranch_security import BranchSecurity class GithubBranchEnforceAdmins(BranchSecurity): def init(self): name = "Ensure GitHub branch protection rules is enforced on admins" id = "CKVGITHUB8" super().init( name=name, id=id ) def getevaluatedkeys(self): return ['enforce_admins/enabled'] check = GithubBranchEnforceAdmins() ``` And also add the JSON schema to validate the GitHub API response `/checkov/github/schemas/branch_protection.py`: ```python from checkov.github.schemas.base_schema import GithubConfSchema class BranchProtectionSchema(GithubConfSchema): def init(self): schema = { "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { "url": { "type": "string" }, "required_signatures": { "type": "object", "properties": { "url": { "type": "string" }, "enabled": { "type": "boolean" } }, "required": [ "url", "enabled" ] }, "enforce_admins": { "type": "object", "properties": { "url": { "type": "string" }, "enabled": { "type": "boolean" } }, "required": [ "url", "enabled" ] }, "requiredlinearhistory": { "type": "object", "properties": { "enabled": { "type": "boolean" } }, "required": [ "enabled" ] }, "allowforcepushes": { "type": "object", "properties": { "enabled": { "type": "boolean" } }, "required": [ "enabled" ] }, "allow_deletions": { "type": "object", "properties": { "enabled": { "type": "boolean" } }, "required": [ "enabled" ] }, "requiredconversationresolution": { "type": "object", "properties": { "enabled": { "type": "boolean" } }, "required": [ "enabled" ] } }, "required": [ "url", "enforce_admins", "requiredlinearhistory", "allowforcepushes", "allow_deletions", ] } super().init(schema=schema) schema = BranchProtectionSchema() ``` follow the examples in `tests/github/test_runner.py` and add a test to the new check So there you have it! A new check will be scanned once your contribution is merged!