πŸ“… let's chat! explore the endless possibilities creating industries that don't exist. click here

guidewire-enterprise-rbac

Implement enterprise role-based access control for Guidewire InsuranceSuite including API roles, user permissions, and security policies. Trigger with phrases like "guidewire rbac", "permissions guidewire", "user roles", "api access control", "security permissions". allowed-tools: Read, Write, Edit, Bash(curl:*), Grep version: 1.0.0 license: MIT author: Jeremy Longshore <jeremy@intentsolutions.io>

Allowed Tools

No tools specified

Provided by Plugin

guidewire-pack

Claude Code skill pack for Guidewire InsuranceSuite (24 skills)

saas packs v1.0.0
View Plugin

Installation

This skill is included in the guidewire-pack plugin:

/plugin install guidewire-pack@claude-code-plugins-plus

Click to copy

Instructions

# Guidewire Enterprise RBAC ## Overview Implement comprehensive role-based access control for Guidewire InsuranceSuite including API roles, user permissions, system roles, and security policies. ## Prerequisites - Access to Guidewire Cloud Console (GCC) - Understanding of OAuth2 and JWT - Knowledge of enterprise security patterns ## RBAC Architecture ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Guidewire RBAC Architecture β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Guidewire Hub (IdP) β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ Users β”‚ β”‚ Groups β”‚ β”‚ Applicationsβ”‚ β”‚ Roles β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ Internal β”‚ β”‚ β€’ AD Sync β”‚ β”‚ β€’ Browser β”‚ β”‚ β€’ API Roles β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ External β”‚ β”‚ β€’ Manual β”‚ β”‚ β€’ Service β”‚ β”‚ β€’ App Roles β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β–Ό β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ PolicyCenter β”‚ β”‚ ClaimCenter β”‚ β”‚ BillingCenter β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ System Roles: β”‚ β”‚ System Roles: β”‚ β”‚ System Roles: β”‚ β”‚ β”‚ β”‚ β€’ Underwriter β”‚ β”‚ β€’ Claims Adjuster β”‚ β”‚ β€’ Billing Admin β”‚ β”‚ β”‚ β”‚ β€’ Policy Admin β”‚ β”‚ β€’ Claims Supervisor β”‚ β”‚ β€’ Payment Handler β”‚ β”‚ β”‚ β”‚ β€’ Agent β”‚ β”‚ β€’ SIU Investigator β”‚ β”‚ β€’ Collections Agent β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ API Roles: β”‚ β”‚ API Roles: β”‚ β”‚ API Roles: β”‚ β”‚ β”‚ β”‚ β€’ pc_policy_read β”‚ β”‚ β€’ cc_claim_read β”‚ β”‚ β€’ bc_billing_read β”‚ β”‚ β”‚ β”‚ β€’ pc_policy_admin β”‚ β”‚ β€’ cc_claim_admin β”‚ β”‚ β€’ bc_payment_admin β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ## Instructions ### Step 1: Configure API Roles in GCC ```yaml # API Role Configuration # Guidewire Cloud Console > Identity & Access > API Roles api_roles: # Read-only roles - name: pc_policy_read application: PolicyCenter description: Read-only access to policies and accounts permissions: - endpoint: /account/v1/accounts operations: [GET] - endpoint: /account/v1/accounts/{id} operations: [GET] - endpoint: /policy/v1/policies operations: [GET] - endpoint: /policy/v1/policies/{id} operations: [GET] # Admin roles - name: pc_policy_admin application: PolicyCenter description: Full access to policy administration permissions: - endpoint: /account/v1/accounts operations: [GET, POST, PATCH] - endpoint: /job/v1/submissions operations: [GET, POST, PATCH] - endpoint: /job/v1/submissions/{id}/quote operations: [POST] - endpoint: /job/v1/submissions/{id}/bind operations: [POST] - endpoint: /policy/v1/policies operations: [GET, POST, PATCH] # Claims roles - name: cc_claim_admin application: ClaimCenter description: Full access to claims management permissions: - endpoint: /claim/v1/claims operations: [GET, POST, PATCH] - endpoint: /fnol/v1/fnol operations: [POST] - endpoint: /claim/v1/claims/{id}/exposures operations: [GET, POST, PATCH] - endpoint: /claim/v1/claims/{id}/payments operations: [GET, POST] ``` ### Step 2: Service Account Configuration ```typescript // Service account management interface ServiceAccount { clientId: string; name: string; description: string; apiRoles: string[]; environments: string[]; } const serviceAccounts: ServiceAccount[] = [ { clientId: 'integration-service-prod', name: 'Integration Service', description: 'Backend integration service for policy and claims sync', apiRoles: ['pc_policy_admin', 'cc_claim_read'], environments: ['production'] }, { clientId: 'agent-portal-prod', name: 'Agent Portal', description: 'Agent-facing portal application', apiRoles: ['pc_policy_read', 'pc_submission_handler'], environments: ['production', 'uat'] }, { clientId: 'reporting-service', name: 'Reporting Service', description: 'Read-only access for reporting', apiRoles: ['pc_policy_read', 'cc_claim_read', 'bc_billing_read'], environments: ['production'] } ]; // Register service account in GCC async function registerServiceAccount(account: ServiceAccount): Promise { const response = await gccClient.post('/api/v1/applications', { clientId: account.clientId, name: account.name, description: account.description, type: 'service', apiRoles: account.apiRoles.map(role => ({ name: role })) }); console.log(`Registered service account: ${account.clientId}`); } ``` ### Step 3: User Role Management in Gosu ```gosu // User role management package gw.security.roles uses gw.api.util.Logger uses gw.pl.persistence.core.Bundle class RoleManager { private static final var LOG = Logger.forCategory("RoleManager") // Assign role to user static function assignRole(user : User, roleCode : String) { var role = Role.get(roleCode) if (role == null) { throw new IllegalArgumentException("Role not found: ${roleCode}") } if (user.hasRole(role)) { LOG.info("User ${user.UserName} already has role ${roleCode}") return } gw.transaction.Transaction.runWithNewBundle(\bundle -> { var u = bundle.add(user) var userRole = new UserRole(bundle) userRole.User = u userRole.Role = role LOG.info("Assigned role ${roleCode} to user ${user.UserName}") }) } // Remove role from user static function removeRole(user : User, roleCode : String) { var role = Role.get(roleCode) if (role == null) { throw new IllegalArgumentException("Role not found: ${roleCode}") } gw.transaction.Transaction.runWithNewBundle(\bundle -> { var u = bundle.add(user) var userRole = u.Roles.firstWhere(\ur -> ur.Role == role) if (userRole != null) { bundle.delete(userRole) LOG.info("Removed role ${roleCode} from user ${user.UserName}") } }) } // Check if user has permission static function hasPermission(user : User, permission : String) : boolean { return user.Roles.hasMatch(\ur -> ur.Role.Permissions.hasMatch(\p -> p.Code == permission) ) } // Get all permissions for user static function getUserPermissions(user : User) : Set { var permissions = new HashSet() user.Roles.each(\ur -> { ur.Role.Permissions.each(\p -> { permissions.add(p.Code) }) }) return permissions } } ``` ### Step 4: Custom Permission Checks ```gosu // Custom permission framework package gw.security.permissions uses gw.api.util.Logger uses gw.api.web.SessionUtil class PermissionChecker { private static final var LOG = Logger.forCategory("PermissionChecker") // Check permission with audit logging static function checkPermission(permission : String) : boolean { var user = SessionUtil.CurrentUser if (user == null) { LOG.warn("Permission check failed: No user in session") return false } var hasPermission = RoleManager.hasPermission(user, permission) if (!hasPermission) { LOG.warn("Permission denied: ${permission} for user ${user.UserName}") auditPermissionDenial(user, permission) } return hasPermission } // Require permission (throws if denied) static function requirePermission(permission : String) { if (!checkPermission(permission)) { throw new SecurityException("Permission denied: ${permission}") } } // Check entity-level permission static function canAccessEntity(entity : KeyableBean, operation : String) : boolean { var user = SessionUtil.CurrentUser if (user == null) { return false } // Check ownership if (isOwner(user, entity)) { return true } // Check hierarchical access if (hasHierarchicalAccess(user, entity)) { return true } // Check role-based access var permission = "${entity.IntrinsicType.Name}_${operation}" return checkPermission(permission) } private static function isOwner(user : User, entity : KeyableBean) : boolean { // Check if user created or is assigned to entity if (entity typeis Policy) { return entity.CreateUser == user } else if (entity typeis Claim) { return entity.AssignedUser == user } return false } private static function hasHierarchicalAccess(user : User, entity : KeyableBean) : boolean { // Check organizational hierarchy if (entity typeis Policy) { var policyOrg = entity.ProducerCodeOfRecord?.Organization return user.Organization == policyOrg || isParentOrg(user.Organization, policyOrg) } return false } private static function auditPermissionDenial(user : User, permission : String) { // Log to audit trail gw.api.audit.AuditLogger.log( "PERMISSION_DENIED", "User ${user.UserName} denied permission: ${permission}", user.PublicID ) } } ``` ### Step 5: Row-Level Security ```gosu // Row-level security implementation package gw.security.rls uses gw.api.database.Query uses gw.api.web.SessionUtil class RowLevelSecurity { // Apply security filters to queries static function applySecurityFilter(query : Query) : Query { var user = SessionUtil.CurrentUser if (user == null || user.hasRole(Role.get("SystemAdmin"))) { return query // No filtering for system admins } var entityType = query.getTargetType() if (entityType == Policy) { return applyPolicySecurityFilter(query as Query, user) as Query } else if (entityType == Claim) { return applyClaimSecurityFilter(query as Query, user) as Query } else if (entityType == Account) { return applyAccountSecurityFilter(query as Query, user) as Query } return query } private static function applyPolicySecurityFilter( query : Query, user : User ) : Query { // Filter by user's organization or producer code var userProducerCodes = user.ProducerCodes.map(\pc -> pc.Code) if (!userProducerCodes.Empty) { query.join(Policy#ProducerCodeOfRecord) .compareIn(ProducerCode#Code, userProducerCodes) } return query } private static function applyClaimSecurityFilter( query : Query, user : User ) : Query { // Filter by assigned user or group var userGroups = user.GroupUsers.map(\gu -> gu.Group) query.or(\orClause -> { orClause.compare(Claim#AssignedUser, Equals, user) if (!userGroups.Empty) { orClause.compareIn(Claim#AssignedGroup, userGroups) } }) return query } private static function applyAccountSecurityFilter( query : Query, user : User ) : Query { // Filter by producer code assignment var userProducerCodes = user.ProducerCodes.map(\pc -> pc.PublicID) if (!userProducerCodes.Empty) { query.subselect(Account#ID, CompareIn, Query.make(AccountProducerCode) .compareIn(AccountProducerCode#ProducerCode, userProducerCodes) .subselect(AccountProducerCode#Account, CompareIn, Account#ID) ) } return query } } // Secured query helper class SecuredQuery { static function make(type : Type) : Query { var query = Query.make(type) return RowLevelSecurity.applySecurityFilter(query) } } // Usage class PolicyService { static function findPoliciesForCurrentUser() : List { // Automatically applies row-level security return SecuredQuery.make(Policy) .compare(Policy#Status, Equals, PolicyStatus.TC_INFORCE) .select() .toList() } } ``` ### Step 6: API Authorization Middleware ```typescript // API authorization middleware import { Request, Response, NextFunction } from 'express'; interface SecurityContext { userId: string; roles: string[]; apiRoles: string[]; organizationId: string; producerCodes: string[]; } // Extract security context from JWT function extractSecurityContext(token: JWTPayload): SecurityContext { return { userId: token.sub, roles: token.roles || [], apiRoles: token.api_roles || [], organizationId: token.org_id, producerCodes: token.producer_codes || [] }; } // Require specific API role function requireApiRole(...requiredRoles: string[]) { return (req: Request, res: Response, next: NextFunction) => { const context = (req as any).securityContext as SecurityContext; if (!context) { return res.status(401).json({ error: 'Unauthorized' }); } const hasRequiredRole = requiredRoles.some(role => context.apiRoles.includes(role) ); if (!hasRequiredRole) { return res.status(403).json({ error: 'Forbidden', message: 'Insufficient API role permissions', requiredRoles, userRoles: context.apiRoles }); } next(); }; } // Row-level security filter for API responses function applySecurityFilter( data: T[], context: SecurityContext, filterFn: (item: T, context: SecurityContext) => boolean ): T[] { if (context.roles.includes('SystemAdmin')) { return data; } return data.filter(item => filterFn(item, context)); } // Usage in routes app.get('/api/policies', authMiddleware, requireApiRole('pc_policy_read', 'pc_policy_admin'), async (req, res) => { const context = (req as any).securityContext; let policies = await guidewireClient.getPolicies(); // Apply row-level security policies = applySecurityFilter(policies, context, (policy, ctx) => { return ctx.producerCodes.includes(policy.producerCode) || ctx.organizationId === policy.organizationId; }); res.json(policies); } ); ``` ## Role Matrix | Role | PolicyCenter | ClaimCenter | BillingCenter | |------|-------------|-------------|---------------| | System Admin | Full Access | Full Access | Full Access | | Underwriter | Submissions, Quotes | Read Only | Read Only | | Claims Adjuster | Read Only | Claims, Payments | Read Only | | Billing Admin | Read Only | Read Only | Full Access | | Agent | Submissions, Read | FNOL Only | Read Only | | Auditor | Read Only | Read Only | Read Only | ## Best Practices | Practice | Description | |----------|-------------| | Least Privilege | Grant minimum necessary permissions | | Role Separation | Separate roles by function, not convenience | | Regular Audits | Review role assignments quarterly | | Service Accounts | Use dedicated accounts for integrations | | API Role Scoping | Scope API roles to specific endpoints | ## Output - API role configuration - Service account setup - User role management - Custom permission framework - Row-level security - Authorization middleware ## Resources - [Guidewire Security Documentation](https://docs.guidewire.com/security/) - [API Role Configuration](https://docs.guidewire.com/cloud/) - [Authentication Architecture](https://docs.guidewire.com/cloud/pc/202503/cloudapica/) ## Next Steps For migration strategies, see `guidewire-migration-deep-dive`.

Skill file: plugins/saas-packs/guidewire-pack/skills/guidewire-enterprise-rbac/SKILL.md