Agent Registry lets you configure automated security scanning for standalone skills, enforce scanning policies across your organization using Organization Policy Service, and triage security findings so that you can prevent compromised skills from reaching your agents.
When you upload a
skill revision,
Agent Registry scans the SKILL.md instruction file, optional scripts, and
supporting assets for security risks such as unauthorized data exfiltration,
exposed credentials, and prompt injection.
Skill security scanning uses large language models (LLMs) to evaluate instructions, code logic, and semantic intent. Because LLM analysis is probabilistic, scans might produce false positives or false negatives, and results might vary across runs. Additionally, details about findings might be approximate and subject to hallucination. Developers must review and verify scan findings before applying remediation changes.
Before you begin
- Set up Agent Registry.
For a single-project setup, get the project ID of the governance project where Agent Registry is enabled. If you configured a management boundary for multiple projects, use the ID of your management project for boundary-wide discovery and registration, or specify a member project ID for single-project operations.
Register a standalone skill in Agent Registry.
To use the Google Cloud CLI commands in this document, set up your gcloud CLI environment.
Required roles
To get the permissions that you need to configure scanning and triage findings in Agent Registry, ask your administrator to grant you the following IAM roles on the governance project where Agent Registry is enabled:
-
Configure skill scanning:
Agent Registry User (
roles/agentregistry.user) -
View skills and skill revisions:
Agent Registry API Viewer (
roles/agentregistry.viewer) -
View and list security findings:
Agent Registry API Admin (
roles/agentregistry.admin) -
Enforce scanning policies at the organization or folder level:
Organization Policy Administrator (
roles/orgpolicy.policyAdmin)
For more information about granting roles, see Manage access to projects, folders, and organizations.
You might also be able to get the required permissions through custom roles or other predefined roles.
Other Agent Registry roles might also include the permissions required to configure scanning and view skills. For more information, see Agent Registry roles and permissions.
Uncompressed payload size constraints
To ensure optimal performance and accommodate processing token limits for underlying LLM scanners, Agent Registry enforces strict uncompressed size limits when scanning is active:
- Total uncompressed skill size: maximum of 10 MB for the extracted archive.
- Per-file uncompressed size: maximum of 1 MB for any individual file within the skill package.
If a skill has scanning enabled and exceeds these limits,
creating a skill revision fails with an INVALID_ARGUMENT error or the
revision's scan status resolves to UNSUPPORTED_FORMAT.
If scanning is explicitly disabled, Agent Registry bypasses these scanning-specific size bounds, but general system limits still apply. For more information about system limits, see Quotas and system limits.
Configure a scanning policy for a skill
By default, skills use the Enabled (Blocking) (ENABLED_BLOCKING)
scanning policy, which
automatically scans uploaded skill revisions for security risks such as
unauthorized data exfiltration, exposed credentials, and prompt injection.
Detected issues are exposed as read-only Finding resources in your
governance project:
projects/PROJECT_NUMBER/locations/LOCATION/findings/FINDING_ID.
With Enabled (Blocking), Agent Registry blocks downloading revisions with security findings and prevents promoting revisions with findings or pending scans as the skill's default revision.
You can also configure scanning policies for non-blocking audit mode
(ENABLED_NONBLOCKING) or disable scanning (DISABLED). For more information
about supported scanning policies, see
Scanning policies.
Set or update skill scan settings
Enabling or updating scanning on an existing skill applies only to skill revisions created after the configuration change. Scanning isn't retroactively triggered for revisions that were already created. To scan skill contents uploaded when scanning was disabled, you must create a new skill revision.
To configure scanning settings when creating or updating a skill, follow these steps:
Console
In the Google Cloud console, go to the Agent Registry page:
Select the Skills tab.
Click Add skill or select an existing skill and click Edit.
In the Security scanning section, select the scanning policy you want.
Click Save or Create.
gcloud
Create a skill with scanning enabled (blocking): run the
gcloud agent-registry skills createcommand with the--scanning-policyflag set toenabled-blocking. For example, if you register a skill using a ZIP archive from a Cloud Storage bucket:gcloud agent-registry skills create SKILL_ID \ --project=PROJECT_ID \ --location=LOCATION \ --target-state=disabled \ --scanning-policy=enabled-blocking \ --gcs-source-uri="gs://BUCKET_NAME/SKILL_PACKAGE.zip"Create a skill with scanning enabled (non-blocking): run the
gcloud agent-registry skills createcommand with the--scanning-policyflag set toenabled-nonblocking. For example, if you register a skill using a ZIP archive from a Cloud Storage bucket:gcloud agent-registry skills create SKILL_ID \ --project=PROJECT_ID \ --location=LOCATION \ --target-state=disabled \ --scanning-policy=enabled-nonblocking \ --gcs-source-uri="gs://BUCKET_NAME/SKILL_PACKAGE.zip"Update scanning policy on an existing skill: run the
gcloud agent-registry skills updatecommand with the--scanning-policyflag set to the selected policy, for exampleenabled-nonblocking:gcloud agent-registry skills update SKILL_ID \ --project=PROJECT_ID \ --location=LOCATION \ --scanning-policy=enabled-nonblockingDisable scanning on a skill: run the
gcloud agent-registry skills updatecommand with the--scanning-policyflag set todisabled:gcloud agent-registry skills update SKILL_ID \ --project=PROJECT_ID \ --location=LOCATION \ --scanning-policy=disabledDescribe scan configuration on an existing skill: run the
gcloud agent-registry skills describecommand with the--formatflag set tovalue(scanningConfig.policy):gcloud agent-registry skills describe SKILL_ID \ --project=PROJECT_ID \ --location=LOCATION \ --format="value(scanningConfig.policy)"
Replace the following:
SKILL_ID: the ID of the skill. When updating or describing an existing manually registered skill, include theprivate-prefix, such asprivate-my-skill.PROJECT_ID: the project ID.LOCATION: the registry location.BUCKET_NAME: the Cloud Storage bucket name that contains the ZIP bundle. Before importing from a bucket, ensure that the Agent Registry service agent has thestorage.objects.getpermission on the bucket. For more information, see Register a skill.SKILL_PACKAGE: the name of the skill package containing the skill payload.
REST
To configure scanning using the REST API, include the scanningConfig object
in your request body:
curl -X PATCH \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{
"scanningConfig": {
"policy": "ENABLED_BLOCKING"
}
}' \
"https://agentregistry.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/skills/SKILL_ID?updateMask=scanningConfig"
Replace the following:
PROJECT_ID: the project ID.LOCATION: the registry location.SKILL_ID: the ID of the skill. For manually registered skills, include theprivate-prefix, such asprivate-my-skill.
Enforce scanning using Organization Policy Service
You can enforce organization-wide scanning policies by defining a custom
Organization Policy Service constraint on the Skill resource that evaluates the scanning
policy, with optional Resource Manager tag exemptions.
For information about organization policy enforcement in Agent Registry, capabilities, and limitations, see Organization policy enforcement.
Define the custom constraint
Create a YAML file named skills-scan-constraint.yaml with the following
specification:
name: organizations/ORGANIZATION_ID/customConstraints/custom.skillsScanningEnforcement
resourceTypes:
- agentregistry.googleapis.com/Skill
methodTypes:
- CREATE
- UPDATE
condition: resource.scanningConfig.policy == "DISABLED"
actionType: DENY
displayName: Prevent Disabling Skills Scanning
description: Prevents creating or updating skills with scanning disabled.
Replace ORGANIZATION_ID with your numerical
organization ID.
To require blocking mode across all skills and prevent both DISABLED and
ENABLED_NONBLOCKING scanning policies, you can alternatively set
condition: resource.scanningConfig.policy == "ENABLED_BLOCKING" and
actionType: ALLOW.
Set the custom constraint
Upload and register the custom constraint in your organization with the
gcloud org-policies set-custom-constraint
command:
gcloud org-policies set-custom-constraint skills-scan-constraint.yaml
Apply the policy with conditional exemptions
Create a policy definition file named skills-scan-policy.yaml that enforces
the constraint across all standard projects while, for example, exempting
testing projects that you tagged with exempt-scanning-enforcement: true:
name: organizations/ORGANIZATION_ID/policies/custom.skillsScanningEnforcement
spec:
rules:
# Enforce scanning on all standard projects
- enforce: true
condition:
expression: "!resource.matchTag('ORGANIZATION_ID/exempt-scanning-enforcement', 'true')"
title: "Enforce Scanning"
description: "Enforce scanning on all non-exempt projects"
# Bypass enforcement for tagged projects
- enforce: false
condition:
expression: "resource.matchTag('ORGANIZATION_ID/exempt-scanning-enforcement', 'true')"
title: "Exempt Testing Projects"
description: "Allow scanning to be disabled for testing projects"
Replace ORGANIZATION_ID with your numerical
organization ID.
Apply the policy to your organization with the
gcloud org-policies set-policy
command:
gcloud org-policies set-policy skills-scan-policy.yaml
Verify policy
Verify that the policy is active on a project with the
gcloud org-policies describe
command:
gcloud org-policies describe custom.skillsScanningEnforcement \
--project=PROJECT_ID \
--effective
Replace PROJECT_ID with your project ID.
Review scan results and revision status
When you publish a skill revision, the scanner runs asynchronously in the
background. To inspect the revision metadata and verify the scan outcome, run
the
gcloud agent-registry skills revisions describe
command:
gcloud agent-registry skills revisions describe REVISION_ID \
--skill=SKILL_ID \
--project=PROJECT_ID \
--location=LOCATION
Replace the following:
REVISION_ID: the ID of the skill revision.SKILL_ID: the ID of the skill container. For manually registered skills, include theprivate-prefix, such asprivate-my-skill.PROJECT_ID: the project ID.LOCATION: the registry location.
The output contains the scanResult block that looks like the following
example:
name: projects/my-project/locations/us-central1/skills/private-my-skill/revisions/rev-v1
createTime: '2026-08-10T09:15:00.000000Z'
state: ACTIVE
scanResult:
scanState: SUCCEEDED
scanTime: '2026-08-10T09:16:22.000000Z'
findings:
- projects/my-project/locations/us-central1/findings/b9a8c7d6-e5f4-4321-89ab-cdef01234567
Possible values for scanResult.scanState are:
SUCCEEDED: the scan completed execution. If security issues are detected, their resource names are listed in thescanResult.findingsarray. If no issues are detected,scanResult.findingsis empty.RUNNING: the scan is actively executing.DISABLED: scanning is bypassed because the skill's scanning policy is set toDISABLEDat the time the skill revision is created.UNSUPPORTED_FORMAT: the uploaded archive can't be analyzed by the scanner, for example, because its uncompressed size exceeded the scanning limits or its archive format is unsupported. Details are provided inscanResult.errorMessage.FAILED: the scan can't complete due to an internal error. Details are provided inscanResult.errorMessage.
A revision's scan status reflects the scanning configuration active at the time the revision was created. Enabling or updating scanning on a skill applies only to revisions created after the change and doesn't retroactively trigger a scan for existing revisions. To scan skill contents uploaded when scanning was disabled, you must create a new skill revision.
Triage security findings
When a scan detects security issues, detailed telemetry is published to
Agent Registry as Finding resources scoped to your project and location.
Viewing findings requires the Agent Registry API Admin
(roles/agentregistry.admin) role.
List all findings for a skill revision: run the
gcloud agent-registry findings listcommand:gcloud agent-registry findings list \ --project=PROJECT_ID \ --location=LOCATION \ --filter="resource=\"projects/PROJECT_ID/locations/LOCATION/skills/SKILL_ID/revisions/REVISION_ID\""Replace the following:
PROJECT_ID: the project ID.LOCATION: the registry location.SKILL_ID: the ID of the skill container, such asprivate-my-skill.REVISION_ID: the ID of the skill revision.
The output is similar to the following:
NAME SEVERITY FINDING_CLASS CREATE_TIME projects/my-project/locations/us-central1/findings/FINDING_ID SEVERITY_CRITICAL VULNERABILITY 2026-08-10T09:16:22.104ZDescribe finding details: run the
gcloud agent-registry findings describecommand:gcloud agent-registry findings describe FINDING_ID \ --project=PROJECT_ID \ --location=LOCATION \ --format=jsonReplace the following:
FINDING_ID: the ID of theFindingresource.PROJECT_ID: the project ID.LOCATION: the registry location.
Sample finding output:
{ "name": "projects/my-project/locations/us-central1/findings/FINDING_ID", "uid": "FINDING_ID", "createTime": "2026-08-10T09:16:22.104Z", "updateTime": "2026-08-10T09:16:22.104Z", "resource": "projects/my-project/locations/us-central1/skills/private-my-skill/revisions/rev-v1", "severity": "SEVERITY_CRITICAL", "findingClass": "VULNERABILITY", "files": [ { "path": "resources/helper.py", "lineNumber": "12" } ], "detail": "Involves unauthorized outbound network requests transmitting sensitive local files or environment variables. Detected inside resources/helper.py at line 12." }Each
Findingresource includes the following key fields:resource: the full resource name of the skill revision associated with the finding.severity: the severity level. Allowed values are:SEVERITY_CRITICALSEVERITY_HIGHSEVERITY_MEDIUMSEVERITY_LOWSEVERITY_UNSPECIFIED
findingClass: the type of finding:VULNERABILITY: a software or instruction weakness.SECRET: exposed plaintext credentials, keys, or tokens.
files: the list of affected files in the skill archive, including the relativepathandlineNumber. A value of0indicates that the finding applies to the entire file.detail: a detailed explanation of the detected security issue.
Remediate findings and update skills
To resolve security findings on a skill, follow these steps:
- Review the
detailfield of the finding and inspect the offending filepathandlineNumberin thefilesarray. Because automated scanning uses LLMs to inspect semantic code and instructions, verify the reported line numbers and findings before modifying your files. - Update your source files in your local development environment to resolve the finding. For example, remove unauthorized network calls, remove exposed credentials, or eliminate prompt injection patterns.
- Package the updated files into a new ZIP archive.
- Create a new skill revision.
- Verify that the new revision's
scanResult.scanStateresolves toSUCCEEDEDwith no findings listed. - Update the default revision of the skill to point to the verified revision.
What's next
- Learn about skills architecture.
- Learn how to register skills.
- Learn how to manage skill revisions.
- Review quotas and system limits.