Fix security: only expose auth vars to containers, not full .env
Previously, the entire .env file was copied and mounted into containers, exposing all environment variables to the agent. Now only the specific authentication variables needed by Claude Code (CLAUDE_CODE_OAUTH_TOKEN and ANTHROPIC_API_KEY) are extracted and mounted. https://claude.ai/code/session_01Y6Az5oUPkYmJhA1N9MUd67
This commit is contained in:
@@ -82,7 +82,7 @@ cat .env # Should show one of:
|
|||||||
|
|
||||||
**Apple Container Bug:** Environment variables passed via `-e` are lost when using `-i` (interactive/piped stdin).
|
**Apple Container Bug:** Environment variables passed via `-e` are lost when using `-i` (interactive/piped stdin).
|
||||||
|
|
||||||
**Workaround:** The system mounts `.env` as a file and sources it inside the container.
|
**Workaround:** The system extracts only authentication variables (`CLAUDE_CODE_OAUTH_TOKEN`, `ANTHROPIC_API_KEY`) from `.env` and mounts them for sourcing inside the container. Other env vars are not exposed.
|
||||||
|
|
||||||
To verify env vars are reaching the container:
|
To verify env vars are reaching the container:
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
2
SPEC.md
2
SPEC.md
@@ -230,7 +230,7 @@ The token can be extracted from `~/.claude/.credentials.json` if you're logged i
|
|||||||
ANTHROPIC_API_KEY=sk-ant-api03-...
|
ANTHROPIC_API_KEY=sk-ant-api03-...
|
||||||
```
|
```
|
||||||
|
|
||||||
The `.env` file is automatically mounted into the container at `/workspace/env-dir/env` and sourced by the entrypoint script. This workaround is needed because Apple Container loses `-e` environment variables when using `-i` (interactive mode with piped stdin).
|
Only the authentication variables (`CLAUDE_CODE_OAUTH_TOKEN` and `ANTHROPIC_API_KEY`) are extracted from `.env` and mounted into the container at `/workspace/env-dir/env`, then sourced by the entrypoint script. This ensures other environment variables in `.env` are not exposed to the agent. This workaround is needed because Apple Container loses `-e` environment variables when using `-i` (interactive mode with piped stdin).
|
||||||
|
|
||||||
### Changing the Assistant Name
|
### Changing the Assistant Name
|
||||||
|
|
||||||
|
|||||||
@@ -111,17 +111,30 @@ function buildVolumeMounts(group: RegisteredGroup, isMain: boolean): VolumeMount
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Environment file directory (workaround for Apple Container -i env var bug)
|
// Environment file directory (workaround for Apple Container -i env var bug)
|
||||||
|
// Only expose specific auth variables needed by Claude Code, not the entire .env
|
||||||
const envDir = path.join(DATA_DIR, 'env');
|
const envDir = path.join(DATA_DIR, 'env');
|
||||||
fs.mkdirSync(envDir, { recursive: true });
|
fs.mkdirSync(envDir, { recursive: true });
|
||||||
const envFile = path.join(projectRoot, '.env');
|
const envFile = path.join(projectRoot, '.env');
|
||||||
if (fs.existsSync(envFile)) {
|
if (fs.existsSync(envFile)) {
|
||||||
fs.copyFileSync(envFile, path.join(envDir, 'env'));
|
const envContent = fs.readFileSync(envFile, 'utf-8');
|
||||||
|
const allowedVars = ['CLAUDE_CODE_OAUTH_TOKEN', 'ANTHROPIC_API_KEY'];
|
||||||
|
const filteredLines = envContent
|
||||||
|
.split('\n')
|
||||||
|
.filter(line => {
|
||||||
|
const trimmed = line.trim();
|
||||||
|
if (!trimmed || trimmed.startsWith('#')) return false;
|
||||||
|
return allowedVars.some(v => trimmed.startsWith(`${v}=`));
|
||||||
|
});
|
||||||
|
|
||||||
|
if (filteredLines.length > 0) {
|
||||||
|
fs.writeFileSync(path.join(envDir, 'env'), filteredLines.join('\n') + '\n');
|
||||||
mounts.push({
|
mounts.push({
|
||||||
hostPath: envDir,
|
hostPath: envDir,
|
||||||
containerPath: '/workspace/env-dir',
|
containerPath: '/workspace/env-dir',
|
||||||
readonly: true
|
readonly: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (group.containerConfig?.additionalMounts) {
|
if (group.containerConfig?.additionalMounts) {
|
||||||
for (const mount of group.containerConfig.additionalMounts) {
|
for (const mount of group.containerConfig.additionalMounts) {
|
||||||
|
|||||||
Reference in New Issue
Block a user