Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions skills/cloud/gcp-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ The CIS Google Cloud Platform Foundation Benchmark v2.0.0 is a consensus-driven
- Access to GCP infrastructure-as-code files (Terraform `.tf`, Deployment Manager `.yaml`/`.jinja`)
- gcloud CLI output or configuration exports (if reviewing a live environment)
- IAM policy bindings and org policy definitions
- Workload Identity Federation pools, providers, external principal bindings, and CI/OIDC trust policy definitions
- VPC and firewall rule definitions
- Cloud Audit Logs configuration

Expand Down Expand Up @@ -100,7 +101,7 @@ Produce the final report using the structure defined in the Output Format sectio
| Severity | Definition | Examples |
|----------|-----------|----------|
| **Critical** | Immediate risk of data breach or unauthorized access | Public GCS buckets, firewall rules allowing 0.0.0.0/0 on SSH/RDP, Cloud SQL with public IP and no SSL, user-managed SA keys with admin roles |
| **High** | Significant security gap that materially weakens posture | Default service accounts with broad scopes, missing Cloud Audit Logs, no VPC flow logs, instances with public IPs |
| **High** | Significant security gap that materially weakens posture | Default service accounts with broad scopes, missing Cloud Audit Logs, no VPC flow logs, instances with public IPs, broad Workload Identity Federation principal sets |
| **Medium** | Control gap that should be addressed in normal cycle | Missing log metric filters, DNSSEC not enabled, Shielded VM not enabled, uniform bucket access not set |
| **Low** | Hardening recommendation or defense-in-depth measure | OS Login not enabled, serial port access not explicitly disabled, BigQuery tables without CMEK |
| **Informational** | Best practice observation, no direct security impact | Default network still exists (non-production), naming conventions, documentation gaps |
Expand Down Expand Up @@ -138,6 +139,16 @@ Produce the final report using the structure defined in the Output Format sectio
| 6 | Cloud SQL | X | Y | Z | nn% |
| 7 | BigQuery | X | Y | Z | nn% |

### Identity Federation Evidence

| Control Area | Status | Evidence Reviewed | Risk Notes |
|---|---|---|---|
| WIF provider issuer and audience | Pass / Fail / Not Evaluable | `<provider config>` | `<notes>` |
| Attribute mapping and condition | Pass / Fail / Not Evaluable | `<attribute_mapping / attribute_condition>` | `<notes>` |
| Service account impersonation binding scope | Pass / Fail / Not Evaluable | `<google_service_account_iam_member>` | `<notes>` |
| External principal TokenCreator grants | Pass / Fail / Not Evaluable | `<IAM binding>` | `<notes>` |
| CI workload claim binding | Pass / Fail / Not Evaluable | `<workflow / OIDC claims>` | `<notes>` |

### Detailed Findings

#### [CIS X.Y] <Recommendation Title>
Expand Down Expand Up @@ -190,10 +201,11 @@ Produce the final report using the structure defined in the Output Format sectio

1. **Missing org-level policy checks.** Many CIS controls (e.g., 3.1 default network, 5.1 public access) can be enforced via org policies. Check both resource-level configuration and org policy constraints.
2. **Confusing GCP-managed vs. user-managed service account keys.** CIS 1.4 only flags user-managed keys (created via `google_service_account_key`). Keys automatically managed by GCP services are acceptable.
3. **VPC flow logs must be per-subnet.** CIS 3.8 requires flow logs on every subnet, not just the VPC. Each `google_compute_subnetwork` must have a `log_config` block.
4. **Cloud SQL authorized_networks vs. private IP.** CIS 6.5 flags `0.0.0.0/0` in authorized networks, but CIS 6.6 goes further and recommends disabling public IP entirely in favor of private networking.
5. **BigQuery dataset-level vs. table-level CMEK.** CIS 7.2 checks table-level encryption, while CIS 7.3 checks the dataset default. Both should be evaluated independently.
6. **Default compute service account identification.** The default SA follows the pattern `PROJECT_NUMBER-compute@developer.gserviceaccount.com`. Grep for this pattern, not just the string "default."
3. **Treating Workload Identity Federation as automatically safe.** WIF removes long-lived keys, but broad `principalSet` members, missing `attribute_condition`, or project-level impersonation roles can create a keyless privilege escalation path.
4. **VPC flow logs must be per-subnet.** CIS 3.8 requires flow logs on every subnet, not just the VPC. Each `google_compute_subnetwork` must have a `log_config` block.
5. **Cloud SQL authorized_networks vs. private IP.** CIS 6.5 flags `0.0.0.0/0` in authorized networks, but CIS 6.6 goes further and recommends disabling public IP entirely in favor of private networking.
6. **BigQuery dataset-level vs. table-level CMEK.** CIS 7.2 checks table-level encryption, while CIS 7.3 checks the dataset default. Both should be evaluated independently.
7. **Default compute service account identification.** The default SA follows the pattern `PROJECT_NUMBER-compute@developer.gserviceaccount.com`. Grep for this pattern, not just the string "default."

