feat: add comprehensive user permission controls for Claude workflows

- Add multi-level permission checking for issue implementation workflow
- Support multiple permission strategies: privileged users, admins only, combined, org-based
- Add permission validation with detailed error messages
- Restrict code review workflow to privileged users and repository members
- Create permission configuration file (.github/claude-config.json)
- Add comprehensive permission documentation

Permission strategies available:
- Privileged users only (most restrictive)
- Repository admins only
- Admins OR privileged users (default)
- Organization members with write access
- Everyone with write access (least restrictive)

Current configuration:
- Issue implementation: admins OR privileged users (bastiaan, xtr-dev-team)
- Code reviews: privileged users and repository members only

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-18 21:16:51 +02:00
parent bfa214aed6
commit 534b0e440f
5 changed files with 310 additions and 222 deletions

View File

@@ -1,213 +0,0 @@
# Claude Issue Implementation Automation
This repository includes GitHub workflow automation that allows Claude to implement issues automatically when requested via issue comments.
## How to Use
### 1. Trigger Implementation
Comment on any open issue with one of these triggers:
- `@claude implement`
- `@claude fix`
- `@claude create`
**Example:**
```
@claude implement
Please add TypeScript support for the billing configuration options.
```
### 2. What Happens
When you trigger the automation:
1. **Permission Check**: Verifies you have write access to the repository
2. **Branch Creation**: Creates a new branch under `claude/issue-{number}-{timestamp}`
3. **Implementation**: Claude analyzes the issue and implements the requested changes using the official Anthropic Claude Code action
4. **Pull Request**: Automatically creates a PR with the implementation
5. **Notification**: Updates the issue with progress and results
### 3. Branch Naming Convention
Branches are created with the pattern:
```
claude/issue-{issue-number}-{timestamp}
```
**Examples:**
- `claude/issue-123-20241218-143052`
- `claude/issue-456-20241218-151234`
### 4. Requirements
#### Repository Setup
- The workflow must be merged into your default branch (usually `main` or `dev`)
- Required GitHub secrets:
- `CLAUDE_CODE_OAUTH_TOKEN` - Your Claude Code OAuth token for implementation
#### Issue Requirements
- Issue must be **open**
- Issue should have clear, actionable requirements
- Include relevant context, code examples, or specifications
#### User Permissions
- Only users with **write access** or higher can trigger implementations
- This includes repository collaborators, maintainers, and owners
## Examples
### Good Issue for Implementation
```markdown
## Feature Request: Add Invoice PDF Export
**Description**: Users should be able to export invoices as PDF files
**Requirements**:
- Add "Export PDF" button to invoice detail page
- Generate PDF using existing invoice data
- Include company logo and styling
- Support both individual and bulk export
**Acceptance Criteria**:
- [ ] PDF export button appears on invoice page
- [ ] Generated PDF matches invoice design
- [ ] Bulk export works from invoice list
- [ ] Error handling for failed exports
```
### Trigger Comment
```
@claude implement
Please implement the PDF export feature as described in the issue. Make sure to follow the existing code patterns and add appropriate tests.
```
## Workflow Features
### ✅ Automated Branch Management
- Creates unique branches for each implementation
- Cleans up branches if no changes are made
- Prevents branch name conflicts
### ✅ Permission Control
- Validates user has write access before proceeding
- Provides clear error messages for unauthorized users
### ✅ Progress Tracking
- Real-time updates in issue comments
- Links to workflow execution logs
- Clear success/failure notifications
### ✅ Quality Assurance
- Uses official Anthropic Claude Code action
- Follows existing code patterns
- Includes appropriate documentation
- Maintains project coding standards
- Runs build, typecheck, and lint commands
## Troubleshooting
### Implementation Failed
If the workflow fails:
1. Check the [Actions tab](../../actions) for detailed logs
2. Verify the issue has clear, actionable requirements
3. Ensure repository permissions are configured correctly
4. Check that `CLAUDE_CODE_OAUTH_TOKEN` secret is set
5. Try again with more specific requirements
### No Changes Made
If Claude determines no changes are needed:
- The issue might already be implemented
- Requirements may need clarification
- The request might not be actionable as code
### Permission Denied
If you get permission errors:
- Verify you have write access to the repository
- Contact a repository maintainer for access
- Check if you're commenting on the correct repository
## Advanced Usage
### Multiple Implementations
You can request multiple implementations on the same issue:
- Each trigger creates a new branch
- Previous implementations remain available
- Latest implementation gets priority
### Custom Instructions
Provide specific implementation guidance:
```
@claude implement
Use the Stripe API for payment processing. Follow the existing payment provider pattern in src/providers/. Make sure to add proper error handling and webhook support.
```
### Review Process
All implementations create pull requests that:
- Reference the original issue
- Include detailed implementation notes
- Require manual review before merging
- Follow standard PR review process
## Configuration
### Required Secrets
Add these secrets in repository settings:
| Secret | Description | Required |
|--------|-------------|----------|
| `CLAUDE_CODE_OAUTH_TOKEN` | Claude Code OAuth token for implementation | Yes |
### Workflow Permissions
The workflow requires these permissions:
- `contents: write` - Create branches and commits
- `issues: write` - Comment on issues
- `pull-requests: write` - Create pull requests
- `id-token: write` - Required for Claude Code action
### Allowed Tools
Claude can run these commands during implementation:
- `pnpm build` - Build the project
- `pnpm typecheck` - Run TypeScript type checking
- `pnpm lint` - Run ESLint
- `npm run test` - Run tests
## Technical Details
### Claude Code Action
This workflow uses the official `anthropics/claude-code-action@beta` which provides:
- Direct integration with Claude's code generation capabilities
- Secure authentication via OAuth tokens
- Advanced code analysis and implementation features
- Built-in safety and quality controls
### Implementation Process
1. Claude analyzes the issue requirements
2. Reviews existing codebase patterns
3. Generates implementation following project conventions
4. Runs quality checks (build, typecheck, lint)
5. Creates commits with descriptive messages
6. Opens pull request with detailed description
## Limitations
- Only works with open issues
- Requires clear, actionable requirements
- Limited to repository collaborators
- May need manual refinement for complex features
- Cannot handle issues requiring external services or APIs without proper configuration
## Support
If you encounter issues with the automation:
1. Check workflow logs in the Actions tab
2. Verify issue requirements are clear and actionable
3. Ensure you have proper repository permissions
4. Verify `CLAUDE_CODE_OAUTH_TOKEN` secret is configured
5. Create a new issue describing the problem
---
**Note**: This automation is powered by Anthropic's Claude Code action and creates production-ready code, but all implementations should be reviewed before merging to ensure they meet your specific requirements and quality standards.

