mirror of
https://github.com/xtr-dev/payload-billing.git
synced 2025-12-10 02:43:24 +00:00
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:
213
.github/CLAUDE_AUTOMATION.md
vendored
213
.github/CLAUDE_AUTOMATION.md
vendored
@@ -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
212
.github/CLAUDE_PERMISSIONS.md
vendored
Normal 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
23
.github/claude-config.json
vendored
Normal 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"
|
||||
}
|
||||
}
|
||||
20
.github/workflows/claude-code-review.yml
vendored
20
.github/workflows/claude-code-review.yml
vendored
@@ -12,11 +12,23 @@ on:
|
||||
|
||||
jobs:
|
||||
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: |
|
||||
# github.event.pull_request.user.login == 'external-contributor' ||
|
||||
# github.event.pull_request.user.login == 'new-developer' ||
|
||||
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
|
||||
# github.event.pull_request.author_association != 'OWNER' &&
|
||||
# github.event.pull_request.author_association != 'MEMBER'
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
|
||||
64
.github/workflows/claude-implement-issue.yml
vendored
64
.github/workflows/claude-implement-issue.yml
vendored
@@ -22,27 +22,81 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check if user has write access
|
||||
- name: Check user permissions
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
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({
|
||||
owner: context.repo.owner,
|
||||
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);
|
||||
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({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
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
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
|
||||
Reference in New Issue
Block a user