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
14 changes: 8 additions & 6 deletions .github/workflows/smoke-antigravity.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 12 additions & 16 deletions pkg/workflow/antigravity_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,20 +164,10 @@ func (e *AntigravityEngine) GetExecutionSteps(workflowData *WorkflowData, logFil
// The conversion script (convert_gateway_config_antigravity.sh) writes settings.json
// during the MCP setup step, so no --mcp-config flag is needed here.

// Auto-approve all tool executions (equivalent to Codex's --dangerously-bypass-approvals-and-sandbox)
// Without this, Antigravity CLI's default approval mode rejects tool calls with "Tool execution denied by policy"
agyArgs = append(agyArgs, "--yolo")

// Skip the workspace trust check so --yolo is not overridden to "default" approval mode.
// Antigravity CLI v1.x checks whether the working directory is trusted and overrides --yolo
// with "default" approval mode (exit code 55) when the folder is untrusted.
// ANTIGRAVITY_CLI_TRUST_WORKSPACE=true (also set in the step env) handles the same case via
// environment variable, but --skip-trust is more reliable when AWF's sandbox does not
// forward all host environment variables into the container.
agyArgs = append(agyArgs, "--skip-trust")

// Add streaming JSON output (JSONL format, compatible with the log parser)
agyArgs = append(agyArgs, "--output-format", "stream-json")
// Auto-approve all tool executions so non-interactive CI runs don't block on permission prompts.
// agy does not support the Gemini-style --yolo/--skip-trust flags.
// This flag grants broad tool permission inside the workflow sandbox, so it is only used in AWF-managed runs.
agyArgs = append(agyArgs, "--dangerously-skip-permissions")

// Note: the --prompt argument is appended raw after shellJoinArgs below because it contains
// a shell command substitution ("$(cat ...)") that must NOT go through shellEscapeArg —
Expand Down Expand Up @@ -233,7 +223,7 @@ func (e *AntigravityEngine) GetExecutionSteps(workflowData *WorkflowData, logFil
PathSetup: "touch " + AgentStepSummaryPath,
// Exclude every env var whose step-env value is a secret so the agent
// cannot read raw token values via bash tools (env / printenv).
ExcludeEnvVarNames: ComputeAWFExcludeEnvVarNames(workflowData, []string{"ANTIGRAVITY_API_KEY"}),
ExcludeEnvVarNames: ComputeAWFExcludeEnvVarNames(workflowData, []string{"ANTIGRAVITY_API_KEY", "GEMINI_API_KEY"}),
})
} else {
command = fmt.Sprintf(`set -o pipefail
Expand Down Expand Up @@ -320,6 +310,12 @@ touch %s
maps.Copy(env, agentConfig.Env)
antigravityLog.Printf("Added %d custom env vars from agent config", len(agentConfig.Env))
}
// The Antigravity CLI and AWF's Gemini API proxy both rely on a Gemini provider key.
// Keep GEMINI_API_KEY aligned with the effective ANTIGRAVITY_API_KEY by default so the
// workflow can authenticate non-interactively without requiring users to duplicate secrets.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Silent empty-string assignment if ANTIGRAVITY_API_KEY is absent from env: env["GEMINI_API_KEY"] will be set to "" rather than being omitted, injecting a blank credential into the step environment.

💡 Suggested fix
    if v := env["ANTIGRAVITY_API_KEY"]; v != "" {
        env["GEMINI_API_KEY"] = v
    }
}

If ANTIGRAVITY_API_KEY is missing or empty (e.g., due to a misconfigured workflow or a future reordering of env population), the current code silently forwards an empty string as GEMINI_API_KEY. The proxy will then receive a blank API key and fail with a confusing auth error rather than a clear "key not set" diagnostic. An explicit non-empty guard prevents this silent path.

if _, hasGeminiKey := env["GEMINI_API_KEY"]; !hasGeminiKey {
env["GEMINI_API_KEY"] = env["ANTIGRAVITY_API_KEY"]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/diagnose] If ANTIGRAVITY_API_KEY is absent from env, this silently sets GEMINI_API_KEY to an empty string, which will pass the FilterEnvForSecrets check and appear in the step env as an empty value — a subtle auth failure that's hard to diagnose.

💡 Suggested guard
if apiKey, hasAPIKey := env["ANTIGRAVITY_API_KEY"]; hasAPIKey && apiKey != "" {
    env["GEMINI_API_KEY"] = apiKey
}

Or at minimum log a warning when propagation is skipped, so the misconfiguration surfaces early in the run log rather than as a 401 from the proxy.

}

// Generate the execution step
stepLines := []string{
Expand All @@ -328,7 +324,7 @@ touch %s
}

// Filter environment variables for security
allowedSecrets := e.GetRequiredSecretNames(workflowData)
allowedSecrets := append([]string{"GEMINI_API_KEY"}, e.GetRequiredSecretNames(workflowData)...)
filteredEnv := FilterEnvForSecrets(env, allowedSecrets)

// Inject GH_TOKEN for CLI proxy (added after filtering since it uses a special
Expand Down
Loading
Loading