Generated banner for Iam Helper For Troubleshooting
Generated logo for Iam Helper For Troubleshooting

Iam Helper For Troubleshooting

GoogleOfficialPublished by Google

  • Skill
  • Tool integration
  • Security
  • Apache-2.0
  • Low risk
  • Has scripts

From the author

Diagnoses, remediates, and manages Identity and Access Management (IAM) access issues on Google Cloud. Supports two distinct operational modes: (1) Requester Flow for developers encountering access denials (capturing error context, self-service PAM JIT activations, elevated developer self-remediation, or logging structured tickets), and (2) Resolver Flow for privileged administrators (authoritative Policy Troubleshooter analysis, deny policy exemptions, least-privilege role discovery, and PAM/IAM provisioning).
— the description by Google

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured approach to diagnosing and resolving Google Cloud IAM access denials. It operates in two modes: a Requester Flow for developers to perform self-service diagnostics or ticket creation, and a Resolver Flow for administrators to perform authoritative policy analysis, role discovery, and access provisioning. The skill enforces strict safety guardrails, including mandatory human-in-the-loop approval for all role modifications and specific protocols for handling unknown access states or existing permissions.

What it does

  • Diagnoses Google Cloud access denial errors using Policy Troubleshooter.
  • Supports self-service PAM JIT activation for developers.
  • Facilitates authoritative policy analysis and deny policy exemption management.
  • Identifies least-privilege roles for resource access.
  • Enforces human-in-the-loop approval for all IAM role provisioning.
  • Logs structured tickets for access escalation.

When to use it

  • When a developer encounters a 403 access denial on a Google Cloud resource.
  • When an administrator needs to investigate missing permissions or troubleshoot IAM policies.
  • When evaluating candidate roles for least-privilege access.
  • When managing PAM JIT grants or deny policy exemptions.

Advantages

  • Provides distinct workflows for different user personas.
  • Ensures security through mandatory human approval for role changes.
  • Prevents infinite loops during troubleshooting.
  • Standardizes access resolution processes across teams.
  • Integrates with Google Cloud Policy Troubleshooter.

Usage examples

“I am getting a 403 error when trying to list buckets in project my-project. Can you help?”
The agent initiates the Requester Flow, captures the error context, and guides the user through self-diagnosis or ticket creation.
“Troubleshoot why [email removed] cannot access the BigQuery dataset in project-a.”
The agent enters the Resolver Flow, evaluates the relevant IAM policies, and identifies the missing permissions or applicable deny policies.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/google/iam-helper-for-troubleshooting/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip iam-helper-for-troubleshooting.zip -d .agents/skills

Documentation by Google

IAM Access Troubleshooter & Remediation Orchestrator on Google Cloud

You are an expert Google Cloud Security and IAM assistant. You diagnose access denial errors and orchestrate the appropriate resolution path depending on the caller's persona and privileges.

Usage Attribution

MUST READ: Before executing any gcloud, REST API, or MCP command, you MUST read and follow the instructions in Usage Attribution.

Mode Selection Guide

Identify the caller's context to select the appropriate operational mode:

ModeTarget Persona / ContextPrimary ActionsReference Guide
Mode 1: Requester FlowDeveloper, Service Account, or requester blocked by an access denialCaptures Error ID, runs self-diagnosis, self-activates PAM JIT grants, self-remediates (if elevated), or logs structured tickets.references/requester.md
Mode 2: Resolver FlowSecurity Admin, Cloud IAM Admin, or agent handling an escalated access ticketAuthoritatively evaluates allow/deny policies, creates deny exemptions, discovers minimal roles, and provisions PAM/IAM access.references/resolver.md
Routing Rules
  1. Follow Mode 1 (Requester Flow) if:

    • You are executing an end-user development task, encounter a 403 / Error ID, and need to perform self-service PAM activation or produce an internal escalation ticket for an administrator.

    • 📖 Reference Guide: Read and follow references/requester.md for detailed execution steps.

  2. Follow Mode 2 (Resolver Flow) if:

    • The user asks you to troubleshoot access, investigate a missing permission, find candidate roles, or resolve an access denial on a Google Cloud resource.

    • 📖 Reference Guide: Read and follow references/resolver.md for detailed execution steps.

  3. Default Behavior:

    • Default to Mode 2 (Resolver Flow) for troubleshooting access denials and missing permissions across Google Cloud resources. Read and follow references/resolver.md for detailed execution steps.


Safety Guardrails & Approval Policy

All access modifications and role provisioning operations are governed by the approval tiers and safety boundaries defined in references/guardrails.md:

  • Human-in-the-Loop (HITL): All role provisioning operations (read-only, mutating, and administrative roles) require explicit human approval before execution. High-risk administrative roles require an explicit high-risk warning.

  • Access Already Granted Rule: When policy evaluation determines accessState: GRANTED (or access is already granted via inherited allow policies), inform the user that the IAM permission configuration is correct and terminate the troubleshooting flow immediately. Do NOT search for roles, suggest role queries, or propose role bindings.

  • Role Discovery Gating: Always ask the user for confirmation before executing queries to list or search candidate roles. Only list roles after receiving user confirmation in a subsequent turn.

  • Unknown Access State / Group Expansion Rule: When policy evaluation returns accessState: UNKNOWN or UNKNOWN_INFO (due to missing permissions to expand group memberships like roles/browser), explain that access is unknown due to missing group expansion permissions (roles/browser), and terminate the troubleshooting flow immediately. Do NOT run secondary queries or probe alternative policies.

  • Anti-Loop & Permission Denied: If troubleshooting commands encounter PERMISSION_DENIED on the caller's identity (HTTP 403), stop immediately without querying roles or running alternative commands. If the user requested replying with "Permission Denied" or the role name, reply immediately with "Permission Denied".

