Skip to content

feat(adk): a secret-free bash environment with the turn's git identity #290

Open

Description

@teemow

Problem

The bash tool runs a model-written command on an allowlisted environment (commandEnvNames in go/adk/pkg/tools/shell.go, carried as fix(adk): run bash tool commands on an allowlisted environment, #303): PATH, HOME, USER, LOGNAME, LANG, LC_*, TERM, TZ, TMPDIR and the CA-bundle variables. The model keys, the controller token and every KAGENT_* variable stay in the runtime (kagent-dev#3002; the open kagent-dev#3014 strips by name instead). The allowlist admits neither GH_TOKEN nor a git identity, so the Harness images' gh (#288) runs gh --version but every authenticated call fails on the kagent Harness. A coding agent working as the person needs two things in that environment and nothing else secret:

  • An inert placeholder token for the provider's CLI. gh refuses every API call without GH_TOKEN; in a Session with caller credentials (feat(egress): caller credentials per Session through Substrate's actor-JWT exchange #297) the egress gateway replaces the header gh sends with the person's token, so the placeholder only has to exist. Nothing sets it today, the allowlist withholds it, and a strip by name (TOKEN) would remove it.
  • git's author and committer identity. Without one git commit fails ("Please tell me who you are") or records the sandbox's user, so nothing the agent commits is attributed to the person. The runtime knows the person of the turn: the identity the a2a gateway forwards as x-kagent-user, which the Go ADK already sets on every model call.

Proposed solution

The carried allowlist gains, per turn, GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, GIT_COMMITTER_NAME and GIT_COMMITTER_EMAIL from the turn's user identity (the email; the name the forwarded identity carries, otherwise the email), and GH_TOKEN set to the translator's inert placeholder value (kagent-credential-injected) in a turn whose dispatch names a workspace directory (#296's working-directory header), so the CLI runs and the gateway does the authentication. The allowlist admits the inert placeholder only: a real token in the runtime's environment never reaches the command. A session without claims (unsecure mode, an agent's propagated caller id) gets no identity variables, so git's own error stands rather than a stand-in author. Built on kagent-dev#3014: the allow-list is proposed there as the shape that keeps a placeholder, and carried on the fork line until upstream settles it.

Acceptance criteria

Activity

  1. teemow commented on Oct 18, 2026

    @teemow
    MemberAuthor

    Checked against the criteria: #598 (merged) delivers the first two (unit tests TestExecuteCommand_TurnEnvironment, TestExecuteCommand_CommitsAsThePersonOfEachTurn), now ticked. Left open: the gh api user fork e2e is #292 (still open) and #297 (blocker) is still open; the FORK.md row is unconfirmed here.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    • Status
      Backlog 📦

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions