Skip to content
Open
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
19 changes: 1 addition & 18 deletions .github/workflows/build-test-java.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,24 +50,7 @@ Clone and test the following projects from the test repository:
1. **Clone Repository**: `gh repo clone Mossaka/gh-aw-firewall-test-java /tmp/test-java`
- **CRITICAL**: If clone fails, immediately call `safeoutputs-missing_tool` with message "CLONE_FAILED: Unable to clone test repository" and stop execution

2. **Configure Maven Proxy**: Maven ignores Java system properties for proxy configuration, so you must create `~/.m2/settings.xml` before running any Maven commands. **IMPORTANT**: Use the literal values `squid-proxy` and `3128` directly in the XML - do NOT use shell variables or environment variable syntax:
```bash
mkdir -p ~/.m2
cat > ~/.m2/settings.xml << 'SETTINGS'
<settings>
<proxies>
<proxy>
<id>awf-http</id><active>true</active><protocol>http</protocol>
<host>squid-proxy</host><port>3128</port>
</proxy>
<proxy>
<id>awf-https</id><active>true</active><protocol>https</protocol>
<host>squid-proxy</host><port>3128</port>
</proxy>
</proxies>
</settings>
SETTINGS
```
2. **Maven Proxy**: Maven proxy configuration (`~/.m2/settings.xml`) is automatically generated by AWF's agent container entrypoint. No manual setup is needed.

3. **Test Projects**:
- `gson`: `cd /tmp/test-java/gson && mvn compile && mvn test`
Expand Down
33 changes: 33 additions & 0 deletions containers/agent/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,39 @@ echo "[entrypoint] Proxy configuration:"
echo "[entrypoint] HTTP_PROXY=$HTTP_PROXY"
echo "[entrypoint] HTTPS_PROXY=$HTTPS_PROXY"

# Generate Maven settings.xml with proxy configuration
# Maven ignores JAVA_TOOL_OPTIONS and HTTP_PROXY; it requires ~/.m2/settings.xml
if [ -n "$SQUID_PROXY_HOST" ] && [ -n "$SQUID_PROXY_PORT" ]; then
MAVEN_DIR="$(eval echo ~awfuser)/.m2"
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

The MAVEN_DIR should use $HOME instead of ~awfuser, and needs chroot mode handling. The HOME environment variable is set to the real user's home directory (via getRealUserHome() in docker-manager.ts, e.g., /home/runner on GitHub Actions), not /home/awfuser. Maven will look for settings.xml in $HOME/.m2/, not /home/awfuser/.m2/.

Additionally, in chroot mode, the file must be created at /host$HOME/.m2/settings.xml to be accessible after the chroot transition, following the same pattern as Claude Code configuration (lines 130-134).

Replace line 173 with:

if [ "${AWF_CHROOT_ENABLED}" = "true" ]; then
  MAVEN_DIR="/host$HOME/.m2"
else
  MAVEN_DIR="$HOME/.m2"
fi
Suggested change
MAVEN_DIR="$(eval echo ~awfuser)/.m2"
if [ "${AWF_CHROOT_ENABLED}" = "true" ]; then
MAVEN_DIR="/host$HOME/.m2"
else
MAVEN_DIR="$HOME/.m2"
fi

Copilot uses AI. Check for mistakes.
if [ ! -f "$MAVEN_DIR/settings.xml" ]; then
mkdir -p "$MAVEN_DIR"
cat > "$MAVEN_DIR/settings.xml" << MAVEN_SETTINGS
<settings>
<proxies>
<proxy>
<id>awf-http</id>
<active>true</active>
<protocol>http</protocol>
<host>${SQUID_PROXY_HOST}</host>
<port>${SQUID_PROXY_PORT}</port>
</proxy>
<proxy>
<id>awf-https</id>
<active>true</active>
<protocol>https</protocol>
<host>${SQUID_PROXY_HOST}</host>
<port>${SQUID_PROXY_PORT}</port>
</proxy>
</proxies>
</settings>
MAVEN_SETTINGS
chown awfuser:awfuser "$MAVEN_DIR" "$MAVEN_DIR/settings.xml"
echo "[entrypoint] ✓ Generated Maven settings.xml with proxy configuration"
else
echo "[entrypoint] Maven settings.xml already exists, skipping generation"
fi
fi

# Print network information
echo "[entrypoint] Network information:"
echo "[entrypoint] IP address: $(hostname -I)"
Expand Down
36 changes: 7 additions & 29 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,47 +161,25 @@

AWF automatically sets `JAVA_TOOL_OPTIONS` with `-Dhttp.proxyHost`, `-Dhttp.proxyPort`, `-Dhttps.proxyHost`, `-Dhttps.proxyPort`, and `-Dhttp.nonProxyHosts` inside the agent container. This works for most Java tools that read standard JVM system properties, including Gradle and SBT.

### Maven Requires Extra Configuration
AWF also automatically generates `~/.m2/settings.xml` with proxy configuration in the agent container entrypoint. This ensures Maven builds work out of the box without manual configuration.

**Problem:** Maven builds fail with network errors even though the domain is in `--allow-domains`

