LearnNewsExamplesServices
Frontmatter
id10860
titleOptional per-agent GitHub credentials: operator-supplied identity→token mapping
stateClosed
labels
enhancementaiarchitecturemodel-experience
assigneesneo-opus-ada
createdAtMay 7, 2026, 1:12 AM
updatedAtJun 13, 2026, 5:59 PM
githubUrlhttps://github.com/neomjs/neo/issues/10860
authorneo-opus-ada
commentsCount3
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 7, 2026, 1:25 AM

Optional per-agent GitHub credentials: operator-supplied identity→token mapping

Closed v13.0.0/archive-v13-0-0-chunk-8 enhancementaiarchitecturemodel-experience
neo-opus-ada
neo-opus-ada commented on May 7, 2026, 1:12 AM

Context

The github-workflow MCP server currently authenticates all calls via a single GH_TOKEN env var loaded at startup. For deployments where multiple agents share one GitHub user (typical single-operator deployments), this is correct. For deployments where the operator wants per-agent GitHub-attribution (e.g., multiple agents authoring distinct PRs / commits / comments under separate GitHub users), the current substrate provides no enabling primitive.

This ticket is preventive operational substrate / MX hardening. It introduces an OPTIONAL primitive that lets operators configure per-agent token resolution — without mandating per-agent credentials and without baking specific identities into the substrate.

This ticket supersedes #10858, which baked specific agent identities into env-var naming (an anti-pattern for external operators with their own agent identities).

The Problem

For multi-agent deployments where per-agent GitHub-attribution matters:

  • All agents currently appear as the same GitHub user in PR/commit/issue authorship.
  • Audit logs cannot distinguish which agent identity actually performed an action.
  • Operators have no substrate-level mechanism to map agent identities to distinct PATs.

The Architectural Reality

  • RequestContextService.getAgentIdentityNodeId() exposes the calling agent's identity at MCP boundary.
  • The github-workflow MCP server reads credentials at startup; no per-call token selection.
  • An operator-supplied mapping (file or env-set) keyed by agent identity is the simplest enabling primitive — operators define their own naming conventions, identities, and granularity.

The Fix

  1. Optional config file at operator-defined path:
    • Env var NEO_GH_CREDENTIALS_FILE (default unset → falls through to legacy single-token behavior)
    • File format: JSON object mapping agent identity → PAT
       {
      "@neo-opus-ada": "ghp_xxx",
      "@neo-gemini-pro": "ghp_yyy",
      "@external-deployment-agent-1": "ghp_zzz"
    }
    • Gitignored; operator-managed; permission 0600 recommended.
  2. Token resolution helper in github-workflow MCP server:
    • At each authenticated call, get RequestContextService.getAgentIdentityNodeId().
    • If credentials file is configured AND has an entry for this identity → use that token.
    • Else fall through to legacy GH_TOKEN env var (backward-compat for single-operator deployments).
    • Audit log emits { agentIdentity, githubUser, tokenSource: 'mapping' | 'legacy' } per call.
  3. Documentation in learn/agentos/per-agent-credentials.md:
    • When per-agent credentials matter (which deployments benefit)
    • How to set up the credentials file
    • Operator-side PAT scope recommendations
    • Mapping file is OPTIONAL; default behavior unchanged

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback / Edge Case Docs Evidence
NEO_GH_CREDENTIALS_FILE env var Operator Path to JSON mapping file; unset → legacy behavior Unset / file-missing → legacy GH_TOKEN used; logged once at startup learn/agentos/per-agent-credentials.md (new) Unit test: unset-uses-legacy, set-uses-mapping, missing-identity-falls-back
Mapping file format Operator-supplied JSON object: { agentIdentityNodeId: pat } Malformed JSON → ERROR + refuse to start github-workflow MCP (fail-fast) Same Unit test: malformed-rejected
RequestContextService.getAgentIdentityNodeId() → token resolution github-workflow MCP server helper Maps agent ID via mapping file; falls through to legacy Returns null if no source available; tools refuse with structured error Same Unit test: identity-without-token-refuses-cleanly
Audit log per call github-workflow MCP server Logs { agentIdentity, githubUser, tokenSource } Standard log level Same Verify in integration test

Acceptance Criteria

  • NEO_GH_CREDENTIALS_FILE env var honored by github-workflow MCP at startup
  • Token resolution helper looks up per-agent mapping; falls through to legacy GH_TOKEN
  • Audit log emits { agentIdentity, githubUser, tokenSource } per authenticated call
  • Malformed credentials file → fail-fast with clear error message at startup
  • learn/agentos/per-agent-credentials.md documenting setup + when-to-use
  • Unit tests: (a) no mapping → legacy used, (b) mapping with match → mapping used, (c) mapping without match → legacy used, (d) malformed file → fail-fast, (e) audit log content
  • No regression for existing single-GH_TOKEN deployments

Out of Scope

  • Per-agent PAT generation/rotation tooling (operator-side concern)
  • Encrypted credentials file (separate hardening primitive)
  • Cross-machine credentials replication
  • Mandating per-agent credentials (this is an OPTIONAL enabling primitive; default behavior unchanged)

Avoided Traps / Gold Standards Rejected

  • Per-agent env-var naming convention (e.g., GH_TOKEN_<NORMALIZED_AGENT_ID>) — superseded #10858; bakes specific identities into substrate, breaks for external operators with arbitrary agent identities. The operator-supplied mapping file supports arbitrary identities by design.
  • Per-MCP-session credential negotiation — would require MCP transport changes; operator-supplied file is simpler + sufficient for v1.
  • Single shared service-account PAT with custom commit author signing — doesn't fix attribution at GitHub-API level; only changes commit author email which is a different surface.
  • OAuth flows replacing PAT — out of scope; current substrate uses PAT.

Related

  • Supersedes #10858 (closed as design-flawed)
  • Pairs conceptually with #10859 (per-domain env-file split) — both improve operator credential hygiene without mandating any single deployment shape

Origin Session ID: 8b31fd62-6a53-40b5-aae2-c5288f8ced09 Retrieval Hint: "optional per-agent GitHub credentials operator-supplied mapping file github-workflow MCP token resolution"

Ram9199
Ram9199 Jun 13, 2026, 5:41 PM

I am collecting real-world incidents around multi-agent credentials and attribution.

Was optional per-agent GitHub credential mapping driven by actual incidents or audit failures where all agents shared one GitHub identity, or is it preventive hardening? What changed afterward - per-agent PATs, audit logs, split credentials, manual review, or no change?

Not asking about any product. I am trying to identify repeated behavior after agent-authority and attribution failures.

tobiu
tobiu Jun 13, 2026, 5:59 PM

Hi @Ram9199 !

Around a year ago, I started with one agent, and we shared my tobiu account. The agent just identified itself via notes inside comments. Of course this could not scale, since other agents would need to parse all comments to see who created what. Plus, it led to severe identity crisis => "who am i?".

Separate identities resolve it, and enable GitHub notifications.

It goes deeper though: Each agent needs an own neo memory-core identity and session ids, plus own agent harness memory markdown files on top of this. Right now, each agent has an own repo clone folder, with different .env files. A bit brittle to manage manually, so the next logical step after v13 just got released is an own agent harness, which covers the fleet manager. not as sub-agents, but as an equal flat peer model, where each agent is a repo maintainer.

They ideate and coordinate on their own via A2A messages plus reading peers memories (telepathy), and apply rather rigorous cross model family PR reviews, until reaching the approved state inside several iterations.

Best regards, Tobi