[!NOTE] Organizations cloning this skill should customize references/guardrails.md to define their specific approval tiers and policies.


Files

scripts/least_privileged_role.py

#!/usr/bin/env python3
"""Finds the candidate IAM role with least privilege granting a specific permission."""

import json
import os
import subprocess
import sys
from typing import List, Optional, Tuple


def get_default_project() -> str:
  """Retrieves the default project ID from gcloud config."""
  try:
    return subprocess.check_output(
        ["gcloud", "config", "get-value", "project"],
        text=True,
        stderr=subprocess.DEVNULL,
    ).strip()
  except (subprocess.SubprocessError, OSError):
    return ""


def list_roles(
    filter_perm: Optional[str] = None,
    extra_args: Optional[List[str]] = None,
) -> List[str]:
  """Lists role names using gcloud iam roles list, optionally filtered by permission."""
  cmd = ["gcloud", "iam", "roles", "list", "--format=value(name)"]
  if filter_perm:
    cmd.append(f"--filter=includedPermissions:{filter_perm}")
  if extra_args:
    cmd.extend(extra_args)
  try:
    output = subprocess.check_output(
        cmd, text=True, stderr=subprocess.DEVNULL
    ).strip()
    return [line.strip() for line in output.splitlines() if line.strip()]
  except (subprocess.SubprocessError, OSError):
    return []


def describe_role(
    role_id: str, extra_args: Optional[List[str]] = None
) -> Optional[dict]:
  """Describes a role using gcloud iam roles describe and returns parsed JSON."""
  cmd = ["gcloud", "iam", "roles", "describe", role_id, "--format=json"]
  if extra_args:
    cmd.extend(extra_args)
  try:
    output = subprocess.check_output(
        cmd, text=True, stderr=subprocess.DEVNULL
    ).strip()
    if output:
      return json.loads(output)
  except (subprocess.SubprocessError, OSError, json.JSONDecodeError):
    pass
  return None


def find_least_privileged_role(
    permission: str,
    project: Optional[str] = None,
    org: Optional[str] = None,
) -> Optional[str]:
  """Finds the role with the fewest permissions that includes the given permission."""
  candidates: List[Tuple[str, Optional[List[str]]]] = []

  # Predefined roles (filtered by permission, excluding overly broad basic roles)
  for role_name in list_roles(filter_perm=permission):
    if role_name not in [
        "roles/owner",
        "roles/editor",
        "roles/viewer",
        "roles/reader",
        "roles/writer",
        "roles/admin",
    ]:
      candidates.append((role_name, None))

  # Project-level custom roles
  if project:
    for role_name in list_roles(
        filter_perm=permission, extra_args=[f"--project={project}"]
    ):
      short_id = role_name.split("/")[-1]
      candidates.append((short_id, [f"--project={project}"]))

  # Organization-level custom roles
  if org:
    for role_name in list_roles(
        filter_perm=permission, extra_args=[f"--organization={org}"]
    ):
      short_id = role_name.split("/")[-1]
      candidates.append((short_id, [f"--organization={org}"]))

  valid_roles = []

  for role_id, extra_args in candidates:
    role_data = describe_role(role_id, extra_args)
    if not role_data:
      continue

    included_perms = role_data.get("includedPermissions", [])
    if permission in included_perms:
      role_name = role_data.get("name", role_id)
      role_name_lower = role_name.lower()

      # Identify service-level standard roles (for example, roles/compute.admin), avoiding basic overly broad roles
      is_service_level_standard = role_name.startswith("roles/") and (
          role_name_lower.endswith("admin")
          or role_name_lower.endswith("editor")
          or role_name_lower.endswith("viewer")
          or role_name_lower.endswith("reader")
          or role_name_lower.endswith("writer")
      )

      valid_roles.append({
          "name": role_name,
          "perm_count": len(included_perms),
          "is_service_level_standard": is_service_level_standard,
          "is_predefined": role_name.startswith("roles/"),
      })

  if not valid_roles:
    return None

  # Updated sorting logic: surface service-level standard roles first, then predefined roles, then by minimum permissions
  valid_roles.sort(
      key=lambda x: (
          not x["is_service_level_standard"],
          not x["is_predefined"],
          x["perm_count"],
      )
  )

  return valid_roles[0]["name"]


def main() -> None:
  permission = os.environ.get("IAM_PERMISSION", "")
  if not permission and len(sys.argv) > 1:
    permission = sys.argv[1]

  if not permission:
    print(
        "Error: IAM_PERMISSION environment variable or argument must be"
        " provided.",
        file=sys.stderr,
    )
    sys.exit(1)

  project = os.environ.get("TARGET_PROJECT_ID", "")
  if not project:
    project = get_default_project()

  org = os.environ.get("TARGET_ORGANIZATION_ID", "")

  best_role = find_least_privileged_role(permission, project=project, org=org)
  if best_role:
    print(best_role)
  else:
    print(
        "Warning: No candidate IAM role found that includes permission"
        f" '{permission}'.",
        file=sys.stderr,
    )


if __name__ == "__main__":
  main()

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs an MCP server, Needs Python

Security

What our scanner noticed· Low risk

  • Scripts that your agent may run

This skill includes scripts that your agent may run. Read them before you use it.

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
Google
Publisher
Google (Official)
Source
google/skills · skills/cloud/iam-helper-for-troubleshooting · commit 2194d3b
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Google or Google.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download iam-helper-for-troubleshooting.zip