fix(staging): add isCPTemplateConfigFile filter to collectCPConfigFiles
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 18s
Harness Replays / detect-changes (pull_request) Successful in 13s
CI / Detect changes (pull_request) Successful in 33s
E2E API Smoke Test / detect-changes (pull_request) Successful in 30s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 27s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 17s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 28s
gate-check-v3 / gate-check (pull_request) Successful in 17s
qa-review / approved (pull_request) Successful in 17s
security-review / approved (pull_request) Successful in 21s
sop-checklist / all-items-acked (pull_request) Successful in 21s
sop-tier-check / tier-check (pull_request) Successful in 21s
Harness Replays / Harness Replays (pull_request) Successful in 8s
CI / Canvas (Next.js) (pull_request) Successful in 10s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 9s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / Python Lint & Test (pull_request) Successful in 15s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 10s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m19s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 9s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m48s
CI / Platform (Go) (pull_request) Failing after 5m37s
CI / all-required (pull_request) Successful in 2s

Cherry-picks the filter from main commit 8fced202: only transport
config.yaml and files under prompts/ from the template directory to the
control plane. Arbitrary template files (adapter.py, Dockerfile, etc.)
are now excluded regardless of size, reducing the transport surface.

Also adds a test case verifying adapter.py is excluded even when within
the size limit.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
Molecule AI · core-be 2026-05-14 22:52:44 +00:00
parent 5d11b1aa2c
commit 9f13fc051c
2 changed files with 25 additions and 0 deletions

View File

@ -257,6 +257,16 @@ func (p *CPProvisioner) Start(ctx context.Context, cfg WorkspaceConfig) (string,
const cpConfigFilesMaxBytes = 12 << 10
// isCPTemplateConfigFile restricts which files from a template directory are
// eligible for transport to the control plane. Only config.yaml (the runtime
// entrypoint config) and files under prompts/ (system prompts) are needed;
// shipping arbitrary files (e.g. adapter.py, Dockerfile) is both unnecessary
// and a potential data-exfiltration surface.
func isCPTemplateConfigFile(name string) bool {
name = filepath.ToSlash(filepath.Clean(name))
return name == "config.yaml" || strings.HasPrefix(name, "prompts/")
}
func collectCPConfigFiles(cfg WorkspaceConfig) (map[string]string, error) {
files := make(map[string]string)
total := 0
@ -310,6 +320,9 @@ func collectCPConfigFiles(cfg WorkspaceConfig) (map[string]string, error) {
if err != nil {
return err
}
if !isCPTemplateConfigFile(rel) {
return nil
}
data, err := os.ReadFile(path)
if err != nil {
return err

View File

@ -1,6 +1,7 @@
package provisioner
import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
@ -291,6 +292,11 @@ func TestStart_CollectsConfigFiles(t *testing.T) {
if err := os.WriteFile(filepath.Join(tmpl, "config.yaml"), []byte("name: test\n"), 0o600); err != nil {
t.Fatal(err)
}
// adapter.py is within the size limit but is NOT config.yaml or prompts/,
// so isCPTemplateConfigFile must exclude it from the transport.
if err := os.WriteFile(filepath.Join(tmpl, "adapter.py"), bytes.Repeat([]byte("x"), cpConfigFilesMaxBytes), 0o600); err != nil {
t.Fatal(err)
}
var gotBody cpProvisionRequest
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@ -339,6 +345,12 @@ func TestStart_CollectsConfigFiles(t *testing.T) {
if !foundGenerated {
t.Errorf("ConfigFiles missing generated.json from ConfigFiles")
}
// adapter.py must NOT be in ConfigFiles — isCPTemplateConfigFile filters it out
for name := range gotBody.ConfigFiles {
if name == "adapter.py" {
t.Errorf("adapter.py should not be in ConfigFiles — isCPTemplateConfigFile must filter it out")
}
}
}
// TestStart_SymlinkTemplatePathError — a symlink TemplatePath should cause