7.9 KiB
Omnigent bot identities & attribution setup
This doc explains how commits and automated PR reviews in the
omnigent-ai/omnigent repo are attributed, and how the supporting GitHub App
was set up. There are two deliberately distinct identities — do not
conflate them:
| Identity | Used for | Why this identity |
|---|---|---|
omnigent <noreply@omnigent.ai> |
Co-author trailer on commits authored by polly's coding sub-agents | These commits are produced by git commit in a worker's local worktree — they are not GitHub Actions runs, so a plain org co-author is the honest attribution. No GitHub App user is involved. |
omnigent-ci[bot] (GitHub App) |
CI automation: lockfile-regen commits/PRs and automated PR-review comments | These actions genuinely run inside GitHub Actions, where the App's private key lives and a short-lived installation token is minted per run. The App is an org-owned, least-privilege identity. |
Why two identities and not one? An earlier draft of this work tried to use
omnigent-ci[bot]everywhere, including the sub-agent commit trailer. That was corrected: polly's workers don't run in Actions and never touch the App key, so attributing their commits to the Actions-minted bot user was misleading. Local work → plain org co-author; Actions-minted work → the App bot.
The GitHub App: omnigent-ci[bot]
Naming note. The App was registered as
omnigent-ci(the bareomnigentname was unavailable), so GitHub renders the actor asomnigent-ci[bot].
| Field | Value |
|---|---|
| App name | omnigent-ci |
| Bot actor | omnigent-ci[bot] |
| App ID | 4082516 |
| Bot numeric user ID | 294685417 |
| CI git author email | 294685417+omnigent-ci[bot]@users.noreply.github.com |
The numeric user ID (294685417) is what links GitHub's no-reply commit email
back to the bot's profile; it is distinct from the App ID (4082516), which is
used only to mint installation tokens.
Why a GitHub App (not a PAT or a plain machine user)? An App is an org-owned identity with scoped, least-privilege permissions and a short-lived installation token minted per run — no long-lived personal credential to leak.
Org-admin setup (one-time, completed)
These steps required org-admin and are done. They are recorded here because they are not captured anywhere in the repo and would otherwise have to be reverse-engineered.
1. Create the App
Created at https://github.com/organizations/omnigent-ai/settings/apps/new:
- GitHub App name:
omnigent-ci→ actoromnigent-ci[bot]. - Homepage URL: any valid URL.
- Webhook: Active unchecked — token-minting only, no webhook.
- Repository permissions (least privilege):
- Contents: Read and write — push branches / commits.
- Pull requests: Read and write — open/update PRs and post reviews.
- Metadata: Read-only (mandatory).
- Everything else No access.
- Where can this App be installed? Only on
omnigent-ai. - Installed into
omnigent-ai, scoped to theomnigentrepo.
App ID 4082516. A private key (.pem) was generated and stored as a
secret (step 3).
Optional/cosmetic: App settings → Display information → upload a square logo. Purely visual — does not affect the user ID, attribution, or wiring.
2. Resolve the bot's numeric user ID
GitHub's no-reply commit email embeds a numeric user ID assigned after install:
gh api users/omnigent-ci%5Bbot%5D --jq '.id'
# -> 294685417
(%5Bbot%5D is the URL-encoding of [bot].)
3. Store the App credentials
In omnigent-ai/omnigent → Settings → Secrets and variables → Actions:
- Variable
OMNIGENT_BOT_APP_ID=4082516 - Secret
OMNIGENT_BOT_APP_KEY= the App's.pemprivate key
The workflows gate on
vars.OMNIGENT_BOT_APP_ID != ''. If the variable is absent or misnamed, the token-mint step is skipped and the workflow falls back toGITHUB_TOKEN(attributing the action togithub-actions[bot]) — so the exact names matter.
omnigent-ci[bot]replaced the old OSS regen bot. The previousOSS_REGEN_APP_ID/OSS_REGEN_APP_KEYconfig and its App have been retired; nothing in the repo referencesOSS_REGEN_*anymore.
In-repo wiring (shipped)
Sub-agent commit co-author trailer
polly never commits directly; its coding sub-agents (claude_code, codex,
pi) run git commit / gh pr create in their own worktrees. Each such commit
ends with a co-author trailer attributing it to the org:
Co-authored-by: omnigent <noreply@omnigent.ai>
This requirement lives in the worker IMPLEMENT instructions:
examples/polly/agents/claude_code/config.yamlexamples/polly/agents/codex/config.yamlexamples/polly/agents/pi/config.yaml
A
Co-authored-bytrailer is GitHub's lightweight attribution mechanism — it attributes the commit to the org in addition to the worker author and needs no signing key. It is not cryptographic signing (GPG/sigstore), which is a separate, heavier concern.
The packaged copies under
omnigent/resources/examples/polly/...are a symlink to theexamples/polly/...source, so there is a single source of truth — no dual copies to keep in sync.
CI commits/PRs as omnigent-ci[bot]
The lockfile-regen workflows (.github/workflows/oss-regenerate-and-smoke.yml
and oss-regen-on-comment.yml) mint the App token and set the git identity so
regen commits/PRs are authored by the bot:
- name: Mint App token
id: app-token
if: vars.OMNIGENT_BOT_APP_ID != ''
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
app-id: ${{ vars.OMNIGENT_BOT_APP_ID }}
private-key: ${{ secrets.OMNIGENT_BOT_APP_KEY }}
git config user.name "omnigent-ci[bot]"
git config user.email "294685417+omnigent-ci[bot]@users.noreply.github.com"
The push uses steps.app-token.outputs.token || secrets.GITHUB_TOKEN, so a
missing App config falls back to github-actions[bot] rather than failing.
Automated PR review posted as omnigent-ci[bot]
.github/workflows/polly-review.yml runs a full cross-vendor Polly review of a
PR diff (on PR open/reopen/ready, a /review comment from a write-access user,
or workflow_dispatch) and posts the findings as a PR comment. It mints the App
token and posts the review as omnigent-ci[bot]:
- name: Mint App token
id: app-token
if: steps.trigger.outputs.skip != 'true' && steps.creds.outputs.available == 'true' && vars.OMNIGENT_BOT_APP_ID != ''
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
app-id: ${{ vars.OMNIGENT_BOT_APP_ID }}
private-key: ${{ secrets.OMNIGENT_BOT_APP_KEY }}
- name: Post review comment
env:
GH_TOKEN: ${{ steps.app-token.outputs.token || github.token }}
# ...
Fail-open by design. If the App vars are absent, the post falls back to
github.tokenand the review still posts (asgithub-actions[bot]). The review content is valuable regardless of who signs it — this is deliberately the opposite of a fail-closed posting gate. The workflow always checks out the trusted default branch and fetches the PR diff via the API; PR-authored code is never executed, and the minted token is scoped to the post step only.
Quick reference
| Surface | Identity on the artifact | Where it's wired |
|---|---|---|
| polly sub-agent commits | omnigent <noreply@omnigent.ai> (co-author trailer) |
examples/polly/agents/*/config.yaml |
| Lockfile-regen commits/PRs | omnigent-ci[bot] |
oss-regenerate-and-smoke.yml, oss-regen-on-comment.yml |
| Automated PR review comments | omnigent-ci[bot] (fallback github-actions[bot]) |
polly-review.yml |
Config: variable OMNIGENT_BOT_APP_ID = 4082516, secret
OMNIGENT_BOT_APP_KEY = App private key. The old OSS_REGEN_APP_* config and
App are retired.