id: gcloud-service-account-keys-rotation

info:
  name: GCP Service Account Keys - No Rotation Configured
  author: kelu27
  severity: high
  description: |
    Detects Google Cloud Platform (GCP) service account keys that have no rotation enabled.
    Keys with an expiration date of 9999-12-31T23:59:59 are considered non-rotating and pose security risks if compromised.
  impact: |
    Service account keys without rotation can remain valid indefinitely, making them vulnerable to compromise or misuse if leaked, stolen, or improperly secured.
  remediation: |
    Implement a key rotation policy for user-managed service account keys. Regularly rotate keys and delete old ones. Consider using Workload Identity Federation to eliminate the need for long-lived keys entirely.
  reference:
    - https://cloud.google.com/iam/docs/understanding-service-accounts
    - https://cloud.google.com/iam/docs/best-practices-for-securing-service-accounts
    - https://cloud.google.com/iam/docs/key-rotation
  metadata:
    max-request: 3
  tags: cloud,devops,gcp,gcloud,iam,google-cloud-iam,gcp-cloud-config,security,rotation

flow: |
  code(1)
  for(let projectId of iterate(template.projectIds)){
    set("projectId", projectId)
    code(2)
    for(let email of iterate(template.emails)){
      set("email", email)
      code(3)
    }
  }

self-contained: true

code:
  - engine:
      - sh
      - bash
    source: |
      gcloud projects list --format="json(projectId)"

    extractors:
      - type: json
        name: projectIds
        internal: true
        json:
          - ".[].projectId"

  - engine:
      - sh
      - bash
    source: |
      gcloud iam service-accounts list --project $projectId --format="json(email)"

    extractors:
      - type: json
        name: emails
        internal: true
        json:
          - ".[].email"

  - engine:
      - sh
      - bash
    source: |
      gcloud iam service-accounts keys list --iam-account=$email --format="json"

    matchers:
      - type: word
        words:
          - "9999-12-31T23:59:59"

    extractors:
      - type: dsl
        dsl:
          - '"Service Account Key without Rotation Found in Service Account " + email + " in project " + projectId'
# digest: 4a0a0047304502204623d9adc6a13d65071f0594fa0b3d7fa5e896ca090bf8fa9839d929ade0c112022100d60606906dc75634017a16226765ffff6e9425c77da34ba19fa3b5566826259e:922c64590222798bb761d5b6d8e72950