{"record":{"id":"1da6f25bcd40fa97","repo":"spring-projects/spring-security","slug":"principal-does-not-have-required-acl-permissions-t","errorCode":null,"errorMessage":"Principal does not have required ACL permissions to perform requested operation","messagePattern":"Principal does not have required ACL permissions to perform requested operation","errorType":"exception","errorClass":"AccessDeniedException","httpStatus":403,"severity":"error","filePath":"acl/src/main/java/org/springframework/security/acls/domain/AclAuthorizationStrategyImpl.java","lineNumber":130,"sourceCode":"\t\tif (owner instanceof GrantedAuthoritySid\n\t\t\t\t&& authorities.contains(((GrantedAuthoritySid) owner).getGrantedAuthority())) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Not authorized by ACL ownership; try via adminstrative permissions\n\t\tGrantedAuthority requiredAuthority = getRequiredAuthority(changeType);\n\n\t\tif (authorities.contains(requiredAuthority.getAuthority())) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Try to get permission via ACEs within the ACL\n\t\tList<Sid> sids = this.sidRetrievalStrategy.getSids(authentication);\n\t\tif (acl.isGranted(Arrays.asList(BasePermission.ADMINISTRATION), sids, false)) {\n\t\t\treturn;\n\t\t}\n\n\t\tthrow new AccessDeniedException(\n\t\t\t\t\"Principal does not have required ACL permissions to perform requested operation\");\n\t}\n\n\tprivate GrantedAuthority getRequiredAuthority(int changeType) {\n\t\tif (changeType == CHANGE_AUDITING) {\n\t\t\treturn this.gaModifyAuditing;\n\t\t}\n\t\tif (changeType == CHANGE_GENERAL) {\n\t\t\treturn this.gaGeneralChanges;\n\t\t}\n\t\tif (changeType == CHANGE_OWNERSHIP) {\n\t\t\treturn this.gaTakeOwnership;\n\t\t}\n\t\tthrow new IllegalArgumentException(\"Unknown change type\");\n\t}\n\n\t/**\n\t * Creates a principal-like sid from the authentication information.","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/acl/src/main/java/org/springframework/security/acls/domain/AclAuthorizationStrategyImpl.java#L112-L148","documentation":"AclAuthorizationStrategyImpl.securityCheck() throws AccessDeniedException when the authenticated principal is neither the ACL owner, nor holds the required administrative GrantedAuthority, nor is granted BasePermission.ADMINISTRATION via the ACL's ACEs. This is the final gate before ACL changes are applied.","triggerScenarios":"A non-owner principal without the required change-type authority (e.g. aclAuthorizationStrategy with CHANGE_GENERAL authority not assigned) attempts setOwner/setEntriesInheriting/insertAce/deleteAcl and acl.isGranted(ADMINISTRATION, sids, false) returns false.","commonSituations":"Regular users editing ACLs they can read but not administer; missing gaModifyAccessControl/gaModifyAuditing/gaTakeOwnership authorities in AclAuthorizationStrategyImpl construction; ownership never transferred after object creation by an admin.","solutions":["Grant the principal BasePermission.ADMINISTRATION on the ACL, or make them the owner (acl.setOwner(sid) then updateAcl)","Configure AclAuthorizationStrategyImpl with the right authorities and grant users the needed one (e.g. ROLE_ACL_ADMIN for CHANGE_GENERAL)","Have an owner/admin perform the ACL mutation instead","Check acl.isGranted path and SID resolution if the principal believes they hold ADMINISTRATION"],"exampleFix":"// before\nnew AclAuthorizationStrategyImpl(\n    new SimpleGrantedAuthority(\"ROLE_ADMIN\"),\n    new SimpleGrantedAuthority(\"ROLE_ADMIN\"),\n    new SimpleGrantedAuthority(\"ROLE_ADMIN\"));\n// users lack ROLE_ADMIN\n\n// after\nnew AclAuthorizationStrategyImpl(\n    new SimpleGrantedAuthority(\"ROLE_ACL_OWNER\"),\n    new SimpleGrantedAuthority(\"ROLE_ACL_AUDIT\"),\n    new SimpleGrantedAuthority(\"ROLE_ACL_ADMIN\"));\n// and grant ROLE_ACL_ADMIN to service accounts that modify ACLs","handlingStrategy":"validation","validationCode":"Acl acl = aclService.readAclById(objectIdentity);\nboolean canAdminister = acl.isGranted(List.of(BasePermission.ADMINISTRATION),\n    sidRetrievalStrategy.getSids(authentication), false)\n    || authentication.getAuthorities().stream()\n        .anyMatch(g -> g.getAuthority().equals(\"ROLE_ACL_ADMIN\"));","typeGuard":"null","tryCatchPattern":"try {\n    mutableAclService.updateAcl(acl);\n} catch (AccessDeniedException e) {\n    throw new ResponseStatusException(HttpStatus.FORBIDDEN, \"Not an ACL administrator\");\n}","preventionTips":["Grant the CHANGE_GENERAL/CHANGE_AUDITING/TAKE_OWNERSHIP authorities to the right principals","Transfer ACL ownership when object ownership changes in the domain","Verify ADMINISTRATION ACEs exist for service accounts performing ACL administration"],"tags":["spring-security","acl","administration","access-denied","ownership"],"backgroundTag":"insufficient-permissions","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}