Skip to content

feat(cloud-agent): add environment network controls - #8899

Open
eshurakov wants to merge 3 commits into
mainfrom
kojo/681f1b1cb5c0
Open

eshurakov wants to merge 3 commits into
mainfrom
kojo/681f1b1cb5c0

Conversation

@eshurakov

@eshurakov eshurakov commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Add None, Limited, and Full network access controls to repository environments. Restricted modes retain the server-owned Kilo, Git, and repository-host baseline. Limited accepts validated additional hostnames.

Persist the policy and apply it during session preparation. Preserve explicit API overrides and existing environment ownership checks. Scoped children inherit the parent's recorded policy and fail closed when it cannot be validated.

Verification

  • Manually checked creation, editing, saving, reopening, validation, cancellation, save-failure recovery, and responsive layouts on the earlier verified revision. The editor source is unchanged by the review cleanup.
  • Confirmed saved None policy and explicit API precedence through real local registration and session metadata.
  • Native sandbox allow/deny probes and real child execution remain unverified. The local HTTP/high-port service endpoints prevent restricted native startup.

Visual Changes

Repository environment settings now include a None/Limited/Full selector and a domain editor for Limited. Required Kilo/Git access stays visible in the help text.

Reviewer Notes

These are owner-managed session defaults. Owner-level account credentials can change them; they are not an immutable limit against those credentials. Existing personal ownership and organization management-role checks apply. Scoped child credentials cannot edit environments.

Apply the additive database migration first, then the Worker, then the web changes. The generated migration retains its normal table lock; production lock duration was not measured.

Final local verification at 0fd5178900beee5cf9f6ade89d4b56c5b16eedf9: 865 selected tests, three relevant typechecks, scoped lint, formatting, and whitespace checks passed. Browser/runtime evidence above remains prior-revision evidence. No deployment or production verification occurred.

Kojo published the branch, processed all four Kilo review threads, pushed the schema cleanup, and posted replies before resolving the threads. Fresh GitHub checks are tracked separately from local verification.

Comment thread services/kilo-mcp/catalog.json
Comment thread packages/db/src/migrations/0304_smooth_zzzax.sql
Comment thread services/cloud-agent-next/src/router/handlers/session-creation-preflight.ts Outdated
Comment thread apps/web/src/routers/cloud-environments-router.ts Outdated
@kilo-code-bot

kilo-code-bot Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 2 Issues Found | Recommendation: Address before merge

Executive Summary

The network-policy persistence, router, inheritance, and migration changes are correct; the only new findings are two optional web-form suggestions in environment-form.ts (a stale unsaved-changes flag for hidden domain text and a misleading over-length hostname message).

Assumptions: [INFERENCE] Native outbound enforcement and real child execution remain unverified by the PR's own evidence; a staging run with a restricted parent is still needed. Scoped children inherit the recorded allowlist but not the environment's saved sandbox allocation, so a default provider that is not Cloudflare Containers makes the child create fail closed with BAD_REQUEST (intentional per the regression test, but it affects subagent usability). The active MCP-exposure and migration-lock threads are answered/accepted and not re-raised.

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 2
Issue Details (click to expand)

SUGGESTION

