Skip to content

Support registration Agent Key credentials for NyxID workflow llm_call #3649

Description

@louis4li

Problem

Channel default skills can run in registration_agent_key mode, and the registration Agent Key is already used for Ornn/private skill access, connected-service discovery, and downstream proxy tools. However, a workflow llm_call fails when executed from a no-login channel turn:

llm_request_failed: NyxID authentication required for provider 'nyxid'. Please sign in.

Observed failure point:

  • src/Aevatar.AI.LLMProviders.NyxId/NyxIdLLMProvider.cs
  • ResolveAccessTokenWithSource() only accepts:
    • CallerContext.Credentials.NyxIdBearer
    • LlmControl.NyxIdAccessToken
    • host accessor token

It does not accept a registration Agent Key credential, so channel no-init workflows containing llm_call require user login even when the registration already has a ready Agent Key.

Expected behavior

For channel turns configured with:

"credential_source_mode": "registration_agent_key"

workflow llm_call should be able to call the NyxID LLM route using the registration Agent Key, subject to NyxID Agent Key scopes and allowed service grants.

The Agent Key should not be treated as a user login bearer identity. It should remain a registration-owned credential, with audit context preserving:

  • registration id
  • scope id
  • channel platform
  • conversation id
  • sender id
  • Agent Key id/prefix, not raw secret

Relevant existing behavior

The repository already has a similar pattern for managed Codex:

  • src/Aevatar.AI.Infrastructure.ChronoSandbox/NyxIdCodeExecutionPort.cs

That code explicitly keeps Agent Keys as bearer caller credentials when calling NyxID:

// Agent Keys must remain bearer caller credentials here. NyxID authenticates
// them and forwards the same Authorization value to Chrono on admitted routes.

This pattern should be reused or abstracted instead of inventing a second credential transport.

NyxID route

NyxIdLLMProvider uses OpenAI-compatible routing through NyxID:

Gateway:

/api/v1/llm/gateway/v1

Or configured/proxy route:

/api/v1/proxy/s/{serviceSlug}
/api/v1/proxy/{serviceId}

The active registration Agent Key can already include chrono-llm-public in allowed_services, so the intended practical route can be:

/api/v1/proxy/s/chrono-llm-public

or gateway if NyxID confirms gateway Agent Key admission.

Proposed implementation

  1. Extend the LLM credential model

Add a typed credential source for NyxID Agent Key, rather than stuffing Agent Key into NyxIdAccessToken.

Example shape:

CallerContext.Credentials.NyxIdAgentKey
CallerContext.Credentials.NyxIdCredentialKind = AgentKey

Preserve existing bearer behavior.

  1. Resolve registration Agent Key before workflow llm_call

When channel runtime starts a workflow from a registration with credential_source_mode=registration_agent_key, resolve the stored ChannelNyxIdAgentKey secret reference.

Attach it to the workflow run caller context or LLM caller context as typed Agent Key material.

Do not expose the raw key in logs, metadata bags, read models, or tool receipts.

  1. Update NyxIdLLMProvider

Replace ResolveAccessTokenWithSource() with a typed credential resolver.

Support:

  • user bearer
  • LLM control bearer
  • registration Agent Key
  • host accessor token

For Agent Key, send it to NyxID using the same bearer credential transport used by managed Codex:

Authorization: Bearer <agent-key>

Log only credential kind/source and length/prefix-safe metadata.

  1. Reuse or extract common NyxID credential transport

Current Codex path has Agent Key-specific proxy handling. Extract common logic if possible, for example:

  • normalize NyxID credential
  • classify credential kind
  • build Authorization header
  • preserve exact UserService selector

Avoid duplicating "Agent Key as bearer caller credential" logic in both Codex and LLM provider.

  1. Route selection

Prefer configured LLM proxy route when available, especially chrono-llm-public, because it can be allowlisted on Agent Keys like other services.

Keep gateway support if NyxID confirms /api/v1/llm/gateway/v1 admits Agent Keys.

If gateway rejects Agent Key, return a clear diagnostic:

nyxid_llm_agent_key_not_admitted

rather than falling back to "Please sign in."

Acceptance criteria

  • A Telegram/default skill workflow with registration_agent_key can execute an llm_call without sender /init.
  • The same workflow still works for sender-bound/user bearer mode.
  • If the Agent Key lacks LLM service permission, failure is explicit and classified as authorization, not login required.
  • Existing Codex Agent Key behavior remains unchanged.
  • Logs show credential source as registration-agent-key but never log the raw key.
  • Tests cover:
    • NyxIdLLMProvider resolves bearer credentials as before.
    • NyxIdLLMProvider resolves Agent Key credentials and sends them as bearer caller credentials.
    • channel workflow llm_call receives registration credential context.
    • missing LLM grant produces a clear authorization failure.
    • no credential still produces the existing sign-in-required failure.

Notes

Do not model this as sender login. The subject is the registration/bot authority, not the Telegram sender. Sender identity should remain trigger/audit context only.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions