Skip to content

feat: inject short-lived scoped CLI credentials into agent sessions#4752

Open
supernandor wants to merge 2 commits into
feat/agents-inlinefrom
feat/agent-cli-credentials
Open

feat: inject short-lived scoped CLI credentials into agent sessions#4752
supernandor wants to merge 2 commits into
feat/agents-inlinefrom
feat/agent-cli-credentials

Conversation

@supernandor
Copy link
Copy Markdown
Contributor

Summary

Gives the managed agent CLI access to the SuperPlane API by injecting a short-lived scoped JWT token into the Anthropic session.

How it works

  1. Session creation → generates a 1h scoped JWT (locked to org, user, purpose agent)
  2. First message → prepends a CLI setup block that writes ~/.superplane.yaml with the token
  3. Session resume → auto-refreshes token if expired
  4. Agent runssuperplane CLI commands authenticate with the scoped token

What the agent sees (first message only)

[Agent CLI Setup — run this silently before any SuperPlane commands]
cat > ~/.superplane.yaml << 'SUPERPLANE_CONFIG_EOF'
contexts:
- apiToken: <short-lived-jwt>
  organization: <org-id>
  organizationId: <org-id>
  url: https://app.superplane.com
currentcontext: https://app.superplane.com/<org-id>
output: text
SUPERPLANE_CONFIG_EOF

[Canvas ID: <canvas-id>]
[Canvas version: <version>]

<user's actual question>

Security

  • 1h TTL — token expires quickly, limits blast radius
  • Org-scoped — can't access other organizations
  • Server-side injection — user never sees the token in browser
  • Ephemeral container — Anthropic destroys it when session ends

Changes

File Change
db/migrations/20260512210222_* Add api_token + api_token_expires_at columns
pkg/agents/service.go Token generation + auto-refresh
pkg/agents/store.go Store/retrieve token
pkg/agents/stream.go buildPrompt injects CLI config
pkg/agents/stream_test.go Tests for prompt building with/without token

Tests

  • TestBuildPrompt_WithToken_FirstMessage — verifies CLI setup injected
  • TestBuildPrompt_WithoutToken — verifies no setup when no token
  • All existing tests pass (13 total)

When creating an agent session, generate a 1-hour scoped JWT token
locked to the user's org. On the first message of each session (or
after token refresh), inject a CLI setup block that writes
~/.superplane.yaml with the token, org ID, and API URL.

This lets the agent's bash tool run SuperPlane CLI commands
authenticated as the user, scoped to their org, without exposing
long-lived tokens.

Changes:
- Migration: add api_token + api_token_expires_at to agent_sessions
- Service: generate scoped token on session create, auto-refresh on resume
- Stream: buildPrompt injects CLI config on first message
- Tests: buildPrompt with/without token, updated existing tests
@superplanehq-integration
Copy link
Copy Markdown

👋 Commands for maintainers:

  • /sp start - Start an ephemeral machine (takes ~30s)
  • /sp stop - Stop a running machine (auto-executed on pr close)

Instead of calling GetSession separately (which races with ListEvents),
detect session.status_idle and session.status_failed from the events
list itself. Since events are ordered, the idle event always comes
AFTER all agent.message events, guaranteeing the full response is
captured before we close the stream.

Also removes GetSession from the poll loop entirely — one fewer API
call per poll cycle.
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.

1 participant