[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6F756YVXZ8N3QF8JN3A1SWJ":3,"skill-same:01M6F756YVXZ8N3QF8JN3A1SWJ":78},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":46,"linkOnly":47,"markdownContent":48,"markdownBody":49,"frontMatter":50,"refName":55,"commitSha":56,"skillDirectory":57,"forksCount":58,"repositoryHtmlUrl":59,"repositoryHomepageUrl":6,"ownerHtmlUrl":60,"ownerBlogUrl":61,"ownerDescription":62,"updatedAt":63,"install":64,"resources":77},"01M6F756YVXZ8N3QF8JN3A1SWJ","guidewire-enterprise-rbac",null,"Implement enterprise role-based access control for Guidewire InsuranceSuite\nincluding API roles, user permissions, and security policies.\nTrigger with phrases like \"guidewire rbac\", \"permissions guidewire\",\n\"user roles\", \"api access control\", \"security permissions\".","Dicklesworthstone\u002Fpi_agent_rust","Dicklesworthstone","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F35050222?v=4","01M6CG26AR942CSVMN1M5E3DSE","Jeff Emanuel","01M6CG26EPP71PSHW1VDS71121",1992,"MIT","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Fplugins-community\u002Fplugins\u002Fsaas-packs\u002Fguidewire-pack\u002Fskills\u002Fguidewire-enterprise-rbac\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],"rbac","guidewire enterprise rbac","Enterprise","write","for","with","Role-Based","trigger","io","roles","control","Access Control","edit","security","read","curl","grep","access","Bash","api","permissions","implement","2026-11-10 10:12:30",false,"---\nname: guidewire-enterprise-rbac\ndescription: |\n  Implement enterprise role-based access control for Guidewire InsuranceSuite\n  including API roles, user permissions, and security policies.\n  Trigger with phrases like \"guidewire rbac\", \"permissions guidewire\",\n  \"user roles\", \"api access control\", \"security permissions\".\nallowed-tools: Read, Write, Edit, Bash(curl:*), Grep\nversion: 1.0.0\nlicense: MIT\nauthor: Jeremy Longshore \u003Cjeremy@intentsolutions.io>\n---\n\n# Guidewire Enterprise RBAC\n\n## Overview\n\nImplement comprehensive role-based access control for Guidewire InsuranceSuite including API roles, user permissions, system roles, and security policies.\n\n## Prerequisites\n\n- Access to Guidewire Cloud Console (GCC)\n- Understanding of OAuth2 and JWT\n- Knowledge of enterprise security patterns\n\n## RBAC Architecture\n\n```\n┌─────────────────────────────────────────────────────────────────────────────────┐\n│                         Guidewire RBAC Architecture                              │\n├─────────────────────────────────────────────────────────────────────────────────┤\n│                                                                                  │\n│  ┌─────────────────────────────────────────────────────────────────────────┐   │\n│  │                         Guidewire Hub (IdP)                              │   │\n│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐    │   │\n│  │  │   Users     │  │   Groups    │  │ Applications│  │   Roles     │    │   │\n│  │  │             │  │             │  │             │  │             │    │   │\n│  │  │ • Internal  │  │ • AD Sync   │  │ • Browser   │  │ • API Roles │    │   │\n│  │  │ • External  │  │ • Manual    │  │ • Service   │  │ • App Roles │    │   │\n│  │  └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘    │   │\n│  └─────────────────────────────────────────────────────────────────────────┘   │\n│                                        │                                         │\n│                    ┌───────────────────┼───────────────────┐                    │\n│                    │                   │                   │                    │\n│                    ▼                   ▼                   ▼                    │\n│  ┌───────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐ │\n│  │     PolicyCenter      │ │     ClaimCenter       │ │    BillingCenter      │ │\n│  │                       │ │                       │ │                       │ │\n│  │ System Roles:         │ │ System Roles:         │ │ System Roles:         │ │\n│  │ • Underwriter         │ │ • Claims Adjuster     │ │ • Billing Admin       │ │\n│  │ • Policy Admin        │ │ • Claims Supervisor   │ │ • Payment Handler     │ │\n│  │ • Agent               │ │ • SIU Investigator    │ │ • Collections Agent   │ │\n│  │                       │ │                       │ │                       │ │\n│  │ API Roles:            │ │ API Roles:            │ │ API Roles:            │ │\n│  │ • pc_policy_read      │ │ • cc_claim_read       │ │ • bc_billing_read     │ │\n│  │ • pc_policy_admin     │ │ • cc_claim_admin      │ │ • bc_payment_admin    │ │\n│  └───────────────────────┘ └───────────────────────┘ └───────────────────────┘ │\n│                                                                                  │\n└─────────────────────────────────────────────────────────────────────────────────┘\n```\n\n## Instructions\n\n### Step 1: Configure API Roles in GCC\n\n```yaml\n# API Role Configuration\n# Guidewire Cloud Console > Identity & Access > API Roles\n\napi_roles:\n  # Read-only roles\n  - name: pc_policy_read\n    application: PolicyCenter\n    description: Read-only access to policies and accounts\n    permissions:\n      - endpoint: \u002Faccount\u002Fv1\u002Faccounts\n        operations: [GET]\n      - endpoint: \u002Faccount\u002Fv1\u002Faccounts\u002F{id}\n        operations: [GET]\n      - endpoint: \u002Fpolicy\u002Fv1\u002Fpolicies\n        operations: [GET]\n      - endpoint: \u002Fpolicy\u002Fv1\u002Fpolicies\u002F{id}\n        operations: [GET]\n\n  # Admin roles\n  - name: pc_policy_admin\n    application: PolicyCenter\n    description: Full access to policy administration\n    permissions:\n      - endpoint: \u002Faccount\u002Fv1\u002Faccounts\n        operations: [GET, POST, PATCH]\n      - endpoint: \u002Fjob\u002Fv1\u002Fsubmissions\n        operations: [GET, POST, PATCH]\n      - endpoint: \u002Fjob\u002Fv1\u002Fsubmissions\u002F{id}\u002Fquote\n        operations: [POST]\n      - endpoint: \u002Fjob\u002Fv1\u002Fsubmissions\u002F{id}\u002Fbind\n        operations: [POST]\n      - endpoint: \u002Fpolicy\u002Fv1\u002Fpolicies\n        operations: [GET, POST, PATCH]\n\n  # Claims roles\n  - name: cc_claim_admin\n    application: ClaimCenter\n    description: Full access to claims management\n    permissions:\n      - endpoint: \u002Fclaim\u002Fv1\u002Fclaims\n        operations: [GET, POST, PATCH]\n      - endpoint: \u002Ffnol\u002Fv1\u002Ffnol\n        operations: [POST]\n      - endpoint: \u002Fclaim\u002Fv1\u002Fclaims\u002F{id}\u002Fexposures\n        operations: [GET, POST, PATCH]\n      - endpoint: \u002Fclaim\u002Fv1\u002Fclaims\u002F{id}\u002Fpayments\n        operations: [GET, POST]\n```\n\n### Step 2: Service Account Configuration\n\n```typescript\n\u002F\u002F Service account management\ninterface ServiceAccount {\n  clientId: string;\n  name: string;\n  description: string;\n  apiRoles: string[];\n  environments: string[];\n}\n\nconst serviceAccounts: ServiceAccount[] = [\n  {\n    clientId: 'integration-service-prod',\n    name: 'Integration Service',\n    description: 'Backend integration service for policy and claims sync',\n    apiRoles: ['pc_policy_admin', 'cc_claim_read'],\n    environments: ['production']\n  },\n  {\n    clientId: 'agent-portal-prod',\n    name: 'Agent Portal',\n    description: 'Agent-facing portal application',\n    apiRoles: ['pc_policy_read', 'pc_submission_handler'],\n    environments: ['production', 'uat']\n  },\n  {\n    clientId: 'reporting-service',\n    name: 'Reporting Service',\n    description: 'Read-only access for reporting',\n    apiRoles: ['pc_policy_read', 'cc_claim_read', 'bc_billing_read'],\n    environments: ['production']\n  }\n];\n\n\u002F\u002F Register service account in GCC\nasync function registerServiceAccount(account: ServiceAccount): Promise\u003Cvoid> {\n  const response = await gccClient.post('\u002Fapi\u002Fv1\u002Fapplications', {\n    clientId: account.clientId,\n    name: account.name,\n    description: account.description,\n    type: 'service',\n    apiRoles: account.apiRoles.map(role => ({ name: role }))\n  });\n\n  console.log(`Registered service account: ${account.clientId}`);\n}\n```\n\n### Step 3: User Role Management in Gosu\n\n```gosu\n\u002F\u002F User role management\npackage gw.security.roles\n\nuses gw.api.util.Logger\nuses gw.pl.persistence.core.Bundle\n\nclass RoleManager {\n  private static final var LOG = Logger.forCategory(\"RoleManager\")\n\n  \u002F\u002F Assign role to user\n  static function assignRole(user : User, roleCode : String) {\n    var role = Role.get(roleCode)\n    if (role == null) {\n      throw new IllegalArgumentException(\"Role not found: ${roleCode}\")\n    }\n\n    if (user.hasRole(role)) {\n      LOG.info(\"User ${user.UserName} already has role ${roleCode}\")\n      return\n    }\n\n    gw.transaction.Transaction.runWithNewBundle(\\bundle -> {\n      var u = bundle.add(user)\n      var userRole = new UserRole(bundle)\n      userRole.User = u\n      userRole.Role = role\n      LOG.info(\"Assigned role ${roleCode} to user ${user.UserName}\")\n    })\n  }\n\n  \u002F\u002F Remove role from user\n  static function removeRole(user : User, roleCode : String) {\n    var role = Role.get(roleCode)\n    if (role == null) {\n      throw new IllegalArgumentException(\"Role not found: ${roleCode}\")\n    }\n\n    gw.transaction.Transaction.runWithNewBundle(\\bundle -> {\n      var u = bundle.add(user)\n      var userRole = u.Roles.firstWhere(\\ur -> ur.Role == role)\n      if (userRole != null) {\n        bundle.delete(userRole)\n        LOG.info(\"Removed role ${roleCode} from user ${user.UserName}\")\n      }\n    })\n  }\n\n  \u002F\u002F Check if user has permission\n  static function hasPermission(user : User, permission : String) : boolean {\n    return user.Roles.hasMatch(\\ur ->\n      ur.Role.Permissions.hasMatch(\\p -> p.Code == permission)\n    )\n  }\n\n  \u002F\u002F Get all permissions for user\n  static function getUserPermissions(user : User) : Set\u003CString> {\n    var permissions = new HashSet\u003CString>()\n    user.Roles.each(\\ur -> {\n      ur.Role.Permissions.each(\\p -> {\n        permissions.add(p.Code)\n      })\n    })\n    return permissions\n  }\n}\n```\n\n### Step 4: Custom Permission Checks\n\n```gosu\n\u002F\u002F Custom permission framework\npackage gw.security.permissions\n\nuses gw.api.util.Logger\nuses gw.api.web.SessionUtil\n\nclass PermissionChecker {\n  private static final var LOG = Logger.forCategory(\"PermissionChecker\")\n\n  \u002F\u002F Check permission with audit logging\n  static function checkPermission(permission : String) : boolean {\n    var user = SessionUtil.CurrentUser\n    if (user == null) {\n      LOG.warn(\"Permission check failed: No user in session\")\n      return false\n    }\n\n    var hasPermission = RoleManager.hasPermission(user, permission)\n\n    if (!hasPermission) {\n      LOG.warn(\"Permission denied: ${permission} for user ${user.UserName}\")\n      auditPermissionDenial(user, permission)\n    }\n\n    return hasPermission\n  }\n\n  \u002F\u002F Require permission (throws if denied)\n  static function requirePermission(permission : String) {\n    if (!checkPermission(permission)) {\n      throw new SecurityException(\"Permission denied: ${permission}\")\n    }\n  }\n\n  \u002F\u002F Check entity-level permission\n  static function canAccessEntity(entity : KeyableBean, operation : String) : boolean {\n    var user = SessionUtil.CurrentUser\n    if (user == null) {\n      return false\n    }\n\n    \u002F\u002F Check ownership\n    if (isOwner(user, entity)) {\n      return true\n    }\n\n    \u002F\u002F Check hierarchical access\n    if (hasHierarchicalAccess(user, entity)) {\n      return true\n    }\n\n    \u002F\u002F Check role-based access\n    var permission = \"${entity.IntrinsicType.Name}_${operation}\"\n    return checkPermission(permission)\n  }\n\n  private static function isOwner(user : User, entity : KeyableBean) : boolean {\n    \u002F\u002F Check if user created or is assigned to entity\n    if (entity typeis Policy) {\n      return entity.CreateUser == user\n    } else if (entity typeis Claim) {\n      return entity.AssignedUser == user\n    }\n    return false\n  }\n\n  private static function hasHierarchicalAccess(user : User, entity : KeyableBean) : boolean {\n    \u002F\u002F Check organizational hierarchy\n    if (entity typeis Policy) {\n      var policyOrg = entity.ProducerCodeOfRecord?.Organization\n      return user.Organization == policyOrg || isParentOrg(user.Organization, policyOrg)\n    }\n    return false\n  }\n\n  private static function auditPermissionDenial(user : User, permission : String) {\n    \u002F\u002F Log to audit trail\n    gw.api.audit.AuditLogger.log(\n      \"PERMISSION_DENIED\",\n      \"User ${user.UserName} denied permission: ${permission}\",\n      user.PublicID\n    )\n  }\n}\n```\n\n### Step 5: Row-Level Security\n\n```gosu\n\u002F\u002F Row-level security implementation\npackage gw.security.rls\n\nuses gw.api.database.Query\nuses gw.api.web.SessionUtil\n\nclass RowLevelSecurity {\n\n  \u002F\u002F Apply security filters to queries\n  static function applySecurityFilter\u003CT extends KeyableBean>(query : Query\u003CT>) : Query\u003CT> {\n    var user = SessionUtil.CurrentUser\n    if (user == null || user.hasRole(Role.get(\"SystemAdmin\"))) {\n      return query  \u002F\u002F No filtering for system admins\n    }\n\n    var entityType = query.getTargetType()\n\n    if (entityType == Policy) {\n      return applyPolicySecurityFilter(query as Query\u003CPolicy>, user) as Query\u003CT>\n    } else if (entityType == Claim) {\n      return applyClaimSecurityFilter(query as Query\u003CClaim>, user) as Query\u003CT>\n    } else if (entityType == Account) {\n      return applyAccountSecurityFilter(query as Query\u003CAccount>, user) as Query\u003CT>\n    }\n\n    return query\n  }\n\n  private static function applyPolicySecurityFilter(\n    query : Query\u003CPolicy>,\n    user : User\n  ) : Query\u003CPolicy> {\n    \u002F\u002F Filter by user's organization or producer code\n    var userProducerCodes = user.ProducerCodes.map(\\pc -> pc.Code)\n\n    if (!userProducerCodes.Empty) {\n      query.join(Policy#ProducerCodeOfRecord)\n        .compareIn(ProducerCode#Code, userProducerCodes)\n    }\n\n    return query\n  }\n\n  private static function applyClaimSecurityFilter(\n    query : Query\u003CClaim>,\n    user : User\n  ) : Query\u003CClaim> {\n    \u002F\u002F Filter by assigned user or group\n    var userGroups = user.GroupUsers.map(\\gu -> gu.Group)\n\n    query.or(\\orClause -> {\n      orClause.compare(Claim#AssignedUser, Equals, user)\n      if (!userGroups.Empty) {\n        orClause.compareIn(Claim#AssignedGroup, userGroups)\n      }\n    })\n\n    return query\n  }\n\n  private static function applyAccountSecurityFilter(\n    query : Query\u003CAccount>,\n    user : User\n  ) : Query\u003CAccount> {\n    \u002F\u002F Filter by producer code assignment\n    var userProducerCodes = user.ProducerCodes.map(\\pc -> pc.PublicID)\n\n    if (!userProducerCodes.Empty) {\n      query.subselect(Account#ID, CompareIn,\n        Query.make(AccountProducerCode)\n          .compareIn(AccountProducerCode#ProducerCode, userProducerCodes)\n          .subselect(AccountProducerCode#Account, CompareIn, Account#ID)\n      )\n    }\n\n    return query\n  }\n}\n\n\u002F\u002F Secured query helper\nclass SecuredQuery {\n  static function make\u003CT extends KeyableBean>(type : Type\u003CT>) : Query\u003CT> {\n    var query = Query.make(type)\n    return RowLevelSecurity.applySecurityFilter(query)\n  }\n}\n\n\u002F\u002F Usage\nclass PolicyService {\n  static function findPoliciesForCurrentUser() : List\u003CPolicy> {\n    \u002F\u002F Automatically applies row-level security\n    return SecuredQuery.make(Policy)\n      .compare(Policy#Status, Equals, PolicyStatus.TC_INFORCE)\n      .select()\n      .toList()\n  }\n}\n```\n\n### Step 6: API Authorization Middleware\n\n```typescript\n\u002F\u002F API authorization middleware\nimport { Request, Response, NextFunction } from 'express';\n\ninterface SecurityContext {\n  userId: string;\n  roles: string[];\n  apiRoles: string[];\n  organizationId: string;\n  producerCodes: string[];\n}\n\n\u002F\u002F Extract security context from JWT\nfunction extractSecurityContext(token: JWTPayload): SecurityContext {\n  return {\n    userId: token.sub,\n    roles: token.roles || [],\n    apiRoles: token.api_roles || [],\n    organizationId: token.org_id,\n    producerCodes: token.producer_codes || []\n  };\n}\n\n\u002F\u002F Require specific API role\nfunction requireApiRole(...requiredRoles: string[]) {\n  return (req: Request, res: Response, next: NextFunction) => {\n    const context = (req as any).securityContext as SecurityContext;\n\n    if (!context) {\n      return res.status(401).json({ error: 'Unauthorized' });\n    }\n\n    const hasRequiredRole = requiredRoles.some(role =>\n      context.apiRoles.includes(role)\n    );\n\n    if (!hasRequiredRole) {\n      return res.status(403).json({\n        error: 'Forbidden',\n        message: 'Insufficient API role permissions',\n        requiredRoles,\n        userRoles: context.apiRoles\n      });\n    }\n\n    next();\n  };\n}\n\n\u002F\u002F Row-level security filter for API responses\nfunction applySecurityFilter\u003CT>(\n  data: T[],\n  context: SecurityContext,\n  filterFn: (item: T, context: SecurityContext) => boolean\n): T[] {\n  if (context.roles.includes('SystemAdmin')) {\n    return data;\n  }\n  return data.filter(item => filterFn(item, context));\n}\n\n\u002F\u002F Usage in routes\napp.get('\u002Fapi\u002Fpolicies',\n  authMiddleware,\n  requireApiRole('pc_policy_read', 'pc_policy_admin'),\n  async (req, res) => {\n    const context = (req as any).securityContext;\n\n    let policies = await guidewireClient.getPolicies();\n\n    \u002F\u002F Apply row-level security\n    policies = applySecurityFilter(policies, context, (policy, ctx) => {\n      return ctx.producerCodes.includes(policy.producerCode) ||\n             ctx.organizationId === policy.organizationId;\n    });\n\n    res.json(policies);\n  }\n);\n```\n\n## Role Matrix\n\n| Role | PolicyCenter | ClaimCenter | BillingCenter |\n|------|-------------|-------------|---------------|\n| System Admin | Full Access | Full Access | Full Access |\n| Underwriter | Submissions, Quotes | Read Only | Read Only |\n| Claims Adjuster | Read Only | Claims, Payments | Read Only |\n| Billing Admin | Read Only | Read Only | Full Access |\n| Agent | Submissions, Read | FNOL Only | Read Only |\n| Auditor | Read Only | Read Only | Read Only |\n\n## Best Practices\n\n| Practice | Description |\n|----------|-------------|\n| Least Privilege | Grant minimum necessary permissions |\n| Role Separation | Separate roles by function, not convenience |\n| Regular Audits | Review role assignments quarterly |\n| Service Accounts | Use dedicated accounts for integrations |\n| API Role Scoping | Scope API roles to specific endpoints |\n\n## Output\n\n- API role configuration\n- Service account setup\n- User role management\n- Custom permission framework\n- Row-level security\n- Authorization middleware\n\n## Resources\n\n- [Guidewire Security Documentation](https:\u002F\u002Fdocs.guidewire.com\u002Fsecurity\u002F)\n- [API Role Configuration](https:\u002F\u002Fdocs.guidewire.com\u002Fcloud\u002F)\n- [Authentication Architecture](https:\u002F\u002Fdocs.guidewire.com\u002Fcloud\u002Fpc\u002F202503\u002Fcloudapica\u002F)\n\n## Next Steps\n\nFor migration strategies, see `guidewire-migration-deep-dive`.\n","# Guidewire Enterprise RBAC\n\n## Overview\n\nImplement comprehensive role-based access control for Guidewire InsuranceSuite including API roles, user permissions, system roles, and security policies.\n\n## Prerequisites\n\n- Access to Guidewire Cloud Console (GCC)\n- Understanding of OAuth2 and JWT\n- Knowledge of enterprise security patterns\n\n## RBAC Architecture\n\n```\n┌─────────────────────────────────────────────────────────────────────────────────┐\n│                         Guidewire RBAC Architecture                              │\n├─────────────────────────────────────────────────────────────────────────────────┤\n│                                                                                  │\n│  ┌─────────────────────────────────────────────────────────────────────────┐   │\n│  │                         Guidewire Hub (IdP)                              │   │\n│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐    │   │\n│  │  │   Users     │  │   Groups    │  │ Applications│  │   Roles     │    │   │\n│  │  │             │  │             │  │             │  │             │    │   │\n│  │  │ • Internal  │  │ • AD Sync   │  │ • Browser   │  │ • API Roles │    │   │\n│  │  │ • External  │  │ • Manual    │  │ • Service   │  │ • App Roles │    │   │\n│  │  └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘    │   │\n│  └─────────────────────────────────────────────────────────────────────────┘   │\n│                                        │                                         │\n│                    ┌───────────────────┼───────────────────┐                    │\n│                    │                   │                   │                    │\n│                    ▼                   ▼                   ▼                    │\n│  ┌───────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐ │\n│  │     PolicyCenter      │ │     ClaimCenter       │ │    BillingCenter      │ │\n│  │                       │ │                       │ │                       │ │\n│  │ System Roles:         │ │ System Roles:         │ │ System Roles:         │ │\n│  │ • Underwriter         │ │ • Claims Adjuster     │ │ • Billing Admin       │ │\n│  │ • Policy Admin        │ │ • Claims Supervisor   │ │ • Payment Handler     │ │\n│  │ • Agent               │ │ • SIU Investigator    │ │ • Collections Agent   │ │\n│  │                       │ │                       │ │                       │ │\n│  │ API Roles:            │ │ API Roles:            │ │ API Roles:            │ │\n│  │ • pc_policy_read      │ │ • cc_claim_read       │ │ • bc_billing_read     │ │\n│  │ • pc_policy_admin     │ │ • cc_claim_admin      │ │ • bc_payment_admin    │ │\n│  └───────────────────────┘ └───────────────────────┘ └───────────────────────┘ │\n│                                                                                  │\n└─────────────────────────────────────────────────────────────────────────────────┘\n```\n\n## Instructions\n\n### Step 1: Configure API Roles in GCC\n\n```yaml\n# API Role Configuration\n# Guidewire Cloud Console > Identity & Access > API Roles\n\napi_roles:\n  # Read-only roles\n  - name: pc_policy_read\n    application: PolicyCenter\n    description: Read-only access to policies and accounts\n    permissions:\n      - endpoint: \u002Faccount\u002Fv1\u002Faccounts\n        operations: [GET]\n      - endpoint: \u002Faccount\u002Fv1\u002Faccounts\u002F{id}\n        operations: [GET]\n      - endpoint: \u002Fpolicy\u002Fv1\u002Fpolicies\n        operations: [GET]\n      - endpoint: \u002Fpolicy\u002Fv1\u002Fpolicies\u002F{id}\n        operations: [GET]\n\n  # Admin roles\n  - name: pc_policy_admin\n    application: PolicyCenter\n    description: Full access to policy administration\n    permissions:\n      - endpoint: \u002Faccount\u002Fv1\u002Faccounts\n        operations: [GET, POST, PATCH]\n      - endpoint: \u002Fjob\u002Fv1\u002Fsubmissions\n        operations: [GET, POST, PATCH]\n      - endpoint: \u002Fjob\u002Fv1\u002Fsubmissions\u002F{id}\u002Fquote\n        operations: [POST]\n      - endpoint: \u002Fjob\u002Fv1\u002Fsubmissions\u002F{id}\u002Fbind\n        operations: [POST]\n      - endpoint: \u002Fpolicy\u002Fv1\u002Fpolicies\n        operations: [GET, POST, PATCH]\n\n  # Claims roles\n  - name: cc_claim_admin\n    application: ClaimCenter\n    description: Full access to claims management\n    permissions:\n      - endpoint: \u002Fclaim\u002Fv1\u002Fclaims\n        operations: [GET, POST, PATCH]\n      - endpoint: \u002Ffnol\u002Fv1\u002Ffnol\n        operations: [POST]\n      - endpoint: \u002Fclaim\u002Fv1\u002Fclaims\u002F{id}\u002Fexposures\n        operations: [GET, POST, PATCH]\n      - endpoint: \u002Fclaim\u002Fv1\u002Fclaims\u002F{id}\u002Fpayments\n        operations: [GET, POST]\n```\n\n### Step 2: Service Account Configuration\n\n```typescript\n\u002F\u002F Service account management\ninterface ServiceAccount {\n  clientId: string;\n  name: string;\n  description: string;\n  apiRoles: string[];\n  environments: string[];\n}\n\nconst serviceAccounts: ServiceAccount[] = [\n  {\n    clientId: 'integration-service-prod',\n    name: 'Integration Service',\n    description: 'Backend integration service for policy and claims sync',\n    apiRoles: ['pc_policy_admin', 'cc_claim_read'],\n    environments: ['production']\n  },\n  {\n    clientId: 'agent-portal-prod',\n    name: 'Agent Portal',\n    description: 'Agent-facing portal application',\n    apiRoles: ['pc_policy_read', 'pc_submission_handler'],\n    environments: ['production', 'uat']\n  },\n  {\n    clientId: 'reporting-service',\n    name: 'Reporting Service',\n    description: 'Read-only access for reporting',\n    apiRoles: ['pc_policy_read', 'cc_claim_read', 'bc_billing_read'],\n    environments: ['production']\n  }\n];\n\n\u002F\u002F Register service account in GCC\nasync function registerServiceAccount(account: ServiceAccount): Promise\u003Cvoid> {\n  const response = await gccClient.post('\u002Fapi\u002Fv1\u002Fapplications', {\n    clientId: account.clientId,\n    name: account.name,\n    description: account.description,\n    type: 'service',\n    apiRoles: account.apiRoles.map(role => ({ name: role }))\n  });\n\n  console.log(`Registered service account: ${account.clientId}`);\n}\n```\n\n### Step 3: User Role Management in Gosu\n\n```gosu\n\u002F\u002F User role management\npackage gw.security.roles\n\nuses gw.api.util.Logger\nuses gw.pl.persistence.core.Bundle\n\nclass RoleManager {\n  private static final var LOG = Logger.forCategory(\"RoleManager\")\n\n  \u002F\u002F Assign role to user\n  static function assignRole(user : User, roleCode : String) {\n    var role = Role.get(roleCode)\n    if (role == null) {\n      throw new IllegalArgumentException(\"Role not found: ${roleCode}\")\n    }\n\n    if (user.hasRole(role)) {\n      LOG.info(\"User ${user.UserName} already has role ${roleCode}\")\n      return\n    }\n\n    gw.transaction.Transaction.runWithNewBundle(\\bundle -> {\n      var u = bundle.add(user)\n      var userRole = new UserRole(bundle)\n      userRole.User = u\n      userRole.Role = role\n      LOG.info(\"Assigned role ${roleCode} to user ${user.UserName}\")\n    })\n  }\n\n  \u002F\u002F Remove role from user\n  static function removeRole(user : User, roleCode : String) {\n    var role = Role.get(roleCode)\n    if (role == null) {\n      throw new IllegalArgumentException(\"Role not found: ${roleCode}\")\n    }\n\n    gw.transaction.Transaction.runWithNewBundle(\\bundle -> {\n      var u = bundle.add(user)\n      var userRole = u.Roles.firstWhere(\\ur -> ur.Role == role)\n      if (userRole != null) {\n        bundle.delete(userRole)\n        LOG.info(\"Removed role ${roleCode} from user ${user.UserName}\")\n      }\n    })\n  }\n\n  \u002F\u002F Check if user has permission\n  static function hasPermission(user : User, permission : String) : boolean {\n    return user.Roles.hasMatch(\\ur ->\n      ur.Role.Permissions.hasMatch(\\p -> p.Code == permission)\n    )\n  }\n\n  \u002F\u002F Get all permissions for user\n  static function getUserPermissions(user : User) : Set\u003CString> {\n    var permissions = new HashSet\u003CString>()\n    user.Roles.each(\\ur -> {\n      ur.Role.Permissions.each(\\p -> {\n        permissions.add(p.Code)\n      })\n    })\n    return permissions\n  }\n}\n```\n\n### Step 4: Custom Permission Checks\n\n```gosu\n\u002F\u002F Custom permission framework\npackage gw.security.permissions\n\nuses gw.api.util.Logger\nuses gw.api.web.SessionUtil\n\nclass PermissionChecker {\n  private static final var LOG = Logger.forCategory(\"PermissionChecker\")\n\n  \u002F\u002F Check permission with audit logging\n  static function checkPermission(permission : String) : boolean {\n    var user = SessionUtil.CurrentUser\n    if (user == null) {\n      LOG.warn(\"Permission check failed: No user in session\")\n      return false\n    }\n\n    var hasPermission = RoleManager.hasPermission(user, permission)\n\n    if (!hasPermission) {\n      LOG.warn(\"Permission denied: ${permission} for user ${user.UserName}\")\n      auditPermissionDenial(user, permission)\n    }\n\n    return hasPermission\n  }\n\n  \u002F\u002F Require permission (throws if denied)\n  static function requirePermission(permission : String) {\n    if (!checkPermission(permission)) {\n      throw new SecurityException(\"Permission denied: ${permission}\")\n    }\n  }\n\n  \u002F\u002F Check entity-level permission\n  static function canAccessEntity(entity : KeyableBean, operation : String) : boolean {\n    var user = SessionUtil.CurrentUser\n    if (user == null) {\n      return false\n    }\n\n    \u002F\u002F Check ownership\n    if (isOwner(user, entity)) {\n      return true\n    }\n\n    \u002F\u002F Check hierarchical access\n    if (hasHierarchicalAccess(user, entity)) {\n      return true\n    }\n\n    \u002F\u002F Check role-based access\n    var permission = \"${entity.IntrinsicType.Name}_${operation}\"\n    return checkPermission(permission)\n  }\n\n  private static function isOwner(user : User, entity : KeyableBean) : boolean {\n    \u002F\u002F Check if user created or is assigned to entity\n    if (entity typeis Policy) {\n      return entity.CreateUser == user\n    } else if (entity typeis Claim) {\n      return entity.AssignedUser == user\n    }\n    return false\n  }\n\n  private static function hasHierarchicalAccess(user : User, entity : KeyableBean) : boolean {\n    \u002F\u002F Check organizational hierarchy\n    if (entity typeis Policy) {\n      var policyOrg = entity.ProducerCodeOfRecord?.Organization\n      return user.Organization == policyOrg || isParentOrg(user.Organization, policyOrg)\n    }\n    return false\n  }\n\n  private static function auditPermissionDenial(user : User, permission : String) {\n    \u002F\u002F Log to audit trail\n    gw.api.audit.AuditLogger.log(\n      \"PERMISSION_DENIED\",\n      \"User ${user.UserName} denied permission: ${permission}\",\n      user.PublicID\n    )\n  }\n}\n```\n\n### Step 5: Row-Level Security\n\n```gosu\n\u002F\u002F Row-level security implementation\npackage gw.security.rls\n\nuses gw.api.database.Query\nuses gw.api.web.SessionUtil\n\nclass RowLevelSecurity {\n\n  \u002F\u002F Apply security filters to queries\n  static function applySecurityFilter\u003CT extends KeyableBean>(query : Query\u003CT>) : Query\u003CT> {\n    var user = SessionUtil.CurrentUser\n    if (user == null || user.hasRole(Role.get(\"SystemAdmin\"))) {\n      return query  \u002F\u002F No filtering for system admins\n    }\n\n    var entityType = query.getTargetType()\n\n    if (entityType == Policy) {\n      return applyPolicySecurityFilter(query as Query\u003CPolicy>, user) as Query\u003CT>\n    } else if (entityType == Claim) {\n      return applyClaimSecurityFilter(query as Query\u003CClaim>, user) as Query\u003CT>\n    } else if (entityType == Account) {\n      return applyAccountSecurityFilter(query as Query\u003CAccount>, user) as Query\u003CT>\n    }\n\n    return query\n  }\n\n  private static function applyPolicySecurityFilter(\n    query : Query\u003CPolicy>,\n    user : User\n  ) : Query\u003CPolicy> {\n    \u002F\u002F Filter by user's organization or producer code\n    var userProducerCodes = user.ProducerCodes.map(\\pc -> pc.Code)\n\n    if (!userProducerCodes.Empty) {\n      query.join(Policy#ProducerCodeOfRecord)\n        .compareIn(ProducerCode#Code, userProducerCodes)\n    }\n\n    return query\n  }\n\n  private static function applyClaimSecurityFilter(\n    query : Query\u003CClaim>,\n    user : User\n  ) : Query\u003CClaim> {\n    \u002F\u002F Filter by assigned user or group\n    var userGroups = user.GroupUsers.map(\\gu -> gu.Group)\n\n    query.or(\\orClause -> {\n      orClause.compare(Claim#AssignedUser, Equals, user)\n      if (!userGroups.Empty) {\n        orClause.compareIn(Claim#AssignedGroup, userGroups)\n      }\n    })\n\n    return query\n  }\n\n  private static function applyAccountSecurityFilter(\n    query : Query\u003CAccount>,\n    user : User\n  ) : Query\u003CAccount> {\n    \u002F\u002F Filter by producer code assignment\n    var userProducerCodes = user.ProducerCodes.map(\\pc -> pc.PublicID)\n\n    if (!userProducerCodes.Empty) {\n      query.subselect(Account#ID, CompareIn,\n        Query.make(AccountProducerCode)\n          .compareIn(AccountProducerCode#ProducerCode, userProducerCodes)\n          .subselect(AccountProducerCode#Account, CompareIn, Account#ID)\n      )\n    }\n\n    return query\n  }\n}\n\n\u002F\u002F Secured query helper\nclass SecuredQuery {\n  static function make\u003CT extends KeyableBean>(type : Type\u003CT>) : Query\u003CT> {\n    var query = Query.make(type)\n    return RowLevelSecurity.applySecurityFilter(query)\n  }\n}\n\n\u002F\u002F Usage\nclass PolicyService {\n  static function findPoliciesForCurrentUser() : List\u003CPolicy> {\n    \u002F\u002F Automatically applies row-level security\n    return SecuredQuery.make(Policy)\n      .compare(Policy#Status, Equals, PolicyStatus.TC_INFORCE)\n      .select()\n      .toList()\n  }\n}\n```\n\n### Step 6: API Authorization Middleware\n\n```typescript\n\u002F\u002F API authorization middleware\nimport { Request, Response, NextFunction } from 'express';\n\ninterface SecurityContext {\n  userId: string;\n  roles: string[];\n  apiRoles: string[];\n  organizationId: string;\n  producerCodes: string[];\n}\n\n\u002F\u002F Extract security context from JWT\nfunction extractSecurityContext(token: JWTPayload): SecurityContext {\n  return {\n    userId: token.sub,\n    roles: token.roles || [],\n    apiRoles: token.api_roles || [],\n    organizationId: token.org_id,\n    producerCodes: token.producer_codes || []\n  };\n}\n\n\u002F\u002F Require specific API role\nfunction requireApiRole(...requiredRoles: string[]) {\n  return (req: Request, res: Response, next: NextFunction) => {\n    const context = (req as any).securityContext as SecurityContext;\n\n    if (!context) {\n      return res.status(401).json({ error: 'Unauthorized' });\n    }\n\n    const hasRequiredRole = requiredRoles.some(role =>\n      context.apiRoles.includes(role)\n    );\n\n    if (!hasRequiredRole) {\n      return res.status(403).json({\n        error: 'Forbidden',\n        message: 'Insufficient API role permissions',\n        requiredRoles,\n        userRoles: context.apiRoles\n      });\n    }\n\n    next();\n  };\n}\n\n\u002F\u002F Row-level security filter for API responses\nfunction applySecurityFilter\u003CT>(\n  data: T[],\n  context: SecurityContext,\n  filterFn: (item: T, context: SecurityContext) => boolean\n): T[] {\n  if (context.roles.includes('SystemAdmin')) {\n    return data;\n  }\n  return data.filter(item => filterFn(item, context));\n}\n\n\u002F\u002F Usage in routes\napp.get('\u002Fapi\u002Fpolicies',\n  authMiddleware,\n  requireApiRole('pc_policy_read', 'pc_policy_admin'),\n  async (req, res) => {\n    const context = (req as any).securityContext;\n\n    let policies = await guidewireClient.getPolicies();\n\n    \u002F\u002F Apply row-level security\n    policies = applySecurityFilter(policies, context, (policy, ctx) => {\n      return ctx.producerCodes.includes(policy.producerCode) ||\n             ctx.organizationId === policy.organizationId;\n    });\n\n    res.json(policies);\n  }\n);\n```\n\n## Role Matrix\n\n| Role | PolicyCenter | ClaimCenter | BillingCenter |\n|------|-------------|-------------|---------------|\n| System Admin | Full Access | Full Access | Full Access |\n| Underwriter | Submissions, Quotes | Read Only | Read Only |\n| Claims Adjuster | Read Only | Claims, Payments | Read Only |\n| Billing Admin | Read Only | Read Only | Full Access |\n| Agent | Submissions, Read | FNOL Only | Read Only |\n| Auditor | Read Only | Read Only | Read Only |\n\n## Best Practices\n\n| Practice | Description |\n|----------|-------------|\n| Least Privilege | Grant minimum necessary permissions |\n| Role Separation | Separate roles by function, not convenience |\n| Regular Audits | Review role assignments quarterly |\n| Service Accounts | Use dedicated accounts for integrations |\n| API Role Scoping | Scope API roles to specific endpoints |\n\n## Output\n\n- API role configuration\n- Service account setup\n- User role management\n- Custom permission framework\n- Row-level security\n- Authorization middleware\n\n## Resources\n\n- [Guidewire Security Documentation](https:\u002F\u002Fdocs.guidewire.com\u002Fsecurity\u002F)\n- [API Role Configuration](https:\u002F\u002Fdocs.guidewire.com\u002Fcloud\u002F)\n- [Authentication Architecture](https:\u002F\u002Fdocs.guidewire.com\u002Fcloud\u002Fpc\u002F202503\u002Fcloudapica\u002F)\n\n## Next Steps\n\nFor migration strategies, see `guidewire-migration-deep-dive`.\n",{"name":5,"author":51,"license":15,"version":52,"description":53,"allowed-tools":54},"Jeremy Longshore \u003Cjeremy@intentsolutions.io>","1.0.0","Implement enterprise role-based access control for Guidewire InsuranceSuite\nincluding API roles, user permissions, and security policies.\nTrigger with phrases like \"guidewire rbac\", \"permissions guidewire\",\n\"user roles\", \"api access control\", \"security permissions\".\n","Read, Write, Edit, Bash(curl:*), Grep","main","90b50ed0778745a80fd5bfb13b1843d45b9e82f7","tests\u002Fext_conformance\u002Fartifacts\u002Fplugins-community\u002Fplugins\u002Fsaas-packs\u002Fguidewire-pack\u002Fskills\u002Fguidewire-enterprise-rbac",233,"https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust","https:\u002F\u002Fgithub.com\u002FDicklesworthstone","https:\u002F\u002Fwww.jeffreyemanuel.com\u002F","Building in NY","2026-11-15 01:54:15",{"source":8,"skillName":5,"commands":65,"prompt":75,"zipAvailable":76},[66,69,72],{"tool":67,"command":68},"npx","npx skills add Dicklesworthstone\u002Fpi_agent_rust --skill guidewire-enterprise-rbac",{"tool":70,"command":71},"bunx","bunx skills add Dicklesworthstone\u002Fpi_agent_rust --skill guidewire-enterprise-rbac",{"tool":73,"command":74},"pnpm","pnpm dlx skills add Dicklesworthstone\u002Fpi_agent_rust --skill guidewire-enterprise-rbac","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Fplugins-community\u002Fplugins\u002Fsaas-packs\u002Fguidewire-pack\u002Fskills\u002Fguidewire-enterprise-rbac\u002FSKILL.md",true,[],[79,119,143,170,197,219],{"skillNo":80,"name":81,"nameZh":6,"description":82,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":83,"licenseFileUrl":84,"sourceHtmlUrl":85,"categories":86,"keywords":92,"publishedAt":46},"01M6FEGPPK0ZTKCCM0R3E3KS33","web-artifacts-builder","Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn\u002Fui). Use for complex artifacts requiring state management, routing, or shadcn\u002Fui components - not for simple single-file HTML\u002FJSX artifacts.","Apache-2.0","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Futilities\u002Fweb-artifacts-builder\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Futilities\u002Fweb-artifacts-builder\u002FSKILL.md",[87],{"categoryNo":88,"categoryName":89,"taxonomyType":90,"taxonomyTypeDesc":91},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",[93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,28,117,118],"web artifacts builder","web","artifacts","artifacts builder","builder","frontend","css","components","react","component","routing","state management","state","shadcn","file","ui","Tools","Tailwind","use","html","single-file","simple","ui components","multi","jsx","suite",{"skillNo":120,"name":121,"nameZh":6,"description":122,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":83,"licenseFileUrl":123,"sourceHtmlUrl":124,"categories":125,"keywords":130,"publishedAt":46},"01M6FEE9VTK1W4GY21AKREJXRG","webapp-testing","Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fsecurity\u002Fwebapp-testing\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fsecurity\u002Fwebapp-testing\u002FSKILL.md",[126,129],{"categoryNo":127,"categoryName":128,"taxonomyType":90,"taxonomyTypeDesc":91},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":88,"categoryName":89,"taxonomyType":90,"taxonomyTypeDesc":91},[131,132,133,98,134,135,94,136,137,138,108,139,140,141,142,29,28],"testing","webapp testing","webapp","screenshots","playwright","debugging","toolkit","browser","logs","applications","behavior","local",{"skillNo":144,"name":145,"nameZh":6,"description":146,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":147,"sourceHtmlUrl":148,"categories":149,"keywords":150,"publishedAt":46},"01M6FE20F7ZTQBFWKF4MPJ2SBX","neuropixels-analysis","Neuropixels neural recording analysis. Load SpikeGLX\u002FOpenEphys data, preprocess, motion correction, Kilosort4 spike sorting, quality metrics, Allen\u002FIBL curation, AI-assisted visual analysis, for Neuropixels 1.0\u002F2.0 extracellular electrophysiology. Use when working with neural recordings, spike sorting, extracellular electrophysiology, or when the user mentions Neuropixels, SpikeGLX, Open Ephys, Kilosort, quality metrics, or unit curation.","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fscientific\u002Fneuropixels-analysis\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fscientific\u002Fneuropixels-analysis\u002FSKILL.md",[],[151,152,153,154,155,156,157,158,111,159,160,161,162,163,164,165,29,166,167,168,28,169],"analysis","neuropixels analysis","spike","metrics","data","open","quality","user","recordings","Neural","motion","visual","quality metrics","unit","sorting","curation","recording","load","when",{"skillNo":171,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":83,"licenseFileUrl":174,"sourceHtmlUrl":175,"categories":176,"keywords":180,"publishedAt":46},"01M6FDP0PDK6F1GGX395C7625Z","skill-creator","Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fproductivity\u002Fskill-creator\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fproductivity\u002Fskill-creator\u002FSKILL.md",[177],{"categoryNo":178,"categoryName":179,"taxonomyType":90,"taxonomyTypeDesc":91},"01JBSEEDCAT000000000000023","Skill与智能体开发",[181,182,183,184,185,186,187,188,189,190,191,192,193,194,29,28,195,169,196],"skill creator","creator","workflows","create","update","capabilities","knowledge","tool","integrations","specialized","guide","new skill","existing skill","users","Existing","new",{"skillNo":198,"name":199,"nameZh":6,"description":200,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":201,"sourceHtmlUrl":202,"categories":203,"keywords":205,"publishedAt":46},"01M6FDM8Y7VK7NYG9SM7QPA3PW","notebooklm","Use this skill to query your Google NotebookLM notebooks directly from Claude Code for source-grounded, citation-backed answers from Gemini. Browser automation, library management, persistent auth. Drastically reduced hallucinations through document-only responses.","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fproductivity\u002Fnotebooklm\u002FLICENSE","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fproductivity\u002Fnotebooklm\u002FSKILL.md",[204],{"categoryNo":178,"categoryName":179,"taxonomyType":90,"taxonomyTypeDesc":91},[199,206,207,208,209,210,211,138,212,213,111,214,215,216,217,28,218],"google","browser automation","gemini","automation","auth","code","library","management","only","document","query","Citation","source",{"skillNo":220,"name":221,"nameZh":6,"description":222,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":83,"licenseFileUrl":223,"sourceHtmlUrl":224,"categories":225,"keywords":232,"publishedAt":46},"01M6FDHPXE10J3XGTCH5HBHS1M","slack-gif-creator","Knowledge and utilities for creating animated GIFs optimized for Slack. Provides constraints, validation tools, and animation concepts. Use when users request animated GIFs for Slack like \"make me a GIF of X doing Y for Slack.\"","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fenterprise-communication\u002Fslack-gif-creator\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fenterprise-communication\u002Fslack-gif-creator\u002FSKILL.md",[226,229],{"categoryNo":227,"categoryName":228,"taxonomyType":90,"taxonomyTypeDesc":91},"01JBSEEDCAT000000000000005","邮件与沟通",{"categoryNo":230,"categoryName":231,"taxonomyType":90,"taxonomyTypeDesc":91},"01JBSEEDCAT000000000000016","图像与多媒体",[233,234,235,182,236,109,237,238,187,111,239,194,240,241,242,28,243,169],"slack gif creator","slack","gif","validation","constraints","Animation","me","make","Utilities","concepts","request"]