File Line Issue
apps/web/src/components/cloud-agent-next/environment-form.ts 36 Hidden domain text keeps the form dirty after switching back to None/Full
apps/web/src/components/cloud-agent-next/environment-form.ts 94 Overlong hostname is reported as a domain-count error
Files Reviewed (26 files)
  • apps/web/src/components/cloud-agent-next/EnvironmentDialog.tsx
  • apps/web/src/components/cloud-agent-next/EnvironmentNetworkField.tsx
  • apps/web/src/components/cloud-agent-next/RepositoryEnvironmentChip.tsx
  • apps/web/src/components/cloud-agent-next/environment-form.test.ts
  • apps/web/src/components/cloud-agent-next/environment-form.ts - 2 issues
  • apps/web/src/components/cloud-agent-next/settings/EnvironmentsSection.tsx
  • apps/web/src/routers/cloud-environments-router.test.ts
  • apps/web/src/routers/cloud-environments-router.ts
  • apps/web/src/tests/cloud-agent-profile/environment-service.test.ts
  • packages/cloud-agent-profile/package.json
  • packages/cloud-agent-profile/src/environment-contracts.ts
  • packages/cloud-agent-profile/src/environment-service.ts
  • packages/db/src/migrations/0304_smooth_zzzax.sql
  • packages/db/src/migrations/meta/0304_snapshot.json - generated, skipped
  • packages/db/src/migrations/meta/_journal.json - generated, skipped
  • packages/db/src/schema.test.ts
  • packages/db/src/schema.ts
  • packages/worker-utils/src/cloud-agent-authority.test.ts
  • pnpm-lock.yaml - generated, skipped
  • services/cloud-agent-next/src/router/handlers/session-creation-preflight.test.ts
  • services/cloud-agent-next/src/router/handlers/session-creation-preflight.ts
  • services/cloud-agent-next/src/router/handlers/session-prepare.test.ts
  • services/cloud-agent-next/src/router/handlers/session-start-environment.test.ts
  • services/cloud-agent-next/src/session/session-prepare.test.ts
  • services/kilo-mcp/catalog.json - generated, skipped

Fix these issues in Kilo Cloud

Previous Review Summaries (3 snapshots, latest commit 21f4cc1)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 21f4cc1)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Full re-review of the environment network-policy change (the incremental base commit is no longer an ancestor, so I reviewed the complete PR diff against main) found no new defects in the persistence, router, UI, preflight inheritance, or migration changes; the two actionable prior suggestions are fixed and the remaining threads are answered.

Assumptions: [INFERENCE] Native outbound enforcement and deployed-provider parity remain unverified by the PR's own evidence. Scoped children inherit the recorded allowlist but not the environment's saved sandbox allocation; if the owner's default provider resolves to Vercel (which selectDefaultSandboxProvider prefers when enrolled) or non-containers Cloudflare, assertEgressPolicyAllocation rejects the child create as BAD_REQUEST, so a staging run with a restricted parent is needed to confirm subagent launches. The migration CHECK still validates the table under an ACCESS EXCLUSIVE lock; the author's transactional-migrator rationale is accepted and the active thread on that line is not duplicated. The earlier MCP-exposure warning is not re-raised: the policy is an owner-managed default overridable by explicit session input, and environment mutations keep the existing ownership / organization manage-role checks.

Files Reviewed (25 files)
  • apps/web/src/components/cloud-agent-next/EnvironmentDialog.tsx
  • apps/web/src/components/cloud-agent-next/EnvironmentNetworkField.tsx
  • apps/web/src/components/cloud-agent-next/RepositoryEnvironmentChip.tsx
  • apps/web/src/components/cloud-agent-next/environment-form.ts
  • apps/web/src/components/cloud-agent-next/environment-form.test.ts
  • apps/web/src/components/cloud-agent-next/settings/EnvironmentsSection.tsx
  • apps/web/src/routers/cloud-environments-router.ts
  • apps/web/src/routers/cloud-environments-router.test.ts
  • apps/web/src/tests/cloud-agent-profile/environment-service.test.ts
  • packages/cloud-agent-profile/package.json
  • packages/cloud-agent-profile/src/environment-contracts.ts
  • packages/cloud-agent-profile/src/environment-service.ts
  • packages/db/src/migrations/0303_parallel_smiling_tiger.sql
  • packages/db/src/migrations/meta/0303_snapshot.json - generated, skipped
  • packages/db/src/migrations/meta/_journal.json - generated, skipped
  • packages/db/src/schema.ts
  • packages/db/src/schema.test.ts
  • packages/worker-utils/src/cloud-agent-authority.test.ts
  • pnpm-lock.yaml - generated, skipped
  • services/cloud-agent-next/src/router/handlers/session-creation-preflight.ts
  • services/cloud-agent-next/src/router/handlers/session-creation-preflight.test.ts
  • services/cloud-agent-next/src/router/handlers/session-prepare.test.ts
  • services/cloud-agent-next/src/router/handlers/session-start-environment.test.ts
  • services/cloud-agent-next/src/session/session-prepare.test.ts
  • services/kilo-mcp/catalog.json - generated, skipped

