Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions src/docker-manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1382,6 +1382,78 @@ describe('docker-manager', () => {
expect(env.ANOTHER_VAR).toBe('another_value');
});

it('should never pass ACTIONS_RUNTIME_TOKEN to agent container', () => {
const originalToken = process.env.ACTIONS_RUNTIME_TOKEN;
process.env.ACTIONS_RUNTIME_TOKEN = 'test-runtime-token-value';

try {
// Should not be passed in default mode
const result = generateDockerCompose(mockConfig, mockNetworkConfig);
const env = result.services.agent.environment as Record<string, string>;
expect(env.ACTIONS_RUNTIME_TOKEN).toBeUndefined();
} finally {
if (originalToken !== undefined) {
process.env.ACTIONS_RUNTIME_TOKEN = originalToken;
} else {
delete process.env.ACTIONS_RUNTIME_TOKEN;
}
}
});

it('should never pass ACTIONS_RESULTS_URL to agent container', () => {
const originalUrl = process.env.ACTIONS_RESULTS_URL;
process.env.ACTIONS_RESULTS_URL = 'https://results-receiver.actions.githubusercontent.com/';

try {
// Should not be passed in default mode
const result = generateDockerCompose(mockConfig, mockNetworkConfig);
const env = result.services.agent.environment as Record<string, string>;
expect(env.ACTIONS_RESULTS_URL).toBeUndefined();
} finally {
if (originalUrl !== undefined) {
process.env.ACTIONS_RESULTS_URL = originalUrl;
} else {
delete process.env.ACTIONS_RESULTS_URL;
}
}
});

it('should exclude ACTIONS_RUNTIME_TOKEN from env-all passthrough', () => {
const originalToken = process.env.ACTIONS_RUNTIME_TOKEN;
process.env.ACTIONS_RUNTIME_TOKEN = 'test-runtime-token-value';

try {
const configWithEnvAll = { ...mockConfig, envAll: true };
const result = generateDockerCompose(configWithEnvAll, mockNetworkConfig);
const env = result.services.agent.environment as Record<string, string>;
expect(env.ACTIONS_RUNTIME_TOKEN).toBeUndefined();
} finally {
if (originalToken !== undefined) {
process.env.ACTIONS_RUNTIME_TOKEN = originalToken;
} else {
delete process.env.ACTIONS_RUNTIME_TOKEN;
}
}
});

it('should exclude ACTIONS_RESULTS_URL from env-all passthrough', () => {
const originalUrl = process.env.ACTIONS_RESULTS_URL;
process.env.ACTIONS_RESULTS_URL = 'https://results-receiver.actions.githubusercontent.com/';

try {
const configWithEnvAll = { ...mockConfig, envAll: true };
const result = generateDockerCompose(configWithEnvAll, mockNetworkConfig);
const env = result.services.agent.environment as Record<string, string>;
expect(env.ACTIONS_RESULTS_URL).toBeUndefined();
} finally {
if (originalUrl !== undefined) {
process.env.ACTIONS_RESULTS_URL = originalUrl;
} else {
delete process.env.ACTIONS_RESULTS_URL;
}
}
});

it('should exclude system variables when envAll is enabled', () => {
const originalPath = process.env.PATH;
process.env.CUSTOM_HOST_VAR = 'test_value';
Expand Down
6 changes: 6 additions & 0 deletions src/docker-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,12 @@ export function generateDockerCompose(
'SUDO_USER', // Sudo metadata
'SUDO_UID', // Sudo metadata
'SUDO_GID', // Sudo metadata
// GitHub Actions artifact service tokens — excluded from inherited environment
// propagation to prevent agents from uploading arbitrary data as workflow artifacts
// (potential data exfiltration vector). These tokens are only needed by the
// Actions runner itself, not by the agent.
'ACTIONS_RUNTIME_TOKEN',
'ACTIONS_RESULTS_URL',
]);

// When api-proxy is enabled, exclude API keys from agent environment
Expand Down
Loading