From 3f3bcc48b5ce83b946723ad04b7ed3c58bee8c18 Mon Sep 17 00:00:00 2001 From: gearnode Date: Tue, 14 Jan 2025 16:43:15 +0100 Subject: [PATCH] Add COR.INF controls Signed-off-by: gearnode --- .../infra/COR.INF.001_list_your_assets.md | 53 +++++ .../COR.INF.002_scan_security_updates.md | 190 ++++++++++++++++++ ...INF.003_iam_authentication_for_database.md | 57 ++++++ .../infra/COR.INF.004_short_live_auth_ci.md | 88 ++++++++ .../COR.INF.005_manage_service_account.md | 34 ++++ ...006_keep_an_history_of_all_your_changes.md | 36 ++++ .../src/COR.SRC.001.patch_review.md} | 7 +- .../src/COR.SRC.002.enable_code_scanning.md} | 7 +- ...RC.003.dependancy_vulnerability_alerts.md} | 7 +- ...SRC.004.systems_development_life_cycle.md} | 7 +- 10 files changed, 478 insertions(+), 8 deletions(-) create mode 100644 controls/core/infra/COR.INF.001_list_your_assets.md create mode 100644 controls/core/infra/COR.INF.002_scan_security_updates.md create mode 100644 controls/core/infra/COR.INF.003_iam_authentication_for_database.md create mode 100644 controls/core/infra/COR.INF.004_short_live_auth_ci.md create mode 100644 controls/core/infra/COR.INF.005_manage_service_account.md create mode 100644 controls/core/infra/COR.INF.006_keep_an_history_of_all_your_changes.md rename controls/{code/COD.001.patch_review.md => core/src/COR.SRC.001.patch_review.md} (92%) rename controls/{code/COD.002.enable_code_scanning.md => core/src/COR.SRC.002.enable_code_scanning.md} (89%) rename controls/{code/COD.003.dependancy_vulnerability_alerts.md => core/src/COR.SRC.003.dependancy_vulnerability_alerts.md} (88%) rename controls/{code/COD.004.systems_development_life_cycle.md => core/src/COR.SRC.004.systems_development_life_cycle.md} (85%) diff --git a/controls/core/infra/COR.INF.001_list_your_assets.md b/controls/core/infra/COR.INF.001_list_your_assets.md new file mode 100644 index 000000000..232840bb4 --- /dev/null +++ b/controls/core/infra/COR.INF.001_list_your_assets.md @@ -0,0 +1,53 @@ +--- +id: "COR.INF.001" +category: "core/infra" +revision-version: 1 +revision-date: "2024-01-14" +estimate-time: "1h" +necessity: "mandatory" +frameworks: + - name: "soc2" + sections: ["CC2.1", "CC4.1"] +--- + +# List of your Assets + +## Purpose + +The assets that are storing or processing data are potential vulnerabilities +that could be exploited. ⇒ You need to know which assets your company has in +order to be able to properly manage and secure them. + +## Implementation + +If you don’t have one, create an inventory of all your assets that have the +potential to store or process data. This inventory should include: + +- description of the device +- location +- owner +- operating status + +### Google Cloud Platform + +GCP Asset inventory can fulfil this for you if you implement it with systematic +tracking and monitoring: + +1. Go to the **GCP console** and enable **Cloud Asset Inventory API** +2. Navigate to **API & Services** section, and enable **Cloud Asset API** for + the relevant projects +3. Identify which assets you want to monitor. You should include (if relevant): + 1. Compute instances (e.g., VMs) + 2. Storage (e.g., Cloud Storage Buckets) + 3. Networking components (e.g., firewalls) + 4. IAM policies and permissions + 5. Encryption keys (Cloud KMS) + 6. Logging (Cloud Audit Logs) +4. Set up **automatic collection** of assets using **GCP Cloud Scheduler** or + **GCP Cloud Functions** to regularly query and capture inventory snapshots + (that way you can maintain a record of changes) OR use glcoud commands/API + calls: `gcloud asset search-all-resources --scope=projects/your-project-id` + +## Evidence + +- Screenshot of your GCP asset inventory list diff --git a/controls/core/infra/COR.INF.002_scan_security_updates.md b/controls/core/infra/COR.INF.002_scan_security_updates.md new file mode 100644 index 000000000..b886f4c77 --- /dev/null +++ b/controls/core/infra/COR.INF.002_scan_security_updates.md @@ -0,0 +1,190 @@ +--- +id: "COR.INF.002" +category: "core/infra" +revision-version: 1 +revision-date: "2024-01-08" +estimate-time: "1h" +necessity: "mandatory" +frameworks: + - name: "soc2" + sections: ["CC4.1", "CC6.8", "CC7.1"] +--- + +# Scan for security updates + +## Purpose + +An automated security scanning software on your infrastructure components +enables you to fix potential vulnerabilities as soon as they are uncovered. + +## Implementation + +### 1/2 - Enable GCP security + +1. Log in to your **Google Cloud Platform** account and navigate to the + **Security Command Center**. +2. Click **Enable** to activate the Security Command Center for your project or + organization. +3. If other members of your team need access, go to **IAM & Admin** > **IAM** + and assign to them the appropriate roles (**Security Center Admin** or + **Viewer**) +4. In the **Security Command Center dashboard**, look for **Security sources** + and click **Configure** or **Manage Sources**: + - **Asset Inventory**: Enables continuous tracking of assets within your GCP + project or organization. + - **Security Health Analytics**: Automatically scans your resources for + common vulnerabilities and misconfigurations. + - **Event Threat Detection**: Monitors your logs for suspicious activity and + potential threats. + - **Web Security Scanner**: Scans your public-facing web applications for + known vulnerabilities. +5. For each service you want to enable, click on it and follow the prompts to + activate it. Configure any necessary settings, such as defining which + resources should be scanned or monitored. +6. Integrate with other GCP services, such as **Cloud Logging** and **Cloud + Monitoring,** to collect detailed logs and metrics. +7. Save to update your settings. Verify that each service is active on the + Security Sources page. + +### 2/3 - Enable Artifact registry + + + +1. Log in to your **Google Cloud Platform** account and navigate to **Artifact + Registry** under **Storage**. +2. Click **Enable API** +3. If other team members need access, go to **IAM & Admin** > **IAM** and assign + them appropriate roles: + - **Artifact Registry Admin**: Full access to manage repositories and + artifacts. + - **Artifact Registry Writer**: Permission to push artifacts to repositories. + - **Artifact Registry Reader**: Read-only access to repositories. +4. In **Artifact Registry**, click **Create Repository** and configure the + repository: + - **Name**: Set a name for your repository. + - **Location**: Choose a region or multi-region where the artifacts will be + stored. + - **Format**: Select the artifact type (e.g., Docker, npm, Maven). + - Enable **Continuous Scanning** to automatically scan for known + vulnerabilities in container images. +5. Click **Create** +6. For Docker images, run the following command to configure Docker + authentication with `gcloud`: (For other formats like **npm** or **Maven**, + follow the instructions in the **Setup instructions** section of your + repository). + + ```bash + gcloud auth configure-docker + ``` + +7. Push artifacts to your repository: + - For Docker: + ```bash + docker tag IMAGE_NAME LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY_NAME/IMAGE_NAME + docker push LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY_NAME/IMAGE_NAME + ``` + - For other formats, use the respective package manager (e.g., `npm publish`, + `mvn deploy`). +8. Verify your repository by navigating to **Artifact Registry > Repositories**, + and confirm that the uploaded artifacts appear in the repository. + +### 3/3 - Implement alerts in Slack + +1. Navigate to **Pub/Sub, c**lick **Create Topic**, give it a name (e.g., + `security-artifact-alerts`) and click **Create** +2. On the topic you created, click **Create Subscription**, choose a name for + the subscription (e.g., `security-artifact-alerts-subscription`), and choose + **Pull** as the delivery type.. +3. Go to the **Security Command Center**, click on **Settings** or + **Notifications**, choose **Create Notification**, provide a name for the + notification (e.g., `critical-findings-notification`) and select the + **resource type** (**Project** or **Organization**) to scope the + notification. +4. Define conditions for sending notifications, such as: + + - **Severity** (e.g., only send alerts for high or critical severity + findings). + - **Finding types** (e.g., vulnerability detection, unauthorized access + attempts). + + Use filters like: + + ```json + severity="CRITICAL" + ``` + +5. Choose the **Pub/Sub topic** you created (`security-artifact alerts`) and + confirm the connection by allowing **Security Command Center** to publish to + this topic. +6. Go to **Artifact Registry** > **Repositories** and select a repository. + Navigate to **Settings** > **Notifications**. +7. Click **Add Notification** and select relevant event types: + - **Vulnerability Findings** + - **Failed Artifact Uploads** + - **Unauthorized Access** +8. Link this notification to the same **Pub/Sub topic** + (`security-artifact-alerts`). +9. Go to Slack API and click **Create New App**. Choose **From scratch**, name + the app and select your workspace. +10. In the app settings, go to **Incoming Webhooks** and toggle the switch to + **Activate Incoming Webhooks**. Click **Add New Webhook to Workspace** and + choose the channel where you want to post alerts. Copy the **Webhook URL** + provided after adding it - you will use it on GCP. +11. Go to **OAuth & Permissions** in the app settings and add the required + scope: `chat:write` and `incoming-webhook` +12. Send a test message to the channel using the **Webhook URL**: + +```bash +curl -X POST -H 'Content-type: application/json' --data '{"text":"Test alert from GCP Security and Artifact"}' YOUR_SLACK_WEBHOOK_URL +``` + +1. Go to **Cloud Functions** in **Google Cloud Console**, click **Create + Function** and provide a name (e.g., `send-alerts-to-slack`), choose + **Trigger type** as **Pub/Sub** and select your topic + (`security-artifact-alerts`). Set the runtime environment to **Python.** +2. Use the following example code to forward alerts to Slack: (replace + `YOUR_SLACK_WEBHOOK_URL` with your Slack incoming webhook URL) + +```python +import base64 +import json +import requests + +def send_alert_to_slack(event, context): + # Decode the Pub/Sub message + pubsub_message = base64.b64decode(event['data']).decode('utf-8') + alert = json.loads(pubsub_message) + + # Prepare the Slack webhook URL and message format + slack_webhook_url = 'YOUR_SLACK_WEBHOOK_URL' # <= To replace + message = { + 'text': f"New Alert: {alert.get('finding', 'No details')} - Severity: {alert.get('severity', 'Unknown')} - Type: {alert.get('eventType', 'Unknown')}" + } + + # Send the alert to Slack + response = requests.post(slack_webhook_url, json=message) + + if response.status_code != 200: + raise ValueError(f"Request to Slack returned an error {response.status_code}, the response is: {response.text}") +``` + +1. Set the entry point to `send_alert_to_slack` and deploy the function (wait + for it to activate). +2. Generate a test alert or monitor new alerts in **Security Command Center** to + verify that alerts are sent to your Slack channel. + - For Security Command Center: Simulate a high-severity finding. + - For Artifact Registry: Upload a vulnerable artifact or simulate + unauthorized access. + +## Evidence + +- Screenshot of GCP Security enabled on your project +- Screenshot of GCP Security enabled on your registry +- Screenshot of Artifact Registry enabled on your registry +- Screenshot of an alert received OR of its configuration diff --git a/controls/core/infra/COR.INF.003_iam_authentication_for_database.md b/controls/core/infra/COR.INF.003_iam_authentication_for_database.md new file mode 100644 index 000000000..cb015306c --- /dev/null +++ b/controls/core/infra/COR.INF.003_iam_authentication_for_database.md @@ -0,0 +1,57 @@ +--- +id: "COR.INF.003" +category: "core/infra" +revision-version: 1 +revision-date: "2024-01-08" +estimate-time: "1h" +necessity: "mandatory" +frameworks: + - name: "soc2" + sections: ["CC6.1"] +--- + +# IAM for database authentication + +## Purpose + +You want to ensure that only the proper people can access your production +database. You also want to avoid the burden of managing another list of users or +rotating credentials. + +## Implementation + +### **Set Up Custom IAM Roles for Database Access** + +1. In **Google Cloud Console**, go to **IAM & Admin** > **Roles**. +2. Click **Create Role** and define a custom role with only the necessary + permissions for your database (for a read-only role: + `cloudsql.instances.connect`, `cloudsql.instances.get`) +3. Save the role. + +### **Assign Least Privilege Roles to Users or Service Accounts** + +1. Go to **IAM & Admin** > **IAM** +2. Click **Add** to assign the custom role to specific users or service accounts + that require production database access. +3. In the **New principals** field, enter the email of the user or service + account. +4. Under **Role**, choose the custom role you created. +5. **Save** + +### **Enable IAM Database Authentication (Cloud SQL Only)** + +1. Go to **Cloud SQL** > **Instances** +2. Select your production database instance. +3. Under **Connections**, find the **Database Authentication** section and + enable **IAM database authentication** (allows users with the necessary IAM + roles to authenticate with their IAM credentials). + +### Test access + +1. In **Cloud Audit Logs** (under **Logging** > **Logs Explorer**), search for + `cloudsql.googleapis.com` to view access logs. +2. Verify that access is limited to authorized users. + +## Evidence + +- Screenshot showing IAM is active on your Cloud SQL diff --git a/controls/core/infra/COR.INF.004_short_live_auth_ci.md b/controls/core/infra/COR.INF.004_short_live_auth_ci.md new file mode 100644 index 000000000..dcd762f5b --- /dev/null +++ b/controls/core/infra/COR.INF.004_short_live_auth_ci.md @@ -0,0 +1,88 @@ +--- +id: "COR.INF.004" +category: "core/infra" +revision-version: 1 +revision-date: "2024-01-14" +estimate-time: "1h" +necessity: "mandatory" +frameworks: + - name: "soc2" + sections: ["CC6.1", "CC6.3"] +--- + +# Plug GCP & Github + +## Purpose + +Having credentials to manage can become a nightmare (especially if you need to +change/rotate them often) - it quickly becomes time consuming. It is the same +with lifetime tokens - someone leaving and you need to change them. + +## Implementation + +### **1. Create a Workload Identity Pool in GCP** + +1. In **Google Cloud Console**, go to **IAM & Admin** > **Workload Identity + Federation**. +2. Click **Create Pool**, name it (e.g., `github-pool`), and set a + **description**. +3. Select **Provider type:** **OIDC** (OpenID Connect). +4. Under **Provider details**, enter: **Issuer URL**: + `https://token.actions.githubusercontent.com` +5. Click **Create** to finish setting up the pool. + +### 2. **Create a Workload Identity Provider in the Pool** + +1. In the pool, go to **Providers** and click **Add Provider**. +2. Name the provider (e.g., `github-provider`). +3. Set **Issuer URL** to `https://token.actions.githubusercontent.com`. +4. **Attribute mapping**: Add a mapping to verify the GitHub repository: + 1. `google.subject` → `assertion.sub` + 2. `attribute.repository` → `assertion.repository` + 3. `attribute.ref` → `assertion.ref` + 4. `attribute.owner` → `assertion.repository_owner` +5. Click **Create** to add the provider. + +### 3. **Grant IAM Permissions on GCP** + +1. Go to **IAM & Admin** > **IAM**. +2. Find the GCP service account you want GitHub Actions to use, or create a new + one. +3. Click **Add Principal** and specify the **Workload Identity Pool** (in the + format: + `principal://iam.googleapis.com/projects/PROJECT_ID/locations/global/workloadIdentityPools/POOL_ID/attribute.repository/OWNER/REPO`). +4. Assign the necessary **roles** (e.g., `Viewer`, `Editor`) to allow access to + resources. + +### 4. **Configure GitHub Actions to Use Workload Identity** + +1. In your **GitHub repository**, go to **Settings** > **Secrets and + variables** > **Actions**. +2. Add a new secret (e.g., `GCP_WORKLOAD_IDENTITY_PROVIDER`) containing the GCP + **Workload Identity Provider** details. + +### 5. **Set Up GitHub Actions Workflow** + +- In your **GitHub Actions workflow YAML file** (e.g., + `.github/workflows/deploy.yml`), add steps to authenticate: + ```yaml + jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Configure Google Cloud authentication + uses: google-github-actions/auth@v0 + with: + workload_identity_provider: + ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }} + service_account: YOUR_GCP_SERVICE_ACCOUNT_EMAIL + - name: Run GCP commands + run: gcloud projects list + ``` + +This setup enables secure, temporary access from **GitHub Actions** to **GCP** +resources without needing to store long-term credentials. + +## Evidence + +- Screenshot of your Github actions workflow. diff --git a/controls/core/infra/COR.INF.005_manage_service_account.md b/controls/core/infra/COR.INF.005_manage_service_account.md new file mode 100644 index 000000000..8f9a2dffd --- /dev/null +++ b/controls/core/infra/COR.INF.005_manage_service_account.md @@ -0,0 +1,34 @@ +--- +id: "COR.INF.005" +category: "core/infra" +revision-version: 1 +revision-date: "2024-01-14" +estimate-time: "30m" +necessity: "mandatory" +frameworks: + - name: "soc2" + sections: ["CC6.3"] +--- + +# Manage your service accounts + +## Purpose + +You don’t want to use the “default” service account, it has way too many +permissions - it is a super administrator. Even GCP is asking you not to use it, +it is only here for legacy reasons. In the same idea, grant your service +accounts only what is necessary. + +## Implementation + +### Google Cloud Platform + +1. Make sure the default service account is not used by any service - if it is + the case, create a new service account (with only View and/or Edit + permission) and use it. +2. Make sure all your service accounts are only Viewer or Editor - you shouldn’t + have any admin or owner. +3. Delete the default service account if not used anymore + +Note: if you have IaC, it does make sense to have a service account as Admin, +but except in this kind of specific case: no admin diff --git a/controls/core/infra/COR.INF.006_keep_an_history_of_all_your_changes.md b/controls/core/infra/COR.INF.006_keep_an_history_of_all_your_changes.md new file mode 100644 index 000000000..59ecbf01d --- /dev/null +++ b/controls/core/infra/COR.INF.006_keep_an_history_of_all_your_changes.md @@ -0,0 +1,36 @@ +--- +id: "COR.INF.006" +category: "core/infra" +revision-version: 1 +revision-date: "2024-01-14" +estimate-time: "1h" +necessity: "mandatory" +frameworks: + - name: "soc2" + sections: ["CC5.3", "CC7.1", "CC7.2", "CC8.1"] +--- + +# Keep an history of all your changes + +## Purpose + +Infrastructure as Code (IaC) makes sure all your infrastructure changes are done +in a standardized and repeatable process - the chance of human error is lower. +Moreover, IaC enables version control and peer reviews. When growing, you will +have to do it - the earlier the better (later, it can become really painful). + +## Implementation + +**Option 1:** If you don’t want an IaC, in the evidence section, provide a +screenshot of some log of your infrastructure changes + +**Option 2:** If you already have an IaC, go directly to the evidence section, +we only need a screenshot. + +**Option 3:** If you don’t have one, we recommend Terraform - the documentation +is available [here](https://developer.hashicorp.com/terraform/tutorials). + +## Evidence + +- Screenshot showing some logs +- Screenshot of the query you are performing in GCP to see your logs diff --git a/controls/code/COD.001.patch_review.md b/controls/core/src/COR.SRC.001.patch_review.md similarity index 92% rename from controls/code/COD.001.patch_review.md rename to controls/core/src/COR.SRC.001.patch_review.md index 84c5129bb..51d3d6aff 100644 --- a/controls/code/COD.001.patch_review.md +++ b/controls/core/src/COR.SRC.001.patch_review.md @@ -1,14 +1,17 @@ --- -id: "COD-001" -category: "code" +id: "COR.SRC.001" +category: "core/src" revision-version: 1 revision-date: "2024-01-07" estimate-time: "15m" +necessity: "mandatory" frameworks: - name: "soc2" sections: ["CC1.4", "CC5.2", "CC8.1"] --- +# Code Review + ## Purpose Requiring pull requests and code reviews ensures higher code quality and diff --git a/controls/code/COD.002.enable_code_scanning.md b/controls/core/src/COR.SRC.002.enable_code_scanning.md similarity index 89% rename from controls/code/COD.002.enable_code_scanning.md rename to controls/core/src/COR.SRC.002.enable_code_scanning.md index c42d74a39..b80475191 100644 --- a/controls/code/COD.002.enable_code_scanning.md +++ b/controls/core/src/COR.SRC.002.enable_code_scanning.md @@ -1,14 +1,17 @@ --- -id: "COD-002" -category: "code" +id: "COR.SRC.002" +category: "core/src" revision-version: 1 revision-date: "2024-01-07" estimate-time: "15m" +necessity: "optional" frameworks: - name: "soc2" sections: ["CC4.1", "CC8.1"] --- +# Configure Code Scanning + ## Purpose It ensures that potential security flaws are detected early. This proactive diff --git a/controls/code/COD.003.dependancy_vulnerability_alerts.md b/controls/core/src/COR.SRC.003.dependancy_vulnerability_alerts.md similarity index 88% rename from controls/code/COD.003.dependancy_vulnerability_alerts.md rename to controls/core/src/COR.SRC.003.dependancy_vulnerability_alerts.md index c60781489..4bc183d41 100644 --- a/controls/code/COD.003.dependancy_vulnerability_alerts.md +++ b/controls/core/src/COR.SRC.003.dependancy_vulnerability_alerts.md @@ -1,14 +1,17 @@ --- -id: "COD-003" -category: "code" +id: "COR.SRC.003" +category: "core/src" revision-version: 1 revision-date: "2024-01-07" estimate-time: "15m" +necessity: "mandatory" frameworks: - name: "soc2" sections: ["CC4.1", "CC8.1"] --- +# Configure Dependancy Vulnerability Alerts + ## Purpose It ensures your project stays secure and up-to-date without manual tracking of diff --git a/controls/code/COD.004.systems_development_life_cycle.md b/controls/core/src/COR.SRC.004.systems_development_life_cycle.md similarity index 85% rename from controls/code/COD.004.systems_development_life_cycle.md rename to controls/core/src/COR.SRC.004.systems_development_life_cycle.md index d804961b4..63bf2e348 100644 --- a/controls/code/COD.004.systems_development_life_cycle.md +++ b/controls/core/src/COR.SRC.004.systems_development_life_cycle.md @@ -1,14 +1,17 @@ --- -id: "COD-004" -category: "code" +id: "COR.SRC.004" +category: "core/src" revision-version: 1 revision-date: "2024-01-08" estimate-time: "1h" +necessity: "mandatory" frameworks: - name: "soc2" sections: ["CC1.4", "CC5.2", "CC8.1"] --- +# Document your Development Lifecycle + ## Purpose Formalizing a proper development lifecycle helps your engineer in their jobs and