Skip to content

Commit 9ab8522

Browse files
committed
Keep env secrets opaque on internal-edit path; document codebuffignore
1 parent 20c2381 commit 9ab8522

3 files changed

Lines changed: 25 additions & 0 deletions

File tree

sdk/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,11 @@ gitignore. This built-in policy is scoped to
180180
SDK-mediated agent file reads (including `read_files`); it does not add
181181
terminal-command or internal-edit restrictions.
182182

183+
Ignore-rule blocks on `read_files` return `[BLOCKED]` followed by a trailing
184+
reason. `.codebuffignore` — a project-level ignore file with `.gitignore`
185+
syntax, checked alongside `.gitignore` — is the escape hatch: adjust or
186+
negate the matching rule there to allow tool reads of a specific file.
187+
183188
Custom `overrideTools.read_files` implementations must preserve project
184189
gitignore behavior for env templates. The built-in CLI, Desktop, Web, and Cloud
185190
bridges already do this.

sdk/src/__tests__/read-files.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,19 @@ describe('getFiles', () => {
436436
).toBe(true)
437437
expect(goneResult['AGENTS.local.md']).not.toContain('exists on disk')
438438

439+
// Internal-edit path (no env policy): a secret blocked by built-in
440+
// ignore defaults must stay opaque too.
441+
const editFs = createMockFs({
442+
files: { '/project/.env': { content: 'SECRET=value' } },
443+
})
444+
const editResult = await getFiles({
445+
filePaths: ['.env'],
446+
cwd: '/project',
447+
fs: editFs,
448+
enforceEnvPolicy: false,
449+
})
450+
expect(editResult['.env']).toBe(FILE_READ_STATUS.IGNORED)
451+
439452
// The env-policy block must NOT leak a reason or an unblock hint.
440453
const envFs = createMockFs({
441454
files: { '/project/.env': { content: 'SECRET=value' } },

sdk/src/tools/read-files.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ export async function getFiles(params: {
9999
...(isEnvTemplate ? { allowEnvTemplate: true } : {}),
100100
})
101101
if (ignored) {
102+
// The internal-edit path (enforceEnvPolicy: false) skips the env
103+
// gate above, so secrets can reach this branch via built-in ignore
104+
// defaults. Never explain or hint unblocking for them.
105+
if (isSensitiveEnvFilePath(relativePath)) {
106+
result[relativePath] = FILE_READ_STATUS.IGNORED
107+
continue
108+
}
102109
// Keep the sentinel as the prefix (consumers match with startsWith)
103110
// and append the reason, following the FILE_TOO_LARGE precedent.
104111
// The ignore check never touches the file itself, so only claim

0 commit comments

Comments
 (0)