Previous review (commit 0fd5178)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The two follow-up commits are behavior-preserving: they reuse the shared egressModeSchema in the response contract and drop a redundant re-parse of a value the metadata schema already validates and normalizes. The rest of the PR is unchanged since the previous review, whose inline items are now fixed or answered.

Assumptions: The 56 upstream files brought in by the "Merge main" commit were not re-reviewed as PR-authored changes. [INFERENCE] Native outbound enforcement and deployed-provider parity remain unverified by the PR's own evidence. The earlier MCP-exposure warning is not re-raised: the persisted policy is an owner-managed default that explicit session input can override, and environment mutations remain gated by ownership / organization manage-role checks.

Files Reviewed (2 files changed since last review)
  • apps/web/src/routers/cloud-environments-router.ts - 0 issues
  • services/cloud-agent-next/src/router/handlers/session-creation-preflight.ts - 0 issues

Previous review (commit 6be97d3)

Status: 4 Issues Found | Recommendation: Address before merge

Executive Summary

The main risk is that the persisted network policy becomes writable through the MCP-exposed cloudEnvironments.update tool, letting an agent remove the egress restriction for future sessions; the rest are migration-lock and small contract-duplication suggestions.

Assumptions: [INFERENCE] Native outbound enforcement and deployed-provider parity were not exercised (per the PR's own "not verified" list); this review verified that the scoped-child path (scopedPrepareSessionSchema, .strict()) rejects egressMode/egressAllowlist/runtime, so the explicit-override branch is reachable only from non-authority call paths. No memory leaks or markdown/image issues apply: the new UI adds state only and no .md files change.

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 3
Issue Details (click to expand)

WARNING

File Line Issue
services/kilo-mcp/catalog.json 8589 Published cloudEnvironments.update MCP mutation can set egressMode: "unrestricted" and widen/remove a saved environment network policy for all future sessions

SUGGESTION

File Line Issue
packages/db/src/migrations/0302_gray_zombie.sql 3 ADD CONSTRAINT ... CHECK scans the populated table under ACCESS EXCLUSIVE; use NOT VALID + VALIDATE CONSTRAINT
services/cloud-agent-next/src/router/handlers/session-creation-preflight.ts 328 Second egressAllowlistSchema.parse is unreachable and would raise a raw ZodError instead of parentPolicyUnavailableError
apps/web/src/routers/cloud-environments-router.ts 125 Response schema restates the egress mode enum instead of reusing egressModeSchema
Files Reviewed (25 files)
  • apps/web/src/components/cloud-agent-next/EnvironmentDialog.tsx - 0 issues
  • apps/web/src/components/cloud-agent-next/EnvironmentNetworkField.tsx - 0 issues
  • apps/web/src/components/cloud-agent-next/RepositoryEnvironmentChip.tsx - 0 issues
  • apps/web/src/components/cloud-agent-next/environment-form.test.ts - 0 issues
  • apps/web/src/components/cloud-agent-next/environment-form.ts - 0 issues
  • apps/web/src/components/cloud-agent-next/settings/EnvironmentsSection.tsx - 0 issues
  • apps/web/src/routers/cloud-environments-router.test.ts - 0 issues
  • apps/web/src/routers/cloud-environments-router.ts - 1 issue
  • apps/web/src/tests/cloud-agent-profile/environment-service.test.ts - 0 issues
  • packages/cloud-agent-profile/package.json - 0 issues
  • packages/cloud-agent-profile/src/environment-contracts.ts - 0 issues
  • packages/cloud-agent-profile/src/environment-service.ts - 0 issues
  • packages/db/src/migrations/0302_gray_zombie.sql - 1 issue
  • packages/db/src/migrations/meta/0302_snapshot.json - generated, skipped
  • packages/db/src/migrations/meta/_journal.json - generated, skipped
  • packages/db/src/schema.test.ts - 0 issues
  • packages/db/src/schema.ts - 0 issues
  • packages/worker-utils/src/cloud-agent-authority.test.ts - 0 issues
  • pnpm-lock.yaml - generated, skipped
  • services/cloud-agent-next/src/router/handlers/session-creation-preflight.test.ts - 0 issues
  • services/cloud-agent-next/src/router/handlers/session-creation-preflight.ts - 1 issue
  • services/cloud-agent-next/src/router/handlers/session-prepare.test.ts - 0 issues
  • services/cloud-agent-next/src/router/handlers/session-start-environment.test.ts - 0 issues
  • services/cloud-agent-next/src/session/session-prepare.test.ts - 0 issues
  • services/kilo-mcp/catalog.json - 1 issue

Fix these issues in Kilo Cloud


Reviewed by deepseek-flash-latest · Input: 135.3K · Output: 33.4K · Cached: 3.6M

Review guidance: REVIEW.md from base branch main

@eshurakov eshurakov changed the title Repository Environment Network Access Controls feat(cloud-agent): add environment network controls Oct 26, 2026
Kojo squashed the task's work onto f2ef0ed, the tip of origin/main, because the pull request conflicted with it. It replaces 21f4cc1.
@eshurakov

Copy link
Copy Markdown
Contributor Author

Visual verification

Tested revision: 21f4cc1d1d49f7f9f0ff231295dcefa713bcc5ac.

Controlled demonstration; does not prove a live integration.

The actual EnvironmentNetworkField component at this published revision shows None, Limited, and Full with their descriptions. This standalone demo uses a custom shell and synthetic data. It does not verify backend persistence or network enforcement.

Visual verification

Controlled demonstration; does not prove a live integration.

Selecting Limited exposes Additional allowed domains. Entered example domains remain visible. This is a controlled component interaction, without backend requests.

Visual verification

Privacy review:

Inspected both complete images. Only public component text and synthetic example domains are visible. No account, repository, credential, internal URL, or unrelated application data is present. PNG files contain only IHDR, IDAT, and IEND chunks.

saved.sandboxAllocation !== draft.sandboxAllocation
saved.sandboxAllocation !== draft.sandboxAllocation ||
saved.networkAccess.mode !== draft.networkAccess.mode ||
saved.networkAccess.domains !== draft.networkAccess.domains

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[SUGGESTION]: Hidden domain text keeps the form dirty after switching back to None or Full

EnvironmentNetworkField retains domains when the mode changes, and buildEgressPolicy ignores that hidden text for None/Full, but this comparison still counts it. Switching Limited → Full (or None) therefore leaves hasEnvironmentFormChanges true even though saving sends no policy, so EnvironmentBuildPanel blocks Build/Refresh with "Save your changes before building." Compare domains only while the mode is limited.

Suggested change
saved.networkAccess.domains !== draft.networkAccess.domains
(saved.networkAccess.mode === 'limited' && saved.networkAccess.domains !== draft.networkAccess.domains)

}
);
if (!parsed.success) {
const tooMany = parsed.error.issues.some(issue => issue.code === 'too_big');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[SUGGESTION]: Overlong hostname is reported as a domain-count error

egressDomainSchema also has .max(254), which emits the same too_big code as the array limit, so a single hostname longer than 254 characters shows "Add no more than 100 domains." Restrict the check to the array-level issue (path length 1).

Suggested change
const tooMany = parsed.error.issues.some(issue => issue.code === 'too_big');
const tooMany = parsed.error.issues.some(issue => issue.code === 'too_big' && issue.path.length === 1);

This branch has not been deployed

No deployments
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