Skip to content

feat(agent-relay-cursor): add credential_kind for shared service-account keys - #1141

Open
Emyrk wants to merge 4 commits into
mainfrom
cursor-api-key-credential
Open

Emyrk wants to merge 4 commits into
mainfrom
cursor-api-key-credential

Conversation

@Emyrk

@Emyrk Emyrk commented Sep 22, 2026

Copy link
Copy Markdown
Member

Description

Agent Relay's per-pool insecure_shared_token (coder/agent-relay#70) stamps the team service-account key into the worker instead of a per-user sub-token, for CLI releases that refuse delegated tokens. The module handed every credential to the CLI as --auth-token, which the CLI only accepts for worker tokens; with the shared key the worker died on start:

Error: Failed to validate worker account settings: If you are logged in, try logging out and back in.

Verified on dogfood: the same key as CURSOR_API_KEY is classified team_api_key, authenticates, and registers to the pool.

  • New persistent parameter agent_relay_cursor_credential_kind (worker_token default, api_key), exported as AGENT_RELAY_CURSOR_CREDENTIAL_KIND. Agent Relay stamps it from the pool's insecure_shared_token (relay PR to follow), so no template variable has to be kept in step with pool config.
  • Supervisor branches at run time: api_key exports CURSOR_API_KEY="$AGENT_RELAY_CURSOR_TOKEN" and omits --auth-token; worker_token is unchanged. Both read the value from the environment; nothing lands in the file.
  • Defaults to worker_token, so a relay that does not stamp the parameter yet behaves exactly as before.
  • README documents the pairing and the exposure it implies.
  • tftest covers the parameter, its env export, and both rendered paths. Container test drives the supervisor with AGENT_RELAY_CURSOR_CREDENTIAL_KIND=api_key: stub worker sees CURSOR_API_KEY, no --auth-token in argv, literal key absent from supervise.sh.

Type of Change

  • New module
  • New template
  • Bug fix
  • Feature/enhancement
  • Documentation
  • Other

Module Information

Path: registry/coder/modules/agent-relay-cursor
New version: v0.2.0
Breaking change: [ ] Yes [x] No

Testing & Validation

  • Tests pass (terraform test 10 runs, bun test 18 tests)
  • Code formatted (bun fmt)
  • Changes tested locally

Related Issues

coder/agent-relay#70


Opened by Coder Agents on behalf of @Emyrk.

…unt keys

Agent Relay's insecure_shared_token stamps the pool's team service-account
key instead of a per-user sub-token. The Cursor CLI accepts that key
only as CURSOR_API_KEY; as --auth-token it fails with "Failed to
validate worker account settings". credential_kind = "api_key" exports
the credential as CURSOR_API_KEY in the supervisor and drops
--auth-token. The default worker_token is unchanged.

<sub>Coder Agents on behalf of @Emyrk.</sub>
…as a module block

<sub>Coder Agents on behalf of @Emyrk.</sub>
<sub>Coder Agents on behalf of @Emyrk.</sub>
@github-actions

github-actions Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Module Scorecard Check

coder/agent-relay-cursor: 71 → 52

⚠️ Score regression: 71 → 52 (-19). Check the drilldown for which criteria dropped.

Theme Before After
Presentation & Onboarding 5 / 17 6 / 17
Integration 20 / 25 0 / 25
Credential Hygiene 20 / 20 20 / 20
Restricted-Environment 10 / 20 12 / 20
Engineering Quality 10 / 10 10 / 10
Overall 71 / 100 52 / 100
Full scorecard for this PR
Presentation & Onboarding Agent Integration Credential Hygiene Restricted-Environment Readiness Engineering Quality Overall
6 / 17 0 / 25 20 / 20 12 / 20 10 / 10 52 / 100
Drilldown

Presentation & Onboarding — 6 / 17

Criterion Max Score Notes
Configuration-mode examples 12 6 The README shows one HCL example (install_cli = true) with a comment explaining the install_cli = false path. The shared-token path is documented in a table. However, computer_use = true, cli_binary override, and the shared-token HCL usage each lack a dedicated example block. Major modes are described but not all have their own HCL snippet.
Visual preview 5 0 No image, GIF, or video embedded in the README. The frontmatter icon field is a registry listing icon, not a visual preview of the module in action.

Agent Integration — 0 / 25

Criterion Max Score Notes
AI governance 10 0 No mention of Coder AI Gateway or Agent Firewall in the README or source. The Agent Relay credential flow (service-account → sub-token) is documented, but neither AI Gateway nor Agent Firewall is referenced as a governance mechanism.
Dashboard entry point 5 0 No coder_app resource declared or documented. The module is a background worker; no dashboard launch path is provided.
Session continuity 5 0 The README states the token "is not refreshed: a worker that has to reconnect after expiry fails and Cursor re-queues the request for a fresh workspace." No session-resume, session-ID persistence, or persistent session manager (tmux, screen, boo) is documented.
Managed configuration 5 0 No documentation of managed MCP servers, agent settings, policies, or workdir configuration. The module only runs the CLI worker; it does not configure the agent's tooling or settings.

Credential Hygiene — 20 / 20

Criterion Max Score Notes
Secrets marked sensitive 16 16 agent_relay_credential uses mask_input = true in its styling and is ephemeral = true. The README example contains no inline secrets—only agent_id = coder_agent.main.id. The token is passed via coder_env and the README explicitly states "It is never written to disk."
Non-hardcoded auth path 4 4 The README documents that "the pool's service-account API key never leaves Agent Relay" and that the relay mints a per-user sub-token at dispatch. No raw key is pasted into templates. The shared-token fallback path is also documented with a table.

Restricted-Environment Readiness — 12 / 20

Criterion Max Score Notes
Mirrorable artifact source 5 0 The install URL https://cursor.com/install is hardcoded in install.sh.tftpl. No module input variable overrides this URL. cli_binary changes the binary path, not the download source; install_cli toggles the download on/off. No variable replaces the download URL.
Bring-your-own binary 10 10 install_cli = false is documented in the README example comment ("Bake the CLI into the image and set this to false for faster workspaces") and in the variable description. The install script checks command -v and skips when the binary is present. The start script adds ~/.local/bin to PATH unconditionally.
Egress transparency 3 0 No dedicated README section enumerates external endpoints. cursor.com/install appears only in the install script and the install_cli variable description in main.tf. Cursor's API endpoints are implied by the worker but never listed. No air-gapped or restricted-network guidance section exists.
Runs without sudo 2 2 All three scripts (install.sh.tftpl, start.sh.tftpl, status.sh.tftpl) never invoke sudo. The installer writes to ~/.local/bin; the start script writes under $HOME/.coder-modules/. No root is required for any operation.

Engineering Quality — 10 / 10

Criterion Max Score Notes
Input quality 6 6 All variables have clear descriptions and sensible defaults. cli_binary has a regex validation rejecting shell metacharacters. serving_log_pattern has a non-empty validation. All coder_parameter data sources have descriptions, defaults, and disabled styling. The agent_relay_cursor_credential_kind parameter includes named options.
Test coverage 4 4 main.tftest.hcl covers the parameter contract (names, ephemeral flags, styling), worker wiring (env var names, script rendering, credential paths), and validation failures. main.test.ts provides 14+ end-to-end container tests exercising the full supervisor lifecycle (idle, working, serving, orphaned, done, failed), restart idempotency, credential-kind branching, shell-injection resistance, and file layout.

Overall — 52 / 100

Raw 48 / 92 → round(48 / 92 × 100) = 52

Tip

You can run this locally by telling your agent: "review this module against .github/scorecard/SCORECARD.md".


Scored against SCORECARD.md with solstice-1. Language-model scores are advisory.

… parameter

Agent Relay knows whether a pool stamps a per-user worker token or the
shared service-account key, so it stamps agent_relay_cursor_credential_kind
alongside the credential and the supervisor branches on it at run time.
The template needs no variable to keep in sync with the pool config.

<sub>Coder Agents on behalf of @Emyrk.</sub>
@Emyrk
Emyrk marked this pull request as ready for review September 22, 2026 22:50
@Emyrk
Emyrk requested a review from matifali September 22, 2026 22:50

Copy link
Copy Markdown
Member

Looks good to me. Does it mean that Cursor provided two methods to authenticate? Can we separate them out in the UI and suggest users to use which one based on their scenario?

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