- Add bot_email action input for custom git commit email on Forgejo - Update claude.yml to use CLAUDE_BOT_TOKEN with bot_id/bot_name/bot_email - Update git-config.ts to use provided email over noreply format - Add "Dedicated Bot User" setup guide to docs/forgejo.md - Update CLAUDE.md with bot identity documentation Infrastructure (done outside code): - claude-bot user created (ID 48, non-admin, with avatar) - Claude team with write access in all 12 orgs - CLAUDE_BOT_TOKEN org-level secret in all 12 orgs Progress: ~85% complete - pending E2E validation after merge Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
6.0 KiB
PRD #5: Dedicated Forgejo User for Claude Bot
Issue: #5 Priority: High Created: 2026-02-25 Status: ~85% complete — code and infra done, pending E2E validation after merge
Problem
Claude currently runs under the human operator's personal Forgejo token (FORGEJO_TOKEN / github_token). This causes:
- Attribution confusion: Commits and comments appear as the human user, not as a bot
- Over-privileged access: The bot inherits all permissions of the human account
- Audit trail: No clear separation between human actions and bot actions in repo history
- Security: If the action is compromised, the human's full token is exposed
On GitHub, this is solved by the GitHub App OIDC token exchange (bot gets its own claude[bot] identity). On Forgejo, there's no such mechanism — we need a manual equivalent.
Solution
Create a dedicated claude-bot user on the Forgejo instance (git.wxs.ro), generate a scoped API token for it, and configure the action workflow to use that token. This gives Claude its own identity for commits, comments, and API operations.
Milestones
Phase 1: Forgejo Admin Setup
-
M1: Create dedicated
claude-botuser on git.wxs.ro- Create user via Forgejo admin panel or API (
POST /admin/users) - Set appropriate display name (e.g., "Claude Bot")
- Set avatar to distinguish from human users
- User should NOT have admin privileges
- Validation: User exists and can log in
- Evidence: User ID 48,
is_admin: false, avatar set to Claude logo
- Create user via Forgejo admin panel or API (
-
M2: Configure bot user permissions and token
- Add
claude-botto theactionsorg (and any other orgs where the action runs) - Grant
writepermission on repos where Claude needs to operate - Generate a scoped API token for the bot user with minimal required permissions:
repo(read/write issues, PRs, comments, branches, commits)packages(if needed for container operations)- NO admin scope, NO user scope beyond what's needed
- Validation: Token can create comments and push branches on a test repo
- Evidence:
Claudeteam withwritepermission created in all 12 orgs, token validated (comment create/delete on issue #5,push: trueon k8s/flux, crossplane/harbor-resources)
- Add
Phase 2: Action Configuration
-
M3: Update workflow to use bot token
- Store the bot token as a Forgejo Actions secret (e.g.,
CLAUDE_BOT_TOKEN) - Update
claude.ymlworkflow to passgithub_token: ${{ secrets.CLAUDE_BOT_TOKEN }}instead of the human token - Update
bot_idandbot_nameinputs to match the new Forgejo user's ID and username - Document the token rotation procedure
- Validation: Action runs with bot token, comments appear as
claude-bot - Evidence:
CLAUDE_BOT_TOKENorg secret in all 12 orgs,claude.ymlupdated withbot_id: "48",bot_name: "claude-bot",bot_email: "claude@wxs.ro". Newbot_emailinput added toaction.yml. - Pending E2E: Trigger a real
@claudemention to verify comments appear asclaude-bot
- Store the bot token as a Forgejo Actions secret (e.g.,
-
M4: Verify git commit attribution
- Ensure
git config user.nameanduser.emailuse the bot user's identity - Verify that
src/github/operations/git-config.tscorrectly picks up the bot user info from the token - Test that pushed commits show the bot user as author in Forgejo UI
- Validation: A tag-mode response that creates a branch shows
claude-botas commit author - Evidence:
git-config.tsusesuser.emailwhen provided (falls back to noreply),context.tsreadsBOT_EMAILenv var, all call sites passbotEmail. 794 tests pass. - Pending E2E: Trigger a tag-mode response that creates a branch to verify commit authorship
- Ensure
Phase 3: Documentation & Hardening
- [~] M5: Update documentation and test across repos
- Update
docs/forgejo.mdwith bot user setup instructions (full 6-step guide added) - Document token rotation procedure (tokens expire, need renewal plan)
- Test the bot user setup on at least one additional repo beyond
claude-code-action - Update
CLAUDE.mdif any workflow changes affect development - Validation: Another developer can follow the docs to set up the bot user on a new Forgejo instance
- Update
Dependencies
- Forgejo admin access to git.wxs.ro (to create the user)
- Understanding of Forgejo's permission model (org membership, repo access)
Risks
| Risk | Mitigation |
|---|---|
| Token expiration | Document rotation procedure, set long-lived token or calendar reminder |
| Bot user locked out | Keep admin access to reset password/token |
| Permission too narrow | Start with write on repos, expand only if needed |
| Bot user confused with human in reviews | Set clear display name and avatar |
Success Criteria
- All Claude comments and commits on Forgejo repos appear as
claude-bot, not the human user - The bot token has minimal scoped permissions (no admin access)
- Documentation allows reproducing the setup on a fresh Forgejo instance
Implementation Notes
New bot_email Action Input
Added bot_email input to action.yml — when set, overrides the default noreply email format ({id}+{name}@users.noreply.{host}). On Forgejo, setting this to the bot user's registered email links commits to the bot's profile in the UI.
Org-Level Secrets
CLAUDE_BOT_TOKEN is stored as an org-level secret (not repo-level) in all 12 orgs with visibility: "all". This means any new repo in any org will automatically have access.
Team Structure
Each org has a Claude team with write permission on all repositories (includes_all_repositories: true). New repos are automatically covered.