diff --git a/COMPLIANCE.md b/COMPLIANCE.md
new file mode 100644
index 0000000..348847b
--- /dev/null
+++ b/COMPLIANCE.md
@@ -0,0 +1,125 @@
+([Back](README.md))
+
+# Compliance
+
+## Table of Contents
+
+* [Compliance](#compliance)
+ * [Overview](#overview)
+ * [GitHub Foundations Toolkit PBMM Compliance Features](#github-foundations-toolkit-pbmm-compliance-features)
+ * [GitHub Security Features Status](#github-security-features-status)
+ * [Audit Logs](#audit-logs)
+ * [Daily Audit Log Export](#daily-audit-log-export)
+ * [Exporting GitHub Enterprise Audit Logs to Azure Sentinel](#exporting-github-enterprise-audit-logs-to-azure-sentinel)
+ * [Streaming Audit Logs to Other Platforms](#streaming-audit-logs-to-other-platforms)
+
+## Overview
+
+This document outlines the compliance and security features of the platform.
+
+## GitHub Foundations Toolkit PBMM Compliance Features
+
+The following table maps the features of the GitHub Foundations Toolkit to the [PBMM Controls]()
+
+
+
+
+| Item | What | Where | Controls | Open-Source Alternative |
+| --- | --- | --- | --- | --- |
+| Encrypted Secrets | Uses GitHub public key to encrypt secrets. Secrets must be encrypted to be used. |
- modules/organization
- modules/private_repository
- modules/public_repository
| IA-5(c)(e)(h)(i), IA-5(1)(c),IA-5(6), IA-5(7), SC-8(1), SC-12, SC-13, SC-17 | - [vault](https://www.hashicorp.com/products/vault)
- [confidant](https://lyft.github.io/confidant/)
|
+| Vulnerability Alerts | - Vulnerability alerts are enabled by default on `public` and `private` repos
- Vulnerabilities detection is automatically updated
| - modules/organization
- modules/private_repository
- modules/public_repository
| SI-4(5), SI-4(7), SI-10 | - [sbom-tool](https://github.com/microsoft/sbom-tool)
- [syft](https://github.com/anchore/syft)
- [cdxgen](https://github.com/CycloneDX/cdxgen)
|
+| Secret Scanning | Scanning of the repo for secrets | - modules/organization
- modules/private_repository
- modules/public_repository
- modules/repository_base
| AC-22, IA-5(7), IR-9, SI-4(5), SI-4(7), SI-10 | - [trufflehog](https://trufflesecurity.com/)
- [gitleaks](https://github.com/gitleaks/gitleaks)
- [detect-secrets](https://github.com/Yelp/detect-secrets)
|
+| Advanced Security | - Code scanning
- Manual step. Instructions to be added to README
| - modules/private_repository
- modules/public_repository
- modules/repository_base
| SI-4(5), SI-4(7), SI-10 | - [semgrep](https://github.com/semgrep/semgrep)
- [sonarqube](https://www.sonarqube.org/)
|
+| Protected Branches Ruleset - Pull Requests | - Require pull requests
- Require at least 1 reviewer
- When new commits are pushed to an existing PR, any previous approvals are required again.
| - modules/private_repository
- modules/public_repository
- modules/repository_base
| CM-3, CM-4, CM-5, SC-28, SI-10, SI-12 | - [GitLab](https://about.gitlab.com/)
|
+| Protected Branches Ruleset - Signed Commits
**TODO - Not currently validated** | | - modules/private_repository
- modules/public_repository
- modules/repository_base
| IA-2, IA-2(11), IA-8, IA-8(100), SC-8, SC-8(1), SC-13, SC-28 | - [GitLab](https://about.gitlab.com/)
- [Git](https://git-scm.com/)
- [Mercurial](https://www.mercurial-scm.org/)
|
+| Export Audit Material
| Audit material is exported in [JSON format](#daily-audit-log-export), or there are instructions on how to obtain logs by other means. [See here](#audit-logs). | GH Action | AC-2(4), AC-6(9), AC-17(1), AU-2, AU-6, SI-4 | - [GitLab](https://about.gitlab.com/)
|
+| Delete branches on merge | Branches are configured to be deleted after a PR is merged | - modules/private_repository
- modules/public_repository
- modules/repository_base | SI-12 |
- [GitLab](https://about.gitlab.com/)
|
+| Repository Creation Restrictions | Users can: - Create private repos
- Create internal repos
User cannot: - Create public repos
- Fork Private repos
| - modules/organization
| AC-20(3), AC-22 | - [GitLab](https://about.gitlab.com/)
|
+| Predefined Roles | Predefined roles include: - Security Engineer
- Contractor
- Community Manager
| - modules/organization
| AC-2, AC-16(2) | - [GitLab](https://about.gitlab.com/)
- [Keycloak](https://www.keycloak.org/)
|
+| Drift Detection | Tool used to detect if the terraform state has drifted from what's stored in source control | - modules/organization
| CM-2, CM-3(f)(g), CM-5, CM-6(c)(d), CM-9(d) | - [Terraform CLI](https://www.terraform.io/)
- [Terragrunt CLI](https://terragrunt.gruntwork.io/)
|
+| Resource Deletion Protection | An action that forces a user to acknowledge Terraform plan deletions, before performing them | - modules/organization
| AC-16(2), CM-3, CM-4, CM-5, CM-6(D), CM-9, SI-10 | - [GitLab](https://docs.gitlab.com/runner/)
|
+| Detect whether GHAS enabled | For public repositories, and repos with GHAS purchased, we recommend that it be turned on. This GH Action runs daily at 2am to check that the setting is enabled in all eligible repos | GH Action | IA-5(7), SI-4(5), SI-4(7), SI-10 | - [GitLab runners](https://docs.gitlab.com/runner/)
|
+| Documentations- Creating resources | The documentation for the GHF toolkit includes the relevant documentation that describes authentication methods for users signing into your enterprise, how to create organizations and teams for repository access and collaboration, and suggested best practices for user security | READMEs | AC-5, AC-6 | - Any text editor / code-revision control tool.
|
+| | | | | |
+
+### Controls that are met by GitHub by default
+
+The following controls are met by GitHub by default and are not explicitly implemented in the toolkit:
+
+| Item | What | Where | Controls | Open-Source Alternative |
+| --- | --- | --- | --- | --- |
+| Account dormancy policy | GitHub accounts are marked dormant, and made inactive after 90 days of inactivity for Enterprise accounts | [Managing Dormant Accounts](https://docs.github.com/en/enterprise-cloud@latest/admin/managing-accounts-and-repositories/managing-users-in-your-enterprise/managing-dormant-users) | AC-2(3) | - [GitLab](https://about.gitlab.com/)
- [Keycloak](https://www.keycloak.org/)
|
+| HTTPS and SSH access | GitHub enforces the use of HTTPS and/or SSH for committing and pulling code | [GitHub Docs](https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/securing-your-account-with-two-factor-authentication-2fa) | AC-17(2), SC-8, SC-8(1), SC-12, SC-13, SC-17, SC-28, SC-28(1) | - [GitLab](https://about.gitlab.com/)
- [Keycloak](https://www.keycloak.org/)
|
+| | | | | |
+
+
+## GitHub Security Features Status
+
+Inside the toolkit, we strive to provide the most up-to-date security features that GitHub has to offer. Below is a table that shows the status of the features that we support in the toolkit.
+1. The _**Status**_ column is the status of implementing the GitHub feature in the toolkit.
+2. The _Provider Status**_ column is the status of the feature in [Terraform GitHub Provider](https://registry.terraform.io/providers/integrations/github/latest/docs), and
+3. the _**GH API Status**_ column is the status of the feature in the [GitHub API](https://docs.github.com/en/rest/reference).
+
+| Feature | Status | Provider Status | GH API Status | Side Notes |
+| --- | --- | --- | --- | --- |
+| Encrypted secrets | ✅ | ✅ | ✅ | We don't handle encryption directly, but secrets are encrypted with github private keys |
+| Vulnerability alerts | ✅ | ✅ | ✅ | |
+| Private vulnerability reporting | ❌ | ❌ | ✅ | |
+| Secret scanning | ✅ | ✅ | ✅ | |
+| Secret scanning push protection | ✅ | ✅ | ✅ | |
+| CodeQL codescanning | ❌ | ❌ | ✅ | |
+| | | | | |
+| Rulesets | ✅ | ✅ | ✅ | Although the [GitHub Documentation](https://docs.github.com/en/rest/repos/rules?apiVersion=2022-11-28#create-a-repository-ruleset) lists it as a capability in the api there are some limitations. For example: Organization rulesets can define workflows that must be completed for the ruleset to be considered passed, but it is not possible for repository rulesets. |
+| Commit signing enforcement | ✅ | ✅ | ✅ | |
+| Delete branches on merge | ✅ | ✅ | ✅ | |
+| Repository creation restrictions | ✅ | ✅ | ✅ | |
+| | | | | |
+| Custom Repository Roles | ✅ | ✅ | ✅ | |
+| Custom Organization Roles | ❌ | ❌ | ✅ | Confusing because there is a terraform resource named `github_organization_custom_role` but this resource actually makes custom repository roles. Custom organization roles have not been implemented. But the GH api does support it. |
+| Deploy Keys | ❌ | ✅ | ✅ | |
+| Organization Member Base Permissions | ✅ | ✅ | ✅ | |
+| Custom Properties | ❌ | ❌ | ❌ | |
+| | | | | |
+| 2FA | ❌ | ❌ | ❌ | Not exposed by the API. This setting is completely manual |
+| SAML SSO | ❌ | ❌ | ❌ | Not exposed by the API. This setting is completely manual |
+| Team Synchronization | ❌ | ✅ | ✅ | |
+| | | | | |
+
+
+
+## Audit Logs
+
+Learn how to enable audit logs for your GitHub Enterprise account to track user activity and changes made to your organization.
+
+1. For _GitHub Enterprise_ Audit logs, see [GitHub's documentation](https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/using-the-audit-log-api-for-your-enterprise).
+2. To query the audit log API for your _GitHub Enterprise_, see [GitHub's documentation](https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log?apiVersion=2022-11-28).
+3. For _Organization_ Audit logs, see [GitHub's documentation](https://docs.github.com/en/organizations/keeping-your-organization-secure/reviewing-the-audit-log-for-your-organization).
+
+### Daily Audit Log Export
+
+A GitHub Workflow is run daily to export the audit logs to a JSON file. The JSON file is then uploaded to the action's output artifacts. The JSON file can be downloaded from the artifacts tab in the GitHub Actions page.
+
+### Exporting GitHub Enterprise Audit Logs to Azure Sentinel
+
+To export GitHub Enterprise audit logs to Azure Sentinel, [follow the steps found here](https://learn.microsoft.com/en-us/azure/sentinel/data-connectors/azure-logic-apps).
+
+The Azure Marketplace offers the [Microsoft Sentinel - Continuous Threat Monitoring for GitHub (Preview)](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/microsoftcorporation1622712991604.sentinel4github?tab=Overview) connector to help you get started.
+
+### Streaming Audit Logs to Other Platforms
+
+GitHub supports the [streaming of audit logs](https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise) to other platforms. The list of currently supported platforms is:
+
+* [Amazon S3](https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-amazon-s3)
+* [Azure Blob Storage](https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-azure-blob-storage)
+* [Azure Event Hubs](https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-azure-event-hubs)
+* [Datadog](https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-datadog)
+* [Google Cloud Storage](https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-google-cloud-storage)
+* [Splunk](https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk)
diff --git a/README.md b/README.md
index 8e4eff7..6497619 100644
--- a/README.md
+++ b/README.md
@@ -8,20 +8,20 @@ Managing GitHub for large enterprises introduces complex security and consistenc
### Project Features:
-- **Automate Continuous Secure Infrastructure:**
- - Use Terraform to apply Infrastructure as Code (IaC) principles in managing multiple organizations under a single GitHub Enterprise account.
+- **Automate Continuous Secure Infrastructure:**
+ - Use Terraform to apply Infrastructure as Code (IaC) principles in managing multiple organizations under a single GitHub Enterprise account.
- Establish and enforce security best practices by default.
- Use drift detection to promptly identify and rectify unauthorized changes, ensuring your configurations are always secure.
-- **Centralize Control:**
+- **Centralize Control:**
- Gain a comprehensive overview for managing organizations, repositories, and teams across your enterprise.
- - Streamline updates and security policy enforcement across your entire enterprise, reducing the need for manual intervention.
+ - Streamline updates and security policy enforcement across your entire enterprise, reducing the need for manual intervention.
-- **Rapid Rollouts:**
+- **Rapid Rollouts:**
- Push policy updates across the entire enterprise in moments rather than waiting days for each organization to schedule individual exercises.
- Automate repetitive tasks, allowing teams to focus on innovation.
-- **Reduce Security Risks:**
+- **Reduce Security Risks:**
- Enforce consistent security policies across all organizations to minimize vulnerabilities and protect against attacks.
- Have a unified view of potential vulnerabilities to prevent gaps opening in one organization or another.
@@ -52,8 +52,12 @@ Initial setup of your state file backend, and creation of all organizations unde
Management of organizations, repositories, and teams, Review results of drift detection, and execution of pull request plans for your organizations.
+## [Compliance](./COMPLIANCE.md)
+
+Features of the toolkit that ensure compliance and security for your GitHub Enterprise or Organization account.
+
## Contributing to the toolkit
We welcome contributions to the GitHub Foundations Toolkit. Please read these [Contributing Guidelines](./CONTRIBUTING.md) for more information on how to get started.
-**_Embrace a Secure and Efficient Future with the GitHub Foundations Toolkit!_**
\ No newline at end of file
+**_Embrace a Secure and Efficient Future with the GitHub Foundations Toolkit!_**
diff --git a/organizations/.github/scripts/gh_foundations/gh_foundations.py b/organizations/.github/scripts/gh_foundations/gh_foundations.py
new file mode 100644
index 0000000..f9cfb09
--- /dev/null
+++ b/organizations/.github/scripts/gh_foundations/gh_foundations.py
@@ -0,0 +1,203 @@
+"""
+This module provides functions to find and manage organizations, repositories,
+and files in the GHF (GitHub Foundations) project.
+
+Usage:
+- To find all public repositories or repositories with GHAS enabled, run the
+ script with the `--ghas` flag.
+- To find all organizations managed by GHF, run the script with the `--orgs` flag.
+"""
+
+import inspect
+import logging
+import os
+import sys
+
+import argparse
+import hcl2
+
+# Get the absolute path of the script file
+script_dir = os.path.dirname(os.path.abspath(__file__))
+# Construct the path to the providers directory
+providers_dir = os.path.join(script_dir, '../../../providers')
+# Construct the path to the projects directory
+projects_dir = os.path.join(script_dir, '../../../projects')
+
+def find_terragrunt_hcl_files(root_dir=projects_dir)->list:
+ """ Find all terragrunt.hcl files
+
+ Looks for all terragrunt.hcl files in the provided directory and
+ returns a dictionary.
+ Args:
+ root_dir (str): The root directory to search for terragrunt.hcl files.
+ Default is `../../../projects`
+ Returns:
+ dict: A dictionary with the org name as the key and a list of paths
+ to the terragrunt.hcl files as the value
+ """
+ hcl_files = []
+
+ for root, _, files in os.walk(root_dir):
+ for file in files:
+ # ignore file in the .terragrunt-cache directory
+ if '.terragrunt-cache' in root:
+ continue
+
+ dirs = root.split('/')
+ if len(dirs) < 2:
+ continue
+
+ if file.endswith('terragrunt.hcl') or file.endswith('providers.hcl'):
+ logging.debug(
+ "%s: Found tf file: %s",
+ inspect.currentframe().f_code.co_name,
+ os.path.join(root, file)
+ )
+ hcl_files.append(os.path.join(root, file))
+
+ return hcl_files
+
+
+def find_orgs_from_filenames(hcl_files, index_of_key=5)->dict:
+ """ Find all orgs given a set of terragrunt.hcl file paths
+
+ Args:
+ hcl_files (list): A list of terragrunt.hcl file paths
+ index_of_key (int): The index of the Org name in the path. Default is 5
+ Returns:
+ dict: A dictionary with the org name as the key and a list of paths
+ to the terragrunt.hcl files as the value
+ """
+ names = {}
+ for file in hcl_files:
+ dirs = file.split('/')
+ # Add a key/value pair of org name / path to the hcl file
+ # The key is the name of the 3rd dir from the root
+ org_name = dirs[index_of_key]
+ if org_name not in names:
+ names[org_name] = []
+ names[org_name].append(file)
+
+ return names
+
+
+def find_managed_repos()->dict:
+ """ Find all public and private repos managed by GHF
+
+ Searches for repos belonging to any org
+ Returns:
+ dict: A dictionary with two keys, `public` and `private`, each containing a list of repos
+ """
+ hcl_files = find_terragrunt_hcl_files()
+ org_files = find_orgs_from_filenames(hcl_files)
+ repos = {}
+ repos['public'] = []
+ repos['private'] = []
+ for org, files in org_files.items():
+ for file in files:
+ logging.debug("%s: Org: %s\tFile: %s", inspect.currentframe().f_code.co_name, org, file)
+ with open(file, 'r', encoding='utf-8') as f:
+ data = hcl2.load(f)
+ if 'inputs' in data:
+ if 'public_repositories' in data['inputs']:
+ for repo_name, repo_details in data['inputs']['public_repositories'].items():
+ repos['public'].append({
+ 'org': org,
+ 'name': repo_name,
+ })
+ if 'private_repositories' in data['inputs']:
+ # iterate over private repos and add them to the list, along
+ # with the value of the `advance_security` key
+ for repo_name, repo_details in data['inputs']['private_repositories'].items():
+ advance_security = repo_details.get('advance_security', False)
+ repos['private'].append({
+ 'org': org,
+ 'name': repo_name,
+ 'advance_security': advance_security
+ })
+ return repos
+
+
+def find_managed_orgs()->list:
+ """ Find all orgs managed by GHF
+
+ Searches for all terragrunt.hcl files in the organizations directory
+ Returns:
+ list: A list of org names
+ """
+ orgs = []
+ hcl_files = find_terragrunt_hcl_files(providers_dir)
+
+ for file in hcl_files:
+ with open(file, 'r', encoding='utf-8') as f:
+ logging.debug("%s: Reading file: %s", inspect.currentframe().f_code.co_name, file)
+ data = hcl2.load(f)
+ if 'locals' in data:
+ if 'organization_name' in data['locals'][0]:
+ logging.debug(
+ "%s: Found org: %s",
+ inspect.currentframe().f_code.co_name,
+ data['locals'][0]['organization_name']
+ )
+ orgs.append(data['locals'][0]['organization_name'])
+
+ logging.debug(
+ "%s: Found %i orgs",
+ inspect.currentframe().f_code.co_name,
+ len(orgs)
+ )
+ return orgs
+
+
+def find_ghas_eligible_repos()->list:
+ """ Find all public repos or repos with GHAS enabled
+
+ Returns a list of all public repos and private repos with GHAS enabled.
+ """
+ repos = find_managed_repos()
+ return filter_repos_without_ghas_enabled(repos)
+
+
+def filter_repos_without_ghas_enabled(repos)->list:
+ """ Given a list of repos, filter out the ones without GHAS eligible """
+
+ repos_with_ghas = []
+ # append all public repos, since they are enabled by default
+ for repo in repos['public']:
+ repos_with_ghas.append(f"{repo['org']}/{repo['name']}")
+
+ for repo in repos['private']:
+ if repo['advance_security']:
+ repos_with_ghas.append(f"{repo['org']}/{repo['name']}")
+ return repos_with_ghas
+
+
+if __name__ == '__main__':
+ logging.getLogger().setLevel(logging.DEBUG)
+
+ parser = argparse.ArgumentParser(description="Run commands on GHF entities")
+
+ parser.add_argument(
+ '--ghas',
+ action='store_true',
+ dest='ghas',
+ required=False,
+ help='Find all public repos, or repos with GHAS enabled'
+ )
+ parser.add_argument(
+ '--orgs',
+ action='store_true',
+ dest='orgs',
+ required=False,
+ help='Find all orgs managed by GHF'
+ )
+
+
+ known_args, others = parser.parse_known_args(sys.argv)
+
+ if known_args.ghas:
+ ghas_repos = find_ghas_eligible_repos()
+ print(ghas_repos)
+ if known_args.orgs:
+ managed_orgs = find_managed_orgs()
+ print(managed_orgs)
diff --git a/organizations/.github/workflows/ghas-policy-check.yaml b/organizations/.github/workflows/ghas-policy-check.yaml
index 3d2adfc..1a6c630 100644
--- a/organizations/.github/workflows/ghas-policy-check.yaml
+++ b/organizations/.github/workflows/ghas-policy-check.yaml
@@ -21,80 +21,10 @@ jobs:
- name: Checkout the GitHub Foundations repository
uses: actions/checkout@v4
- - name: Create a python script to parse terragrunt.hcl files
- run: |
- cat << 'EOF' > parse_terragrunt_hcl.py
- import os
- import hcl2
-
- def parse_terragrunt_hcl_files(root_dir='./projects'):
- hcl_files = {}
-
- for root, _, files in os.walk(root_dir):
- for file in files:
- # ignore file in the .terragrunt-cache directory
- if '.terragrunt-cache' in root:
- continue
-
- dirs = root.split('/')
- if(len(dirs) < 2):
- continue
- if file.endswith('terragrunt.hcl'):
- # Add a key/value pair of org name / path to the hcl file
- # The key is the name of the 3rd dir from the root
- org_name = dirs[3]
- if org_name not in hcl_files:
- hcl_files[org_name] = []
- hcl_files[org_name].append(os.path.join(root, file))
- return hcl_files
-
- def find_repos_in_terragrunt_hcl_files():
- hcl_files = parse_terragrunt_hcl_files()
- repos = {}
- repos['public'] = []
- repos['private'] = []
- for org in hcl_files:
- for file in hcl_files[org]:
- with open(file, 'r') as f:
- data = hcl2.load(f)
- if 'inputs' in data:
- if 'public_repositories' in data['inputs']:
- for repo_name, repo_details in data['inputs']['public_repositories'].items():
- repos['public'].append({
- 'org': org,
- 'name': repo_name,
- })
- if 'private_repositories' in data['inputs']:
- # iterate over private repos and add them to the list, along
- # with the value of the `advance_security` key
- for repo_name, repo_details in data['inputs']['private_repositories'].items():
- advance_security = repo_details.get('advance_security', False) # Handle missing key with default
- repos['private'].append({
- 'org': org,
- 'name': repo_name,
- 'advance_security': advance_security
- })
- return filter_repos_without_ghas_enabled(repos)
-
- def filter_repos_without_ghas_enabled(repos):
- repos_with_ghas = []
- # append all public repos, since they are enabled by default
- for repo in repos['public']:
- repos_with_ghas.append(f"{repo['org']}/{repo['name']}")
-
- for repo in repos['private']:
- if repo['advance_security'] == True:
- repos_with_ghas.append(f"{repo['org']}/{repo['name']}")
- return repos_with_ghas
-
- if __name__ == '__main__':
- print(find_repos_in_terragrunt_hcl_files())
- EOF
-
- name: Run the python script to parse terragrunt.hcl files
id: repo_list
run: |
- repos=$(python parse_terragrunt_hcl.py)
+ repos=$(python ${{ github.workspace }}/.github/scripts/gh_foundations/gh_foundations.py --ghas)
echo -e "Found repos: $repos"
echo "repos=$(echo -e "${repos}" | sed s/\'/\"/g)" >> $GITHUB_OUTPUT
diff --git a/organizations/.github/workflows/package-audit-logs.yaml b/organizations/.github/workflows/package-audit-logs.yaml
new file mode 100644
index 0000000..038f974
--- /dev/null
+++ b/organizations/.github/workflows/package-audit-logs.yaml
@@ -0,0 +1,64 @@
+name: Package Audit Logs
+
+on:
+ schedule:
+ - cron: "30 3 * * *"
+ workflow_dispatch:
+
+env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+jobs:
+ find-orgs:
+ runs-on: ubuntu-latest
+ outputs:
+ orgs: ${{ steps.find-orgs-step.outputs.orgs }}
+ steps:
+ - name: Checkout the GitHub Foundations repository
+ uses: actions/checkout@v4
+
+ - name: Install HCL python library
+ run: pip install python-hcl2
+
+ - name: Find Orgs
+ id: find-orgs-step
+ run: |
+ orgs=$(python ${{ github.workspace }}/.github/scripts/gh_foundations/gh_foundations.py --orgs)
+ echo -e "Found orgs: $orgs"
+ echo "orgs=$(echo -e "${orgs}" | sed s/\'/\"/g)" >> $GITHUB_OUTPUT
+
+ package-audit-logs:
+ runs-on: ubuntu-latest
+ needs: find-orgs
+ permissions:
+ actions: read
+ contents: write
+ id-token: write
+ strategy:
+ matrix:
+ org: ${{ fromJson(needs.find-orgs.outputs.orgs) }}
+ steps:
+ - name: Checkout the GitHub Foundations repository
+ uses: actions/checkout@v4
+
+ - name: Get the GitHub token
+ id: generate_token
+ uses: FociSolutions/github-foundations/organizations/.github/actions/get-gh-token-gcp@main
+ with:
+ repo_name: "${{ matrix.org }}/"
+ gcp_service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
+ workload_identity_provider: ${{ secrets.WORKLOAD_IDENTITY_PROVIDER }}
+
+ - name: Download Audit Logs
+ id: download-audit-logs
+ run: |
+ # Get today's date, and take only yesterday's logs
+ yesterday=$(date -d "yesterday" '+%Y-%m-%d')
+ curl -H "Authorization: token ${{ steps.generate_token.outputs.token }}" https://api.github.com/orgs/${{ matrix.org }}/audit-log?phrase=created:${yesterday} > audit-log-${yesterday}.json
+ echo "logfile=audit-log-${yesterday}.json" >> $GITHUB_OUTPUT
+
+ - name: Package Audit Logs
+ uses: actions/upload-artifact@v4
+ with:
+ name: ${{ matrix.org }}-${{ steps.download-audit-logs.outputs.logfile }}
+ path: ${{ steps.download-audit-logs.outputs.logfile }}