212
.github/CLAUDE_PERMISSIONS.md vendored Normal file
View File

@@ -0,0 +1,212 @@
# Claude Workflow Permissions
This document explains how to configure user permissions for Claude automation workflows.
## Current Configuration
### Issue Implementation Workflow
- **Strategy**: `adminOrPrivileged` - Repository admins OR privileged users
- **Privileged Users**: `bastiaan`, `xtr-dev-team`
- **Access Check**: Validates permissions before any Claude implementation
### Code Review Workflow
- **Strategy**: `privilegedUsers` - Only users in privileged list
- **Applies to**: Pull request reviews
- **Scope**: PRs created by privileged users only
## Permission Strategies
### 1. Privileged Users Only
```javascript
const isAllowed = privilegedUsers.includes(username);
```
- Most restrictive
- Only specific users can use Claude
- Best for sensitive repositories
### 2. Admins Only
```javascript
const isAllowed = collaborator.permission === 'admin';
```
- Repository administrators only
- Automatic based on GitHub permissions
- Good for small teams
### 3. Admin OR Privileged (Current)
```javascript
const isAllowed = hasAdminAccess || isPrivilegedUser;
```
- Repository admins OR users in privileged list
- Flexible access control
- **Currently active strategy**
### 4. Organization Members with Write Access
```javascript
const isAllowed = isOrgMember && hasWriteAccess;
```
- Organization members with write/admin permissions
- Good for larger organizations
### 5. Everyone with Access
```javascript
const isAllowed = hasWriteAccess;
```
- Any collaborator with write access
- Least restrictive option
## How to Change Permissions
### Option A: Edit Privileged Users List
1. Open `.github/workflows/claude-implement-issue.yml`
2. Find the `privilegedUsers` array (line ~32)
3. Add or remove usernames:
```javascript
const privilegedUsers = [
'bastiaan',
'xtr-dev-team',
'new-user', // Add new users here
'another-user'
];
```
### Option B: Change Permission Strategy
1. Open `.github/workflows/claude-implement-issue.yml`
2. Find line ~77: `const isAllowed = allowedByAdminOrPrivileged;`
3. Replace with your preferred strategy:
```javascript
// Only privileged users
const isAllowed = allowedByUserList;
// Only admins
const isAllowed = allowedByAdminAccess;
// Admin + privileged users (current)
const isAllowed = allowedByAdminOrPrivileged;
// Organization members with write access
const isAllowed = allowedByOrgAndWrite;
```
### Option C: Custom Logic
Add your own permission logic:
```javascript
// Example: Allow specific teams
const allowedTeams = ['core-team', 'senior-devs'];
const userTeams = await github.rest.teams.listForUser({
org: context.repo.owner,
username: username
});
const isInAllowedTeam = userTeams.data.some(team =>
allowedTeams.includes(team.slug)
);
const isAllowed = hasAdminAccess || isInAllowedTeam;
```
## Code Review Permissions
The code review workflow uses a simpler approach with GitHub's built-in author associations:
```yaml
if: |
contains(fromJSON('["bastiaan", "xtr-dev-team"]'), github.event.pull_request.user.login) ||
github.event.pull_request.author_association == 'OWNER' ||
github.event.pull_request.author_association == 'MEMBER'
```
### Author Associations:
- `OWNER` - Repository owner
- `MEMBER` - Organization member
- `COLLABORATOR` - Repository collaborator
- `CONTRIBUTOR` - Has contributed to the repository
- `FIRST_TIME_CONTRIBUTOR` - First-time contributor
- `NONE` - No association
## Testing Permissions
### Test Access for a User
1. Create a test issue
2. Have the user comment `@claude implement`
3. Check the workflow logs for permission results
### Debug Permission Issues
1. Go to **Actions** tab
2. Click on the failed workflow run
3. Expand "Check user permissions" step
4. Review the permission details in logs
## Error Messages
### Access Denied
```
❌ Access Denied: Claude implementation is restricted to privileged users only.
Your access level: write
Privileged user: No
Organization member: Yes
Contact a repository administrator for access.
```
### Permission Details
The error message shows:
- Current repository permission level
- Whether user is in privileged list
- Organization membership status
## Security Considerations
### Best Practices
1. **Start Restrictive**: Begin with privileged users only
2. **Regular Audits**: Review privileged user list regularly
3. **Monitor Usage**: Check workflow logs for unexpected access attempts
4. **Team-based Access**: Consider using GitHub teams for larger organizations
### Risks
- **Over-permissive**: Too many users can increase costs and misuse
- **Under-permissive**: Blocks legitimate development work
- **Stale Permissions**: Former team members with lingering access
## Configuration Examples
### Small Team (2-5 developers)
```javascript
const privilegedUsers = ['owner', 'lead-dev'];
const isAllowed = allowedByAdminOrPrivileged;
```
### Medium Team (5-15 developers)
```javascript
const privilegedUsers = ['owner', 'lead-dev', 'senior-dev1', 'senior-dev2'];
const isAllowed = allowedByAdminOrPrivileged;
```
### Large Organization
```javascript
// Use organization membership + write access
const isAllowed = allowedByOrgAndWrite;
```
### Open Source Project
```javascript
// Only maintainers
const privilegedUsers = ['maintainer1', 'maintainer2'];
const isAllowed = allowedByUserList;
```
## Troubleshooting
### Common Issues
1. **User not in list**: Add username to `privilegedUsers` array
2. **Wrong permission level**: User needs write access minimum
3. **Organization issues**: Verify org membership if using org-based permissions
4. **Case sensitivity**: Usernames are case-sensitive
### Quick Fixes
- **Add user**: Edit workflow file, add to privileged users
- **Temporary access**: Change strategy to `allowedByAdminAccess` temporarily
- **Emergency access**: Repository admins always have access with `adminOrPrivileged` strategy
---
**Note**: Changes to workflow files require a commit to take effect. Test permissions after any modifications.