**Cause:** Maven's HTTP transport (Apache HttpClient / Maven Resolver) ignores Java system properties for proxy configuration. Unlike Gradle and most other Java tools, Maven does **not** read `-DproxyHost`/`-DproxyPort` from `JAVA_TOOL_OPTIONS`.

**Solution:** Create `~/.m2/settings.xml` with proxy configuration before running Maven:

```bash
mkdir -p ~/.m2
cat > ~/.m2/settings.xml << EOF
<settings>
<proxies>
<proxy>
<id>awf-http</id><active>true</active><protocol>http</protocol>
<host>${SQUID_PROXY_HOST}</host><port>${SQUID_PROXY_PORT}</port>
</proxy>
<proxy>
<id>awf-https</id><active>true</active><protocol>https</protocol>
<host>${SQUID_PROXY_HOST}</host><port>${SQUID_PROXY_PORT}</port>
</proxy>
</proxies>
</settings>
EOF
```
### Gradle Works Automatically

The `SQUID_PROXY_HOST` and `SQUID_PROXY_PORT` environment variables are automatically set by AWF in the agent container.
Gradle reads JVM system properties via `ProxySelector.getDefault()`, so the `JAVA_TOOL_OPTIONS` environment variable set by AWF is sufficient. No extra configuration is needed for Gradle builds.

For agentic workflows, add this as a setup step in the workflow `.md` file so the agent creates the file before running Maven commands.
### Maven Works Automatically

### Gradle Works Automatically
Maven's HTTP transport (Apache HttpClient / Maven Resolver) ignores `JAVA_TOOL_OPTIONS` for proxy configuration. AWF handles this by automatically generating `~/.m2/settings.xml` with proxy settings in the agent container entrypoint. No manual configuration is needed.

Gradle reads JVM system properties via `ProxySelector.getDefault()`, so the `JAVA_TOOL_OPTIONS` environment variable set by AWF is sufficient. No extra configuration is needed for Gradle builds.
If you need to override the auto-generated `settings.xml` (e.g., to add custom repositories or mirrors), create your own `~/.m2/settings.xml` before running Maven — the entrypoint will not overwrite an existing file if one is bind-mounted.

### Why This Is Needed

AWF uses a forward proxy (Squid) for HTTPS egress control rather than transparent interception. This means tools must be proxy-aware:

- **Most tools**: Use `HTTP_PROXY`/`HTTPS_PROXY` environment variables (set automatically by AWF)
- **Java tools**: Use `JAVA_TOOL_OPTIONS` with JVM system properties (set automatically by AWF)
- **Maven**: Requires `~/.m2/settings.xml` (must be configured manually — see above)
- **Maven**: Uses `~/.m2/settings.xml` (generated automatically by AWF)

## Log Analysis

Expand Down
13 changes: 13 additions & 0 deletions src/docker-manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,19 @@ describe('docker-manager', () => {
expect(env.SQUID_PROXY_PORT).toBe('3128');
});

it('should set JAVA_TOOL_OPTIONS with JVM proxy properties', () => {
const result = generateDockerCompose(mockConfig, mockNetworkConfig);
const agent = result.services.agent;
const env = agent.environment as Record<string, string>;

expect(env.JAVA_TOOL_OPTIONS).toBeDefined();
expect(env.JAVA_TOOL_OPTIONS).toContain('-Dhttp.proxyHost=squid-proxy');
expect(env.JAVA_TOOL_OPTIONS).toContain('-Dhttp.proxyPort=3128');
expect(env.JAVA_TOOL_OPTIONS).toContain('-Dhttps.proxyHost=squid-proxy');
expect(env.JAVA_TOOL_OPTIONS).toContain('-Dhttps.proxyPort=3128');
expect(env.JAVA_TOOL_OPTIONS).toContain('-Dhttp.nonProxyHosts=localhost|127.0.0.1');
});

it('should mount required volumes in agent container (default behavior)', () => {
const result = generateDockerCompose(mockConfig, mockNetworkConfig);
const agent = result.services.agent;
Expand Down
4 changes: 4 additions & 0 deletions src/docker-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,10 @@ export function generateDockerCompose(
HTTPS_PROXY: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
SQUID_PROXY_HOST: 'squid-proxy',
SQUID_PROXY_PORT: SQUID_PORT.toString(),
// JVM proxy configuration: Java ignores HTTP_PROXY/HTTPS_PROXY and requires
// system properties via JAVA_TOOL_OPTIONS. Works for Gradle, SBT, and most JVM tools.
// Maven requires separate ~/.m2/settings.xml (generated by entrypoint.sh).
JAVA_TOOL_OPTIONS: `-Dhttp.proxyHost=squid-proxy -Dhttp.proxyPort=${SQUID_PORT} -Dhttps.proxyHost=squid-proxy -Dhttps.proxyPort=${SQUID_PORT} -Dhttp.nonProxyHosts=localhost|127.0.0.1`,
HOME: homeDir,
PATH: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
// Configure one-shot-token library with sensitive tokens to protect
Expand Down
Loading