Repository navigation
Conversation
…space secrets Drops the agent_relay_credential parameter and its coder_env from the agent-relay-claude-code and agent-relay-cursor modules. Agent Relay now sends the work order and worker token as ephemeral workspace secrets that the agent injects as SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET and AGENT_RELAY_CURSOR_TOKEN. The dispatched output keys off agent_relay_delivery_id instead. Breaking: a relay that still stamps the credential parameter refuses templates on these versions, so both modules move to 1.0.0.
Contributor
Module Scorecard Check
|
| Theme | Before | After |
|---|---|---|
| Presentation & Onboarding | 6 / 17 | 6 / 17 |
| Integration | 0 / 25 | 0 / 25 |
| Credential Hygiene | 20 / 20 | 20 / 20 |
| Restricted-Environment | 12 / 20 | 12 / 20 |
| Engineering Quality | 10 / 10 | 10 / 10 |
| Overall | 52 / 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 | Two major modes exist: install_cli = true (download at start) and install_cli = false (CLI baked into image). The README's single code example shows install_cli = true with a comment noting the false path. The Parameters and Requirements sections describe both modes in prose, but no separate code example demonstrates the "bake into image" configuration. Half credit for partial documentation of the second mode. |
| Visual preview | 5 | 0 | No image, GIF, or video is embedded in the README. The frontmatter icon field references a registry listing icon, which does not count. |
Credential Hygiene — 20 / 20
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Secrets marked sensitive | 16 | 16 | The work-order JWT is passed exclusively as a Coder workspace secret (SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET), never as a Terraform variable, so no sensitive = true annotation is needed on module inputs. The README explicitly states it "never appears in the build's parameters or Terraform state." No inline secrets appear in any README example. |
| Non-hardcoded auth path | 4 | 4 | The README documents that the credential is injected by the Coder agent from the workspace secret, not pasted into templates: "The work order reaches the runner as the SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET workspace secret, never as a build parameter." This is a platform-injected auth path. |
Restricted-Environment Readiness — 12 / 20
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Mirrorable artifact source | 5 | 0 | The install URL https://claude.ai/install.sh is hardcoded in install.sh.tftpl. No module input variable overrides this download URL. cli_binary overrides the binary path, not the source URL; install_cli is a boolean toggle. No variable exists whose value replaces the download URL. |
| Bring-your-own binary | 10 | 10 | install_cli = false disables the download entirely. The install script's presence check (command -v ${cli_binary}) short-circuits when the CLI is already on PATH. The README documents this: "Bake the CLI into the image and set this to false for faster workspaces." cli_binary allows specifying a custom path. Fully implemented and documented. |
| Egress transparency | 3 | 0 | No dedicated README section enumerates external endpoints. The install URL (claude.ai/install.sh, redirecting to downloads.claude.ai) and Anthropic's runner API are only visible in source code comments and the install script. No "Network," "Egress," or "Air-gapped" section exists in the README. |
| Runs without sudo | 2 | 2 | Neither install.sh.tftpl nor start.sh.tftpl nor status.sh.tftpl invokes sudo. The installer places the binary in ~/.local/bin; the start script creates directories under $HOME. All operations work as an unprivileged user. |
Engineering Quality — 10 / 10
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Input quality | 6 | 6 | All eight variables have clear descriptions and sensible defaults. cli_binary has a regex validation rejecting shell metacharacters; exit_if_unused_min has a whole-number ≥ 0 validation. Descriptions explain the operational impact of each value. |
| Test coverage | 4 | 4 | main.tftest.hcl (7 test runs) covers the parameter contract, ephemeral vs. persistent semantics, script rendering, and security invariants (shell injection via cli_binary, serving_log_pattern as data). main.test.ts (9 tests) executes the actual install/start scripts in a container with stub binaries, verifying the full supervisor lifecycle (idle, working, done, failed, orphaned), the permissions wrapper, PATH handling, and state-file persistence across restarts. |
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 module relies on Agent Relay's work-order JWT and account-lock mechanism, but does not document how Coder governs auth, routing, or policy enforcement via AI Gateway or Agent Firewall. |
| Dashboard entry point | 5 | 0 | No coder_app resource is declared or documented. The module is a headless self-hosted runner with no user-facing UI. No example or built-in dashboard entry point is provided. |
| Session continuity | 5 | 0 | No documentation of resuming an existing agent session across reconnects or relaunches. No mention of tmux, screen, boo, or a persistent session manager. The runner is stateless across workspace rebuilds; agent_relay_session_id is an identifier for Agent Relay's deduplication, not a resume mechanism. |
| Managed configuration | 5 | 0 | No documentation of managed MCP servers, settings files, policies, or workdir configuration. base_dir sets the session checkout directory but does not constitute managed configuration in the rubric's sense. |
Overall — 52 / 100
Raw 48 / 92 → round(48 / 92 × 100) = 52
coder/agent-relay-cursor: 58 → 63
✅ Score improvement: 58 → 63 (+5).
| Theme | Before | After |
|---|---|---|
| Presentation & Onboarding | 6 / 17 | 6 / 17 |
| Integration | 5 / 25 | 10 / 25 |
| Credential Hygiene | 20 / 20 | 20 / 20 |
| Restricted-Environment | 12 / 20 | 12 / 20 |
| Engineering Quality | 10 / 10 | 10 / 10 |
| Overall | 58 / 100 | 63 / 100 |
Full scorecard for this PR
| Presentation & Onboarding | Agent Integration | Credential Hygiene | Restricted-Environment Readiness | Engineering Quality | Overall |
|---|---|---|---|---|---|
| 6 / 17 | 10 / 25 | 20 / 20 | 12 / 20 | 10 / 10 | 63 / 100 |
Drilldown
Presentation & Onboarding — 6 / 17
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Configuration-mode examples | 12 | 6 | The main example shows the default (install_cli = true). The "Requirements" section documents install_cli = false, computer_use = true, and share_desktop = true in prose with their image prerequisites, but none of these alternate modes get a dedicated code-block example. A user must infer the Terraform syntax from the variable names. |
| Visual preview | 5 | 0 | No image, GIF, or video is embedded in the README. The frontmatter icon field is a static SVG icon, not a preview of the module in action. |
Credential Hygiene — 20 / 20
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Secrets marked sensitive | 16 | 16 | The worker token is never a module input; Agent Relay delivers it as an ephemeral workspace secret (AGENT_RELAY_CURSOR_TOKEN), so no Terraform variable carries a secret. The README "Worker credential" section explicitly states it "never appears in the build's parameters or Terraform state." No README example inlines a literal or placeholder key. |
| Non-hardcoded auth path | 4 | 4 | The "Worker credential" section documents the full non-hardcoded path: the pool's service-account key stays in Agent Relay, which mints a user-scoped sub-token at dispatch and injects it as a workspace secret. No raw key is ever pasted into a template. |
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 (documented in README: "Bake the CLI into the image and set this to false for faster workspaces") disables the download entirely. The install script checks command -v and skips; the start script adds ~/.local/bin to PATH unconditionally. Fully documented and tested. |
| Egress transparency | 3 | 0 | No dedicated "Network," "Egress," "Offline," or "Air-gapped" section exists. Endpoints (cursor.com/install, cursor.com/agents) appear scattered in the Requirements and app-URL descriptions but are not enumerated in a single section with restricted-environment guidance. |
| Runs without sudo | 2 | 2 | All three scripts (install.sh.tftpl, start.sh.tftpl, status.sh.tftpl) install to ~/.local/bin, write under $HOME/.coder-modules/, and run the worker as the invoking user. No sudo invocation anywhere. |
Engineering Quality — 10 / 10
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Input quality | 6 | 6 | Every variable has a clear description and sensible default. cli_binary has a regex validation rejecting shell metacharacters; share_desktop has a cross-field validation requiring computer_use; serving_log_pattern rejects empty strings. All are well-documented. |
| Test coverage | 4 | 4 | main.tftest.hcl covers the parameter contract (names, persistence, disabled styling), script rendering (env-var wiring, token handling, flag passing), and validation failures. main.test.ts runs the actual install/start scripts in containers with a stub agent binary, exercising the full supervisor lifecycle (idle, working, serving, done, failed, orphaned), restart idempotency, shell-injection resistance, and file layout. |
Agent Integration — 10 / 25
| Criterion | Max | Score | Notes |
|---|---|---|---|
| AI governance | 10 | 5 | The README documents Agent Relay's governance thoroughly: auth (service-account key → user-scoped sub-token, never in state), routing (pool-based dispatch), and policy (1-hour token expiry, contract verification at startup, reaping via agent_relay_status). However, the specific product names "AI Gateway" and "Agent Firewall" are never used; the mechanism is called "Agent Relay." Per calibration, exactly one governance product documented earns half. |
| Dashboard entry point | 5 | 5 | Two coder_app resources are declared: "Open in Cursor Web" (cursor.com/agents/<id>) and "Open in Cursor Desktop" (cursor:// deeplink). Both are conditional on agent_relay_session_id being set. Documented in the README under the session-id paragraph. |
| Session continuity | 5 | 0 | No session-resume mechanism is documented. The README explicitly 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 tmux, screen, boo, or persistent session manager is used or mentioned. |
| Managed configuration | 5 | 0 | No support for managed MCP servers, agent settings, policies, or workdir configuration is documented. The agent_relay_cursor_repo_url parameter is the template's responsibility to clone; the module does not manage workdir or tool configuration. |
Overall — 63 / 100
Raw 58 / 92 → round(58 / 92 × 100) = 63
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.
5 of 9 tasks
Member
|
Please add the minimum version required for agent-relay and Coder to this module README.md |
matifali
added a commit
that referenced
this pull request
Oct 15, 2026
) ## Description Starts the Cursor worker with `--auth-token-file` instead of `--auth-token`, and corrects the docs that still described the old one-hour token. **Token handoff** - The start step writes `AGENT_RELAY_CURSOR_TOKEN` to `$HOME/.coder-modules/coder/agent-relay-cursor/worker-token` (`umask 077`, renamed into place) and the supervisor passes `--auth-token-file`. - The supervisor unsets `AGENT_RELAY_CURSOR_TOKEN` before launching the worker, so neither the worker nor the agent commands it spawns inherit it. - The supervisor deletes the file when the worker exits. The claim is over by then, so the token is useless. - Result: the token is no longer in the worker's `/proc/<pid>/cmdline`, the CLI re-reads the file when it reconnects (so a replacement token written to the same path works without a restart), and the CLI stops logging `Auth tokens cannot be refreshed automatically...`. **Docs** The README's "Worker credential" section and the `agent_relay_credential` description said the token "expires after an hour" and "is not refreshed". That described the user-scoped sub-token Agent Relay used before 0.11.0. Since then the relay stamps a per-claim Cursor [session token](https://cursor.com/docs/cloud-agent/self-hosted/pool#session-tokens). It ends with the claim and has only a 7-day backstop expiry. The README now says so. No parameter, output, or contract change, so any Agent Relay version works with it. ## Type of Change - [ ] New module - [ ] New template - [x] Bug fix - [ ] Feature/enhancement - [x] Documentation - [ ] Other ## Module Information **Path:** `registry/coder/modules/agent-relay-cursor` **New version:** `v0.5.0` (`agent-relay-cursor` is tagged at v0.4.0, so the unreleased 0.5.0 on main ships with this change) **Breaking change:** [ ] Yes [x] No ## Testing & Validation - [x] Tests pass (`bun test`): 19 pass, plus `terraform test`: 12 pass - [x] Code formatted (`bun fmt`) - [x] Changes tested locally New and updated assertions: the worker gets `--auth-token-file <module dir>/worker-token` and never `--auth-token` or the token value; the file holds the token with mode `600`; the worker's environment has no `AGENT_RELAY_CURSOR_TOKEN`; the file is gone after the worker exits. Also checked against the real CLI (`2026.10.14-941492e`): `agent worker --help` lists `--auth-token-file`, and with `--auth-token-file` the worker skips the "cannot be refreshed" warning that `--auth-token` prints. ## Related Issues Touches `start.sh.tftpl` and `README.md`, like #1173 (credentials as workspace secrets) and #1145 (drain on stop). The overlap is small; whichever merges second needs a trivial rebase. --------- Co-authored-by: coder[bot] <137810501+coder[bot]@users.noreply.github.com> Co-authored-by: Atif Ali <atif@coder.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The
agent-relay-claude-codeandagent-relay-cursormodules now take their credential from a workspace build secret instead of theagent_relay_credentialparameter. Pairs with coder/agent-relay#100 and the coder/coder workspace secrets stack (coder/coder#30459).Warning
Breaking change: both modules move to 1.0.0. An Agent Relay that still sends the credential as a parameter (older relays, or any relay against a coderd without build secrets) refuses templates on 1.0 because the parameter is gone. Stay on
agent-relay-claude-code0.2.0 /agent-relay-cursor0.5.0 until both are upgraded.agent_relay_credentialparameter and thecoder_envthat copied it into the workspace.SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET(Claude Code) orAGENT_RELAY_CURSOR_TOKEN(Cursor).dispatchedoutput checksagent_relay_delivery_id, since Terraform can no longer see the credential.Coder Agents on behalf of @Emyrk.