23
.github/claude-config.json vendored Normal file
View File

@@ -0,0 +1,23 @@
{
"privilegedUsers": [
"bastiaan",
"xtr-dev-team"
],
"permissions": {
"issueImplementation": {
"strategy": "adminOrPrivileged",
"description": "Allow admins and privileged users to request Claude implementations"
},
"codeReview": {
"strategy": "privilegedUsers",
"description": "Only run Claude reviews for privileged users"
}
},
"strategies": {
"privilegedUsers": "Only users in the privilegedUsers list",
"adminsOnly": "Only repository admins",
"adminOrPrivileged": "Repository admins OR users in privilegedUsers list",
"orgMembersWithWrite": "Organization members with write access",
"everyone": "All users with repository access"
}
}

View File

@@ -12,11 +12,23 @@ on:
jobs: jobs:
claude-review: claude-review:
# Optional: Filter by PR author # Permission filter: Only allow specific users or admins to trigger reviews
if: |
contains(fromJSON('["bastiaan", "xtr-dev-team"]'), github.event.pull_request.user.login) ||
github.event.pull_request.author_association == 'OWNER' ||
github.event.pull_request.author_association == 'MEMBER'
# Alternative filters (comment out the above and use one of these):
# Only for external contributors:
# if: github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
# Only for specific users:
# if: contains(fromJSON('["username1", "username2"]'), github.event.pull_request.user.login)
# Only for non-admins (let admins skip review):
# if: | # if: |
# github.event.pull_request.user.login == 'external-contributor' || # github.event.pull_request.author_association != 'OWNER' &&
# github.event.pull_request.user.login == 'new-developer' || # github.event.pull_request.author_association != 'MEMBER'
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:

View File

@@ -22,27 +22,81 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check if user has write access - name: Check user permissions
uses: actions/github-script@v7 uses: actions/github-script@v7
with: with:
script: | script: |
const username = context.actor;
// Method 1: Specific privileged users list
const privilegedUsers = [
'bastiaan', // Repository owner
'xtr-dev-team', // Core team members
// Add more usernames here
];
// Method 2: Check repository permission level
const { data: collaborator } = await github.rest.repos.getCollaboratorPermissionLevel({ const { data: collaborator } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
username: context.actor username: username
}); });
// Method 3: Check organization membership (if applicable)
let isOrgMember = false;
try {
await github.rest.orgs.getMembershipForUser({
org: context.repo.owner,
username: username
});
isOrgMember = true;
} catch (error) {
// User is not an org member or org doesn't exist
isOrgMember = false;
}
// Combined permission check
const isPrivilegedUser = privilegedUsers.includes(username);
const hasAdminAccess = collaborator.permission === 'admin';
const hasWriteAccess = ['admin', 'write'].includes(collaborator.permission); const hasWriteAccess = ['admin', 'write'].includes(collaborator.permission);
if (!hasWriteAccess) {
// Choose your permission strategy:
// Option A: Only specific users
const allowedByUserList = isPrivilegedUser;
// Option B: Only admins
const allowedByAdminAccess = hasAdminAccess;
// Option C: Admin + specific users
const allowedByAdminOrPrivileged = hasAdminAccess || isPrivilegedUser;
// Option D: Organization members with write access
const allowedByOrgAndWrite = isOrgMember && hasWriteAccess;
// Set your chosen strategy here:
const isAllowed = allowedByAdminOrPrivileged; // Change this line to use your preferred strategy
if (!isAllowed) {
const errorMessage = `❌ **Access Denied**: Claude implementation is restricted to privileged users only.
**Your access level**: ${collaborator.permission}
**Privileged user**: ${isPrivilegedUser ? 'Yes' : 'No'}
**Organization member**: ${isOrgMember ? 'Yes' : 'No'}
Contact a repository administrator for access.`;
await github.rest.issues.createComment({ await github.rest.issues.createComment({
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
issue_number: context.issue.number, issue_number: context.issue.number,
body: `❌ Only collaborators with write access can request Claude implementation. Your permission level: ${collaborator.permission}` body: errorMessage
}); });
throw new Error('Insufficient permissions'); throw new Error('Insufficient permissions for Claude implementation');
} }
// Log successful access
console.log(`✅ Access granted to ${username} (${collaborator.permission})`);
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with: