Skip to content

fix: clamp template port sharing level in SubAgentAPI#26061

Open
johnstcn wants to merge 12 commits into
mainfrom
cj/codagt-479
Open

fix: clamp template port sharing level in SubAgentAPI#26061
johnstcn wants to merge 12 commits into
mainfrom
cj/codagt-479

Conversation

@johnstcn
Copy link
Copy Markdown
Member

@johnstcn johnstcn commented Jun 4, 2026

Fixes an issue where sub-agent apps created via CreateSubAgent would bypass the check for the template's max port sharing level:

  • Clamps dynamically inserted workspace_apps to the template max sharing level in coderd.agentapi.SubAgentAPI.
  • Emits a warning when clamping occurs.
  • Adds unit test coverage for the max sharing level matrix.
  • Adds an integration-ish test through the devcontainer sub-agent client path.

Generated by Coder Agents with guidance from a human.

@johnstcn johnstcn self-assigned this Jun 4, 2026
@linear-code
Copy link
Copy Markdown

linear-code Bot commented Jun 4, 2026

CODAGT-479

@johnstcn
Copy link
Copy Markdown
Member Author

johnstcn commented Jun 4, 2026

/coder-agents-review

@coder-agents-review
Copy link
Copy Markdown
Contributor

coder-agents-review Bot commented Jun 4, 2026

Chat: Review in progress | View chat
Requested: 2026-06-04 14:29 UTC by @johnstcn
Spend: $44.78 / $100.00

deep-review v0.7.1 | Round 2 | 2cbce86..4d5a974

Last posted: Round 2, 11 findings (3 P3, 5 Nit, 3 Note), APPROVE. Review

Finding inventory

Findings

# Sev Status Location Summary Round Reviewer Posted
CRF-1 P3 Author fixed (4d5a974) subagent.go:142 GetTemplateByID relies on template default ACL, not explicit SubAgentAPI role permission R1 Meruem P2, Kurapika no-finding Yes
CRF-2 P3 Author fixed (4d5a974) subagent.go:225 Warn log omits sub-agent name and ID R1 Leorio Yes
CRF-3 P3 Author fixed (4d5a974) subagent_test.go:251 require.True(HasSuffix) produces opaque failure messages R1 Chopper P3, Bisky Nit Yes
CRF-4 Nit Author fixed (4d5a974) subagent_test.go:43 Test name claims organization is clamped; only public is R1 Netero Yes
CRF-5 Nit Author fixed (4d5a974) subagent.go:225 Log says "workspace app" not "sub-agent app" R1 Leorio Yes
CRF-6 Note Author accepted R2 (explicitly out of scope, aligns with reviewer's own scoping) provisionerdserver.go:3642 Provisioner path has no MaxPortSharingLevel check R1 Pariston Yes
CRF-7 Note Author fixed (4d5a974) subagent.go:35 PortSharer field has no doc comment; nil fallback is permit-all R1 Leorio Yes
CRF-8 Note Author fixed (4d5a974) subagent.go:224 Clamping is silent; caller cannot discover the reduction R1 Ryosuke P3, Chopper Note, Knov Note Yes
CRF-9 Nit Open subagent.go:142 3-line comment could be tighter R2 Gon P2 Yes
CRF-10 Nit Open subagent.go:228 Comment scopes rationale to devcontainers; handler is generic R2 Gon P2 Yes
CRF-11 Nit Open subagent_test.go:340 "Coder" in integration test name adds no information R2 Gon Yes

Round log

Round 1

Panel. 3 P3, 2 Nit, 3 Note. Reviewed against 2cbce86..49e0119.

Round 2

Panel. CRF-1 through CRF-8 addressed. 3 Nit new. Reviewed against 2cbce86..4d5a974.

About deep-review

CRF = Coder Review Finding (P0-P4, Nit, Note)

Reviewer Focus
Bisky tests
Chopper ops/errors
Churn-guard change verification
Ging language modernization
Gon naming
Hisoka edge cases
Killua perf
Kite change integrity
Knov contracts
Knuckle SQL
Kurapika security
Law decomposition
Leorio docs
Luffy product
Mafu-san process
Mafuuu contracts
Melody dispatch/pairing
Meruem structural
Nami frontend
Netero mechanical checks
Pariston premise testing
Pen-botter product gaps
Razor verification
Robin duplication
Ryosuke Go arch
Takumi concurrency
Zoro shape

🤖 Managed by Coder Agents.

Comment thread enterprise/coderd/subagent_test.go Outdated
return ctx, api, &upsertedApps
}

func TestDevcontainerCoderAppShareClampedByTemplateMaxPortShareLevel(t *testing.T) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

review: chose to go with an "integration-ish" style test, avoiding the full overhead of standing up an agent with fake CLIs etc in favour of just calling the relevant DRPC methods using a stubbed client.

