Skip to content

feat: add authenticated caller-tool delegation for git agents - #102

Draft
adityathebe wants to merge 4 commits into
mainfrom
feat/git-agent-caller-tools
Draft

feat: add authenticated caller-tool delegation for git agents#102
adityathebe wants to merge 4 commits into
mainfrom
feat/git-agent-caller-tools

Conversation

@adityathebe

@adityathebe adityathebe commented Aug 26, 2026

Copy link
Copy Markdown
Member

Problem

Remote Git agents can run prompts, but they cannot safely use tools owned by the Captain supervisor. Passing supervisor credentials or unrestricted tool access through Git would persist secrets and widen the remote agent’s authority.

This PR adds task-scoped caller-tool delegation. An operator can select a remote Git agent and the exact supervisor tools it may request while the supervisor remains responsible for authorization, approval, and execution.

Security model

  • The supervisor intersects the requested tools with the parent run’s resolved tool definitions. Delegation can narrow authority but never widen it.
  • A fresh capability is bound to one task, agent, and expiry. The durable dispatch token only authenticates delivery over the enrolled sidecar’s pinned HTTPS control channel; the delegated credential is never stored in Git or exposed to the browser.
  • The sidecar stores the credential in a mode-0600 task file, consumes it before starting the model, and proxies local MCP calls back to the supervisor over pinned HTTPS.
  • Every call revalidates the credential, task and agent binding, expiry or revocation, delegated tool name, input schema, and approval policy.
  • Capabilities expire and are revoked when the task finishes. After a sidecar restart, stale secrets are deleted because their in-memory sessions cannot be recovered, so delegation fails closed.

Behavior changes

  • Chat can select a remote Git-agent backend, agent, and explicit supervisor-tool allowlist. Browser state contains only that selection, never credentials.
  • Delegated caller tools require an enrolled HTTPS sidecar and an Agent runtime; unsupported CLI and cmux combinations are rejected.
  • /git/ is now explicitly routed to Git smart HTTP instead of falling through to the SPA.
  • Loopback requests without credentials remain exempt from authentication. Loopback requests that provide an Authorization header are now verified, so stale or invalid local tokens return 401.

Issue task-bound caller-tool capabilities from the supervisor and deliver them through the authenticated HTTPS sidecar control channel without placing credentials in Git protocol data.

Restrict discovery and execution to the parent-authorized allowlist, recheck task and agent bindings on every call, and revoke or expire capabilities with secret-free audit events.

Amp-Thread-ID: https://ampcode.com/threads/T-01a03e3c-39ce-714c-b7fe-60010c4f452f
@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown

Gavel summary

Source Pass Fail Skip Duration

Totals: 0 passed · 0 failed · 0 skipped · -

View full results

Comment thread pkg/gitagent/callertools.go Fixed
Comment thread pkg/gitagent/callertools.go Fixed
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown

Gavel summary

