LearnNewsExamplesServices
Frontmatter
id14388
titleAuto-provision AgentIdentity for GitLab PAT cloud users
stateClosed
labels
enhancementaiarchitecture
assigneesneo-gpt
createdAtJul 1, 2026, 1:20 PM
updatedAtJul 1, 2026, 3:26 PM
githubUrlhttps://github.com/neomjs/neo/issues/14388
authorneo-gpt
commentsCount2
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 1, 2026, 3:26 PM

Auto-provision AgentIdentity for GitLab PAT cloud users

Closed v13.1.0/archive-v13-1-0-chunk-8 enhancementaiarchitecture
neo-gpt
neo-gpt commented on Jul 1, 2026, 1:20 PM

Context

A GitLab-PAT authenticated Memory Core cloud deployment can validate a bearer token and stamp raw memory writes with the resolved provider username, but graph-gated Agent OS tools still fail if no matching AgentIdentity node already exists. This breaks first-use cloud deployments where agents authenticate with GitLab PATs instead of pre-seeded Neo maintainer identities.

Verified current behavior:

  • AuthService.createGitlabPatVerifier() validates Authorization: Bearer against {gitlabApiBaseUrl}/api/v4/user and returns userId: user.username, username: user.name || user.username, and source: 'gitlab-pat'.
  • memory-core Server.buildRequestContext() calls bindAgentIdentity(reqAuth.userId).
  • bindAgentIdentity() only looks up @${userId} and returns null on miss.
  • RequestContextService.unboundIdentityError() then causes Mailbox and Permission tools to reject the authenticated caller.
  • Observed cloud behavior: add_memory can persist under the authenticated GitLab username, while graph-gated tools such as list_messages and list_permissions reject because the caller has no matching AgentIdentity node.

The Problem

GitLab-PAT authentication proves a valid deployment principal. That principal is not necessarily pre-known to Neo's checked-in identityRoots.mjs, and cloud operators should not need to modify Neo source or run a Neo-maintainer seed workflow for every deployment user or agent account.

The current behavior conflates:

  1. authentication success and tenant identity via RequestContextService.getUserId(), and
  2. pre-existing AgentIdentity graph-node binding via getAgentIdentityNodeId().

This leaves authenticated cloud agents with partial functionality: raw memory writes work, but A2A mailbox, broadcast participation, permissions, turn presence, and related graph-backed Agent OS surfaces can fail before first use.

The Architectural Reality

  • ai/mcp/server/shared/services/AuthService.mjs owns GitLab-PAT bearer validation and already returns provider-derived user identity.
  • ai/mcp/server/memory-core/Server.mjs owns Memory Core request-context enrichment and AgentIdentity binding.
  • ai/mcp/server/shared/services/RequestContextService.mjs carries both userId and agentIdentityNodeId; graph-gated tools consume the latter.
  • ai/services/memory-core/MailboxService.mjs and PermissionService.mjs require a bound graph identity.
  • ai/services/memory-core/MailboxService.mjs treats accountType: 'agent' as the operational Agent OS routing role for AGENT:* broadcasts.
  • ai/graph/identityRoots.mjs is appropriate for Neo's built-in seeded identities, but it should not be the only way external cloud deployments get graph principals.

The Fix

Add an idempotent Memory Core auto-provision path for authenticated HTTP/SSE identities, starting with gitlab-pat.

Recommended implementation:

  1. Introduce a small graph helper, for example GraphService.ensureAgentIdentityForAuthContext() or a focused identity service, that receives { userId, username, source, provider metadata }.
  2. On successful gitlab-pat request-context build:
    • resolve canonical node id @${userId} or the existing normal form used by Memory Core
    • if the node exists as AgentIdentity, preserve it and update only safe last-auth metadata
    • if the node is missing, create a durable AgentIdentity
    • if an existing non-AgentIdentity node collides, fail closed with an actionable identity-collision error
  3. Auto-provisioned nodes use accountType: 'agent' because the authenticated principal is an Agent OS actor and must participate in A2A and broadcasts like any seeded agent.
  4. Do not infer provider-account nature. Do not write fields such as humanBacked, bot, or equivalent by default. PAT auth only proves a validated provider principal.
  5. Use provider-neutral metadata; do not require githubLogin for GitLab-only deployments:
    • authProvider: 'gitlab'
    • authSource: 'gitlab-pat'
    • providerBaseUrl
    • providerUserId when available from /api/v4/user
    • providerUsername
    • providerDisplayName
    • autoProvisioned: true
    • createdAt
    • lastAuthenticatedAt
  6. Trust must be deployment-authenticated, not unclassified. Under the current taxonomy use internal-authored, or introduce/configure a clearer deployment-trusted / tenant-trusted tier if that taxonomy change is chosen during implementation.
  7. Keep local stdio behavior deliberate: do not silently mask stale NEO_AGENT_IDENTITY typos unless the implementation explicitly opts local stdio into the same provisioning policy.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
GitLab-PAT request context AuthService.createGitlabPatVerifier() Valid bearer auth yields provider principal metadata usable for graph binding Invalid bearer remains an auth failure Cloud deployment auth docs Unit test for request-context payload
AgentIdentity node binding Server.buildRequestContext() plus graph identity helper Missing authenticated GitLab-PAT principal is idempotently created as AgentIdentity Non-AgentIdentity id collision fails closed Memory Core identity docs Unit tests for create/reuse/collision
A2A/mailbox/permission tools MailboxService, PermissionService, RequestContextService Graph-gated tools receive a non-null agentIdentityNodeId after provisioning Actionable unbound-identity error if provisioning fails MCP tool auth docs Unit tests for mailbox and permissions
Provider metadata AgentIdentity graph metadata Store provider-neutral fields such as authProvider, providerUsername, and providerBaseUrl Preserve existing seeded metadata when identity already exists Identity metadata docs Metadata assertion test
Trust classification Existing trust-tier taxonomy or new deployment/tenant tier Authenticated PAT identities are not unclassified Use internal-authored until a better deployment tier exists Deployment identity docs Trust-tier assertion test

Decision Record impact

none. This aligns with the existing Memory Core auth/request-context split and AgentIdentity graph substrate; it does not supersede an ADR.

Acceptance Criteria

  • A successful gitlab-pat authenticated Memory Core request auto-provisions a missing AgentIdentity node for the resolved provider principal before graph-gated tools need it.
  • The auto-provisioned node has accountType: 'agent' and participates in existing A2A, broadcast, mailbox, and permission flows without requiring source edits to ai/graph/identityRoots.mjs.
  • Auto-provisioned metadata is provider-neutral and GitLab-aware; no githubLogin field is required for GitLab-only identities.
  • The implementation does not infer human, bot, or provider-account nature; fields such as humanBacked and bot are not written by default.
  • Trust tier is not unclassified; implementation uses internal-authored or introduces/configures a deployment/tenant-trusted tier with tests and docs.
  • Existing seeded Neo AgentIdentity nodes are preserved and not overwritten except for safe last-auth metadata if applicable.
  • Existing non-AgentIdentity node collision at the target id fails closed with an actionable error.
  • Unit coverage proves: missing GitLab-PAT identity is provisioned; existing identity is reused; provider-neutral metadata is written; mailbox/permissions no longer fail for the provisioned principal; collision fails closed.
  • Docs describe the cloud behavior generically for GitLab-PAT deployments and do not require operators to edit identityRoots.mjs for first-use identities.

Out of Scope

  • OIDC-specific provisioning beyond keeping the design compatible.
  • Dedicated provider-account classification such as human vs bot vs service account.
  • Tenant membership or per-repo KB visibility changes.
  • Deployment image/tool-surface freshness diagnostics.
  • WAL, embedding, and session projection timing; delayed memory embedding remains expected behavior.

Avoided Traps / Gold Standards Rejected

  • Requiring every cloud deployment to edit Neo's identityRoots.mjs: rejected; that is Neo-team seed substrate, not tenant onboarding.
  • Falling back to raw userId without a graph node: rejected; graph-backed A2A, mailbox, and permission surfaces need durable node endpoints.
  • Creating reduced-rights "human" principals: rejected; authenticated PAT callers are operational Agent OS agents and must receive normal A2A and broadcast behavior.
  • GitHub-specific metadata: rejected; GitLab cloud deployments need provider-neutral identity fields.

Related

  • #13493 - related mode-aware unbound identity diagnostics; not a duplicate.
  • #13571 - related RequestContext/AgentIdentity/userId boundary work; not a duplicate.
  • #13431 / #12990 - related GitLab-PAT deployment-healthcheck seams; not duplicates.
  • #13041 - related AgentIdentity metadata evolution; not a duplicate.
  • #14145 - related Discussion about PAT-authenticated wake stream channels; not a duplicate.

Origin Session ID: 4cea162d-b6d0-4f80-9048-ae43a82508de

Handoff Retrieval Hints: GitLab PAT AgentIdentity auto-provision cloud user mailbox permissions, RequestContext agentIdentityNodeId gitlab-pat bindAgentIdentity unbound, provider-neutral AgentIdentity metadata authProvider providerUsername

Live latest-open sweep: checked latest 20 open issues on 2026-07-01; no equivalent found.

A2A in-flight sweep: checked latest 30 A2A messages immediately before creation on 2026-07-01; no overlapping claim found.

tobiu referenced in commit 674678f - "feat(memory-core): auto-provision GitLab PAT identities (#14388) (#14389)" on Jul 1, 2026, 3:26 PM
tobiu closed this issue on Jul 1, 2026, 3:26 PM