Copy link
Copy Markdown
Contributor

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean, well-scoped fix. The clamping design (warn+restrict vs reject) is the right call for the SubAgentAPI's infrastructure callers, and the test coverage is thorough: 4 max-level boundary cases in the mock test plus a real-DB integration test through the full SubAgentClient stack. The PortSharer atomic pointer follows the established AGPL/Enterprise injection pattern. Good work.

Severity count: 3 P3, 2 Nit, 3 Note.

Pariston, after trying to build a case against this change: "I tried to build a case against this change and couldn't. The problem is correctly identified, the fix is at the right layer, the clamping behavior is the correct choice for infrastructure callers, and the tests cover the level ordering thoroughly. The premises hold."

One observation for the PR description: the current text describes the mechanism ("adds a check for and clamp") without stating the problem. Consider leading with: sub-agent apps created via CreateSubAgent bypassed the template's max port sharing level. Then the fix.


coderd/provisionerdserver/provisionerdserver.go:3642

Note [CRF-6] The provisioner maps sdkproto.AppSharingLevel to database.AppSharingLevel and stores it directly without calling AuthorizedLevel. A template with max_port_sharing_level = "authenticated" and a terraform-defined app with sharing_level = "public" stores "public" in the database. The risk is lower than the SubAgentAPI case (template admin controls both settings), but it's structurally the same gap. Not in scope for this PR, noting for visibility. (Pariston)

🤖

🤖 This review was automatically generated with Coder Agents.

Comment thread coderd/agentapi/subagent.go
Comment thread coderd/agentapi/subagent.go Outdated
Comment thread enterprise/coderd/subagent_test.go Outdated
Comment thread enterprise/coderd/subagent_test.go
Comment thread coderd/agentapi/subagent.go Outdated
Comment thread coderd/agentapi/subagent.go
Comment thread coderd/agentapi/subagent.go
@johnstcn
Copy link
Copy Markdown
Member Author

johnstcn commented Jun 4, 2026

Note: leaving CRF-6 above explicitly out of scope.

@johnstcn
Copy link
Copy Markdown
Member Author

johnstcn commented Jun 4, 2026

/coder-agents-review

Copy link
Copy Markdown
Contributor

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All 8 R1 findings addressed in 4d5a974. Fixes verified by Netero and the full panel (9 reviewers). The comments documenting the ACL dependency, nil-PortSharer behavior, and clamp-vs-reject rationale are all accurate and well-placed. The warn log now carries sub-agent name, sub-agent ID, app slug, requested level, max level, and the underlying error, giving operators full diagnostic context.

Severity count: 3 Nit (new). All prior findings resolved.

Hisoka, after pulling every thread: "I came looking for a fight. I pulled every thread I could find. [...] No findings. The code held up."

One process note: the fix commit subject ("address automated code review feedback") is opaque, but this PR will squash-merge under the PR title, which is good.

🤖 This review was automatically generated with Coder Agents.

Comment thread coderd/agentapi/subagent.go Outdated
Comment thread coderd/agentapi/subagent.go Outdated
Comment thread enterprise/coderd/subagent_test.go Outdated
@johnstcn johnstcn marked this pull request as ready for review June 4, 2026 15:19
Copilot AI review requested due to automatic review settings June 4, 2026 15:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a bypass where sub-agent workspace apps created via CreateSubAgent could exceed the template’s maximum allowed port/app sharing level by adding clamping logic in coderd/agentapi.SubAgentAPI, wiring the PortSharer into the agent RPC API, and adding unit/integration-ish test coverage for sharing-level clamping.

Changes:

  • Add template-aware clamping for dynamically inserted workspace_apps in coderd/agentapi.SubAgentAPI, with warning logs when clamping occurs.
  • Thread PortSharer through agentapi.Options and the workspace agent RPC setup so SubAgentAPI can enforce enterprise sharing restrictions.
  • Add a new enterprise test file covering a max-sharing-level matrix and a devcontainer sub-agent client path.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
enterprise/coderd/subagent_test.go Adds unit + integration-ish tests validating app share level clamping against template max.
coderd/workspaceagentsrpc.go Passes the server PortSharer into the per-agent agentapi.Options.
coderd/agentapi/subagent.go Fetches the workspace/template for sub-agent app creation and clamps share levels via PortSharer.
coderd/agentapi/api.go Extends agent API options/sub-agent wiring to include PortSharer.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread coderd/agentapi/subagent.go
Comment thread enterprise/coderd/subagent_test.go
func (a *SubAgentAPI) CreateSubAgent(ctx context.Context, req *agentproto.CreateSubAgentRequest) (*agentproto.CreateSubAgentResponse, error) {
//nolint:gocritic // This gives us only the permissions required to do the job.
ctx = dbauthz.AsSubAgentAPI(ctx, a.OrganizationID, a.OwnerID)
ctx = dbauthz.AsSubAgentAPI(ctx, a.OrganizationID, a.OwnerID, a.OwnerGroups)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit strange. The subagent should take the owner's groups for template access? Should we just add template read to the org permissions on Sub Agent API?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was my initial thought as well, but is that too broad?

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.

3 participants