Persistence: External Access Granted to Gemini Discovery Engine API Apps

This document describes a threat finding type in Security Command Center. Threat findings are generated by threat detectors when they detect a potential threat in your cloud resources. For a full list of available threat findings, see Threat findings index.

Overview

A principal outside of your organization was granted an IAM role that provides access to Gemini Enterprise AI applications or resources. Findings are classified as Medium severity by default.

This finding is generated when a user, service account, or AI agent outside of your organization is granted any of the following Gemini Enterprise (Discovery Engine) roles:

  • roles/discoveryengine.admin
  • roles/discoveryengine.agentAdmin
  • roles/discoveryengine.agentOwner
  • roles/discoveryengine.agentUser
  • roles/discoveryengine.agentspaceAdmin
  • roles/discoveryengine.agentspaceUser
  • roles/discoveryengine.editor
  • roles/discoveryengine.user

Event Threat Detection is the source of this finding.

How to respond

To respond to this finding, do the following:

Step 1: Review finding details

  1. Open the Persistence: External Access Granted to Gemini Discovery Engine API Apps finding as directed in Reviewing findings. The details panel for the finding opens to the Summary tab.

  2. On the Summary tab, review the information in the following sections:

    • What was detected, especially the following fields:
      • Principal email: the email address for the user or service account that assigned the role.
      • Offending access grants: the details of the Gemini Enterprise roles and external members that were added (iamBindings).
    • Affected resource
    • Related links, especially the following fields:
      • Cloud Logging URI: a link to Logging entries.
      • MITRE ATT&CK method: a link to the MITRE ATT&CK documentation.

Step 2: Check logs

  1. On the Summary tab of the finding details panel, click the Cloud Logging URI link to open the Logs Explorer.
  2. On the page that loads, look for new or updated IAM policy bindings using the following filter:
    • protoPayload.methodName="SetIamPolicy"

Step 3: Research attack and response methods

  1. Review MITRE ATT&CK framework entries for this finding type: Account Manipulation: Additional Cloud Roles.
  2. To develop a response plan, combine your investigation results with MITRE research.

Step 4: Implement your response

The following response plan might be appropriate for this finding, but might also impact operations. Carefully evaluate the information you gather in your investigation to determine the best way to resolve findings.

  1. Contact the owner of the project or resource where the external role grant occurred to verify whether the access was authorized.
  2. Revoke the unauthorized IAM role binding from the external principal.
  3. If the account that granted the role (principalEmail) was compromised, revoke its access or delete the compromised service account and rotate its keys.
  4. To restrict adding external principals to your resources, use the Domain restricted sharing organization policy constraint.

For response recommendations, see Respond to AI threat findings.

Example finding JSON

The following is an example of the finding JSON, with default values omitted.

{
  "finding": {
    "name": "organizations/ORGANIZATION_ID/sources/SOURCE_ID/locations/global/findings/FINDING_ID",
    "parent": "organizations/ORGANIZATION_ID/sources/SOURCE_ID/locations/global",
    "resourceName": "//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER",
    "state": "ACTIVE",
    "category": "Persistence: External Access Granted to Gemini Discovery Engine API Apps",
    "securityMarks": {
      "name": "organizations/ORGANIZATION_ID/sources/SOURCE_ID/locations/global/findings/FINDING_ID/securityMarks"
    },
    "eventTime": "TIMESTAMP",
    "createTime": "TIMESTAMP",
    "severity": "MEDIUM",
    "canonicalName": "projects/PROJECT_NUMBER/sources/SOURCE_ID/locations/global/findings/FINDING_ID",
    "findingClass": "THREAT",
    "access": {
      "principalEmail": "PRINCIPAL_EMAIL",
      "callerIp": "IP_ADDRESS",
      "callerIpGeo": {
        "regionCode": "COUNTRY_CODE"
      },
      "userAgent": "USER_AGENT",
      "serviceName": "cloudresourcemanager.googleapis.com",
      "methodName": "SetIamPolicy",
      "principalSubject": "user:PRINCIPAL_EMAIL"
    },
    "mitreAttack": {
      "primaryTactic": "PERSISTENCE",
      "primaryTechniques": [
        "ADDITIONAL_CLOUD_ROLES",
        "ACCOUNT_MANIPULATION"
      ],
      "additionalTactics": [
        "PRIVILEGE_ESCALATION"
      ]
    },
    "iamBindings": [
      {
        "action": "ADD",
        "role": "roles/discoveryengine.agentspaceUser",
        "member": "user:EXTERNAL_USER_EMAIL"
      }
    ],
    "parentDisplayName": "Event Threat Detection",
    "domains": [
      {
        "category": "AI"
      },
      {
        "category": "IDENTITY_AND_ACCESS"
      }
    ],
    "logEntries": [
      {
        "cloudLoggingEntry": {
          "insertId": "INSERT_ID",
          "logId": "cloudaudit.googleapis.com/activity",
          "resourceContainer": "projects/PROJECT_ID",
          "timestamp": "TIMESTAMP"
        }
      }
    ]
  },
  "resource": {
    "name": "//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER",
    "displayName": "PROJECT_ID",
    "type": "google.cloud.resourcemanager.Project",
    "cloudProvider": "GOOGLE_CLOUD_PLATFORM",
    "service": "cloudresourcemanager.googleapis.com",
    "gcpMetadata": {
      "project": "//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER",
      "projectDisplayName": "PROJECT_ID",
      "parent": "//cloudresourcemanager.googleapis.com/organizations/ORGANIZATION_ID",
      "parentDisplayName": "ORGANIZATION_DISPLAY_NAME",
      "organization": "organizations/ORGANIZATION_ID"
    },
    "resourcePath": {
      "nodes": [
        {
          "nodeType": "GCP_PROJECT",
          "id": "projects/PROJECT_NUMBER",
          "displayName": "PROJECT_ID"
        },
        {
          "nodeType": "GCP_ORGANIZATION",
          "id": "organizations/ORGANIZATION_ID"
        }
      ]
    },
    "resourcePathString": "organizations/ORGANIZATION_ID/projects/PROJECT_NUMBER"
  },
  "sourceProperties": {
    "sourceId": {
      "projectNumber": "PROJECT_NUMBER",
      "customerOrganizationNumber": "ORGANIZATION_ID"
    },
    "detectionCategory": {
      "ruleName": "granting_external_access_to_gemini_enterprise_ai_apps"
    },
    "detectionPriority": "MEDIUM",
    "affectedResources": [
      {
        "gcpResourceName": "//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER"
      }
    ],
    "evidence": [
      {
        "sourceLogId": {
          "projectId": "PROJECT_ID",
          "resourceContainer": "projects/PROJECT_ID",
          "timestamp": {
            "seconds": "TIMESTAMP_SECONDS",
            "nanos": TIMESTAMP_NANOS
          },
          "insertId": "INSERT_ID",
          "logId": "cloudaudit.googleapis.com/activity"
        }
      }
    ],
    "findingId": "FINDING_ID",
    "contextUris": {
      "mitreUri": {
        "displayName": "MITRE Link",
        "url": "https://attack.mitre.org/techniques/T1098/003/"
      },
      "cloudLoggingQueryUri": [
        {
          "displayName": "Cloud Logging Query Link",
          "url": "https://console.cloud.google.com/logs/query;query=timestamp%3D%22TIMESTAMP%22%0AinsertId%3D%22INSERT_ID%22?project=PROJECT_ID"
        }
      ]
    },
    "domains": [
      {
        "category": "AI"
      },
      {
        "category": "IDENTITY_AND_ACCESS"
      }
    ]
  }
}

What's next