Source Pass Fail Skip Duration
agentcreds 11 0 0 785.367µs
ai 87 0 0 27ms
aichat 135 0 2 14.1s
anthropicmock 1 0 0 957.245µs
api 223 0 0 63ms
attachments 5 0 0 2ms
bash 4 0 0 152.986µs
callertools 10 0 0 83ms
captain 17 0 0 11.0s
claude 22 0 0 25ms
claudeagent 13 0 0 186ms
cli 239 0 0 6.3s
cmux 4 0 0 1ms
collections 12 0 0 1ms
credentials 5 0 0 59ms
credsync 11 0 0 316ms
database 20 0 0 5.5s
deploy 110 0 0 209ms
genkit 25 0 0 65ms
gitagent 122 0 0 14.5s
github.com/flanksource/captain/migrations 11 0 0 2.9s
github.com/flanksource/captain/pkg/ai 250 0 0 930ms
github.com/flanksource/captain/pkg/ai/agent 26 0 0 450ms
github.com/flanksource/captain/pkg/ai/agent/commit 56 0 0 4.5s
github.com/flanksource/captain/pkg/ai/agent/setup 16 0 0 70ms
github.com/flanksource/captain/pkg/ai/agent/verify 21 0 0 390ms
github.com/flanksource/captain/pkg/ai/agent/worktree 6 0 0 -
github.com/flanksource/captain/pkg/ai/assistanttags 15 0 0 -
github.com/flanksource/captain/pkg/ai/fixture 42 0 0 290ms
github.com/flanksource/captain/pkg/ai/fixture/kubeproxy 2 0 0 180ms
github.com/flanksource/captain/pkg/ai/fixture/mcpproxy 6 0 0 -
github.com/flanksource/captain/pkg/ai/history 54 0 0 20ms
github.com/flanksource/captain/pkg/ai/internal/gen-model-registry 12 0 0 -
github.com/flanksource/captain/pkg/ai/middleware 25 0 0 -
github.com/flanksource/captain/pkg/ai/pricing 9 0 0 -
github.com/flanksource/captain/pkg/ai/prompt 16 0 0 10ms
github.com/flanksource/captain/pkg/ai/provider 169 0 1 -
github.com/flanksource/captain/pkg/ai/provider/claudeagent 54 0 0 1.3s
github.com/flanksource/captain/pkg/ai/provider/cmux 128 0 0 860ms
github.com/flanksource/captain/pkg/ai/provider/genkit 36 0 0 10ms
github.com/flanksource/captain/pkg/ai/provider/jsonrpc 6 0 0 50ms
github.com/flanksource/captain/pkg/aichat 9 0 0 100ms
github.com/flanksource/captain/pkg/aimock 50 0 7 200ms
github.com/flanksource/captain/pkg/aimock/anthropicmock 14 0 0 -
github.com/flanksource/captain/pkg/aimock/openaimock 18 0 0 50ms
github.com/flanksource/captain/pkg/api 143 0 0 340ms
github.com/flanksource/captain/pkg/api/registry 96 0 0 -
github.com/flanksource/captain/pkg/bash 348 0 0 10ms
github.com/flanksource/captain/pkg/captainconfig 25 0 0 -
github.com/flanksource/captain/pkg/captaintoken 23 0 0 1.1s
github.com/flanksource/captain/pkg/claude 138 0 0 10ms
github.com/flanksource/captain/pkg/claude/tools 18 0 0 -
github.com/flanksource/captain/pkg/cli 779 0 1 1m8s
github.com/flanksource/captain/pkg/cmux 1 0 0 -
github.com/flanksource/captain/pkg/codexconfig 10 0 0 -
github.com/flanksource/captain/pkg/container 72 0 1 -
github.com/flanksource/captain/pkg/database 130 0 0 17.3s
github.com/flanksource/captain/pkg/dod 11 0 0 1m0s
github.com/flanksource/captain/pkg/gitagent 31 0 0 300ms
github.com/flanksource/captain/pkg/gitagent/proxy 12 0 0 -
github.com/flanksource/captain/pkg/monitor 60 0 0 2.8s
github.com/flanksource/captain/pkg/sandbox 13 0 0 -
github.com/flanksource/captain/pkg/sandbox/adapter 39 0 0 20ms
github.com/flanksource/captain/pkg/sandbox/presets 13 0 0 -
github.com/flanksource/captain/pkg/session 70 0 0 10ms
history 69 0 0 15ms
migrations 12 0 0 4.1s
openaimock 2 0 0 138.085µs
provider 12 0 0 12ms
registry 38 0 0 6ms
session 28 0 0 11ms
tools 53 0 0 2ms

Totals: 4373 passed · 0 failed · 12 skipped · 3m38s

View full results

Chat requests previously had no supported way to select a remote Git agent and delegated caller tools, leaving authenticated delegation reachable only through lower-level runtime configuration.

Expose sandbox, agent, and tool selection in chat; resolve that untrusted selection server-side; preserve ordered tool policy through execution and approval continuations; and validate caller-tool input before approval brokerage. Consume clicky-ui 0.3.27 so overlapping Agent and CLI model selections remain coherent.

Amp-Thread-ID: https://ampcode.com/threads/T-01a03e3c-39ce-714c-b7fe-60010c4f452f
@socket-security

socket-security Bot commented Aug 28, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​@​flanksource/​clicky-ui@​0.3.277510010096100

View full report

CodeQL traced task-derived values into ordinary filesystem path operations used for transient capability secrets. Task IDs were constrained, but the storage boundary still depended on that validation and could follow a replaced state-directory symlink.

Create, read, remove, and clean up those secrets through os.Root with exclusive 0600 files, confining every task-relative name to the sidecar repository.

Amp-Thread-ID: https://ampcode.com/threads/T-01a03e3c-39ce-714c-b7fe-60010c4f452f
Review found duplicate capability validation, opaque schema-validation placement, a hand-written proxy that could buffer future streamed responses, and imprecise expired-session re-registration.

Keep one final liveness check, document the synthetic input and route-carrier invariants, use a streaming ReverseProxy, retire expired sessions without racing replacement grants, and make the runner's caller-tool endpoint argument explicit.

Amp-Thread-ID: https://ampcode.com/threads/T-01a03e3c-39ce-714c-b7fe-60010c4f452f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants