Awesome-claude-code create-access-control

Generates Access Control components for PHP 8.4. Creates RBAC/ABAC components with PermissionInterface, RoleInterface, VoterInterface, AccessDecisionManager. Includes unit tests.

install
source · Clone the upstream repo
git clone https://github.com/dykyi-roman/awesome-claude-code
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/dykyi-roman/awesome-claude-code "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/create-access-control" ~/.claude/skills/dykyi-roman-awesome-claude-code-create-access-control && rm -rf "$T"
manifest: skills/create-access-control/SKILL.md
source content

Access Control Generator

Creates access control infrastructure for RBAC/ABAC authorization patterns.

When to Use

ScenarioExample
Role-based accessAdmin, editor, viewer roles
Resource ownershipUsers can only edit own resources
Attribute-based rulesAccess based on resource state or user attributes
Complex authorizationMultiple voters with different strategies

Component Characteristics

Permission

  • Enum defining available permissions
  • Hierarchical: parent permissions include children
  • Type-safe, no magic strings

Role

  • Value Object encapsulating role with permissions
  • Supports role hierarchy (admin inherits editor permissions)
  • Immutable, self-validating

VoterInterface

  • Symfony-style voter contract
  • Returns GRANT, DENY, or ABSTAIN
  • Single responsibility: one voter per concern

AccessDecisionManager

  • Aggregates multiple voters
  • Strategies: affirmative (one grant), unanimous (all grant), consensus (majority grants)
  • Configurable per security context

ResourceOwnerVoter

  • Checks if authenticated user owns the resource
  • Works with any entity implementing OwnableInterface
  • Returns ABSTAIN for non-ownable resources

RoleVoter

  • Checks if user has required role for the permission
  • Supports role hierarchy traversal
  • Returns ABSTAIN when permission not role-based

Generation Process

Step 1: Generate Core Components

Path:

src/Infrastructure/Security/AccessControl/

  1. Permission.php
    — Permission enum
  2. Role.php
    — Role value object with hierarchy
  3. AccessSubject.php
    — Value object wrapping the authenticated user context

Step 2: Generate Voter System

Path:

src/Infrastructure/Security/AccessControl/

  1. VoterInterface.php
    — Voter contract with GRANT/DENY/ABSTAIN
  2. Vote.php
    — Vote result enum
  3. AccessDecisionManager.php
    — Voter aggregation with strategies
  4. DecisionStrategy.php
    — Strategy enum (affirmative, unanimous, consensus)

Step 3: Generate Concrete Voters

Path:

src/Infrastructure/Security/AccessControl/Voter/

  1. RoleVoter.php
    — Role hierarchy voter
  2. ResourceOwnerVoter.php
    — Resource ownership voter

Step 4: Generate Tests

  1. RoleTest.php
    — Role hierarchy tests
  2. AccessDecisionManagerTest.php
    — Strategy decision tests
  3. RoleVoterTest.php
    — Role voter tests

File Placement

ComponentPath
Core Classes
src/Infrastructure/Security/AccessControl/
Voters
src/Infrastructure/Security/AccessControl/Voter/
Unit Tests
tests/Unit/Infrastructure/Security/AccessControl/

Naming Conventions

ComponentPatternExample
Permission
Permission
Permission::Edit
Role
Role
Role
Voter Interface
VoterInterface
VoterInterface
Concrete Voter
{Context}Voter
RoleVoter
Decision Manager
AccessDecisionManager
AccessDecisionManager
Strategy Enum
DecisionStrategy
DecisionStrategy::Affirmative
Vote Enum
Vote
Vote::Grant
Test
{ClassName}Test
AccessDecisionManagerTest

Quick Template Reference

Permission

enum Permission: string
{
    case View = 'view';
    case Create = 'create';
    case Edit = 'edit';
    case Delete = 'delete';
    case Manage = 'manage';
}

VoterInterface

interface VoterInterface
{
    public function vote(AccessSubject $subject, Permission $permission, mixed $resource = null): Vote;
}

AccessDecisionManager

final readonly class AccessDecisionManager
{
    /** @param list<VoterInterface> $voters */
    public function __construct(
        private array $voters,
        private DecisionStrategy $strategy = DecisionStrategy::Affirmative
    ) {}

    public function isGranted(AccessSubject $subject, Permission $permission, mixed $resource = null): bool;
}

Usage Example

$manager = new AccessDecisionManager(
    voters: [new RoleVoter(), new ResourceOwnerVoter()],
    strategy: DecisionStrategy::Affirmative
);

$subject = new AccessSubject(userId: $user->id(), roles: $user->roles());

if ($manager->isGranted($subject, Permission::Edit, $article)) {
    $article->update($data);
}

Decision Strategies

Affirmative: ANY voter grants → GRANTED   (default, most permissive)
Consensus:   MAJORITY grants → GRANTED    (balanced)
Unanimous:   ALL voters grant → GRANTED   (most restrictive)

Anti-patterns to Avoid

Anti-patternProblemSolution
String permissionsTypos, no IDE supportUse Permission enum
Inline auth checksScattered, unmaintainableCentralize in voters
God voterSingle voter with all logicOne voter per concern
No ABSTAIN supportVoter must decide everythingABSTAIN when not applicable
Flat rolesNo inheritance, duplicationRole hierarchy
Missing resource checkOnly role-based, no ownershipAdd ResourceOwnerVoter

References

For complete PHP templates and examples, see:

  • references/templates.md
    — Permission, Role, VoterInterface, AccessDecisionManager, Voter templates
  • references/examples.md
    — Authorization examples and tests