---

Expand Down
93 changes: 93 additions & 0 deletions skills/cloud/gcp-review/benchmark-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,99 @@ These roles should be granted at the service account level, not project level.

Check for key rotation mechanisms or expiration policies on service account keys.

### Supplemental IAM Check -- Workload Identity Federation and External OIDC Boundaries

Workload Identity Federation (WIF) is preferred over long-lived service account keys, but an overly broad federation policy can let external workloads impersonate service accounts without a key. Treat WIF as an identity boundary that needs explicit provider, attribute, and service-account binding evidence.

**Grep patterns:**

```
# Workload Identity Federation provider resources
google_iam_workload_identity_pool_provider
workload_identity_pool_provider
attribute_mapping
attribute_condition

# External principals and broad principal sets
principalSet://iam.googleapis.com/.*/attribute.repository/\*
principalSet://iam.googleapis.com/.*/attribute.owner/\*
principal://iam.googleapis.com/
roles/iam.workloadIdentityUser
roles/iam.serviceAccountTokenCreator

# GitHub Actions / CI OIDC providers
issuer_uri = "https://token.actions.githubusercontent.com"
attribute.repository
attribute.ref
attribute.workflow
attribute.actor
```

**Risk patterns:**

```hcl
# BAD: GitHub Actions OIDC provider without repository/ref restriction
resource "google_iam_workload_identity_pool_provider" "github" {
oidc {
issuer_uri = "https://token.actions.githubusercontent.com"
}
attribute_mapping = {
"google.subject" = "assertion.sub"
"attribute.repository" = "assertion.repository"
}
# Missing attribute_condition binding the trusted org/repo/ref/workflow
}

# BAD: Any repository in the provider pool can impersonate the service account
resource "google_service_account_iam_member" "wif" {
service_account_id = google_service_account.deploy.name
role = "roles/iam.workloadIdentityUser"
member = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.pool.name}/attribute.repository/*"
}
```

**Evidence to collect:**

- [ ] Provider issuer is the expected external IdP and uses OIDC/SAML settings appropriate for that IdP.
- [ ] `attribute_mapping` includes stable attributes required for policy decisions, such as `attribute.repository`, `attribute.ref`, `attribute.workflow`, or cloud-specific tenant/application IDs.
- [ ] `attribute_condition` restricts the trusted organization, repository, branch/tag, workflow, audience, or equivalent IdP claims.
- [ ] `roles/iam.workloadIdentityUser` bindings are granted on the target service account, not broadly at project level.
- [ ] `principalSet` members avoid wildcard repository, owner, namespace, or subject patterns unless a documented exception exists.
- [ ] External principals are not also granted `roles/iam.serviceAccountTokenCreator` without a compensating approval and audit trail.
- [ ] Audit logs or CI configuration tie the federated identity to the expected workload, branch, and deployment environment.

**Remediation:**

```hcl
resource "google_iam_workload_identity_pool_provider" "github" {
workload_identity_pool_id = google_iam_workload_identity_pool.ci.workload_identity_pool_id
workload_identity_pool_provider_id = "github-actions"

oidc {
issuer_uri = "https://token.actions.githubusercontent.com"
}

attribute_mapping = {
"google.subject" = "assertion.sub"
"attribute.repository" = "assertion.repository"
"attribute.ref" = "assertion.ref"
"attribute.workflow" = "assertion.workflow"
}

attribute_condition = <<-CEL
assertion.repository == "trusted-org/trusted-repo" &&
assertion.ref == "refs/heads/main" &&
assertion.workflow == "deploy.yml"
CEL
}

resource "google_service_account_iam_member" "github_deploy" {
service_account_id = google_service_account.deploy.name
role = "roles/iam.workloadIdentityUser"
member = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.ci.name}/attribute.repository/trusted-org/trusted-repo"
}
```

### CIS 1.8 -- Ensure that Separation of Duties is Enforced While Assigning Service Account Related Roles to Users

Verify that no user has both `iam.serviceAccountUser` and `iam.serviceAccountAdmin` simultaneously.
Expand Down