Skip to content
Open
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
114 changes: 86 additions & 28 deletions .github/workflows/amber-issue-handler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ jobs:
NUMBER="${{ github.event.issue.number }}"
TITLE=$(gh issue view "$NUMBER" --repo "${{ github.repository }}" --json title --jq '.title')
echo "number=$NUMBER" >> $GITHUB_OUTPUT
echo "title=$TITLE" >> $GITHUB_OUTPUT
{
echo "title<<EOF"
echo "$TITLE"
echo "EOF"
} >> $GITHUB_OUTPUT

- name: Check for existing PR
id: existing
Expand Down Expand Up @@ -88,11 +92,15 @@ jobs:
unclear requirements, multiple valid approaches, missing context — you
MUST ask for clarification. IMPORTANT: Before calling AskUserQuestion,
ALWAYS send a Slack notification first (the session stops streaming when
AskUserQuestion is called, so the notification must go out before):
AskUserQuestion is called, so the notification must go out before).
Use Slack mrkdwn link format: <URL|display text>. Example:
```bash
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"I have a question about #${{ steps.issue.outputs.number }}\n*Issue*: https://github.com/${{ github.repository }}/issues/${{ steps.issue.outputs.number }}\n*Session*: '"$PLATFORM_HOST/projects/$AGENTIC_SESSION_NAMESPACE/sessions/$AGENTIC_SESSION_NAME"'\n*Question*: <brief summary of what you need>"}' \
"$SLACK_WEBHOOK_URL"
TITLE=$(gh issue view ${{ steps.issue.outputs.number }} --repo ${{ github.repository }} --json title --jq '.title')
PAYLOAD=$(jq -nc --arg text "❓ *Question about <https://github.com/${{ github.repository }}/issues/${{ steps.issue.outputs.number }}|#${{ steps.issue.outputs.number }} — $TITLE>*
<your question here>

<$PLATFORM_HOST/projects/$AGENTIC_SESSION_NAMESPACE/sessions/$AGENTIC_SESSION_NAME|View Session>" '{text: $text}')
curl -X POST -H 'Content-type: application/json' --data "$PAYLOAD" "$SLACK_WEBHOOK_URL"
```
Only send if SLACK_WEBHOOK_URL is set. Then call AskUserQuestion.
4. Implement the fix. Write tests if the area has existing test coverage.
Expand All @@ -104,17 +112,28 @@ jobs:
---
🤖 [Ambient Session]($PLATFORM_HOST/projects/$AGENTIC_SESSION_NAMESPACE/sessions/$AGENTIC_SESSION_NAME)
6. Add the `ambient-code:managed` label to the PR.
7. Ensure CI passes. If it fails, investigate and fix.
8. Do not merge. Leave the PR open for human review.
9. When you comment on the PR, include this footer at the end:
7. After creating the PR, send a Slack notification with a brief summary
of what you changed. Use Slack mrkdwn link format: <URL|display text>. Example:
```bash
TITLE=$(gh issue view ${{ steps.issue.outputs.number }} --repo ${{ github.repository }} --json title --jq '.title')
PAYLOAD=$(jq -nc --arg text "🔧 *PR created for <https://github.com/${{ github.repository }}/issues/${{ steps.issue.outputs.number }}|#${{ steps.issue.outputs.number }} — $TITLE>*
<PR_URL|View PR> · <$PLATFORM_HOST/projects/$AGENTIC_SESSION_NAMESPACE/sessions/$AGENTIC_SESSION_NAME|View Session>

<1-2 sentence summary of what you changed>" '{text: $text}')
curl -X POST -H 'Content-type: application/json' --data "$PAYLOAD" "$SLACK_WEBHOOK_URL"
```
Only send if SLACK_WEBHOOK_URL is set.
8. Ensure CI passes. If it fails, investigate and fix.
9. Do not merge. Leave the PR open for human review.
10. When you comment on the PR, include this footer at the end:
_🤖 [Session]($PLATFORM_HOST/projects/$AGENTIC_SESSION_NAMESPACE/sessions/$AGENTIC_SESSION_NAME)_
repos: >-
[{"url": "https://github.com/${{ github.repository }}", "branch": "main"}]
model: claude-opus-4-6
wait: 'true'
timeout: '0'
environment-variables: >-
{"SLACK_WEBHOOK_URL": "${{ secrets.SLACK_WEBHOOK_URL }}", "PLATFORM_HOST": "${{ secrets.PLATFORM_HOST }}"}
{"SLACK_WEBHOOK_URL": "${{ secrets.SLACK_WEBHOOK_URL }}", "PLATFORM_HOST": "${{ secrets.PLATFORM_HOST }}", "GITHUB_TOKEN": "${{ secrets.GITHUB_TOKEN }}"}
Comment on lines 135 to +136
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.

⚠️ Potential issue | 🟠 Major

Don't give the session the write-scoped workflow token.

These env vars inject the job's GITHUB_TOKEN into model sessions; in the fix/issue flows, those same sessions are explicitly told to consume untrusted issue/PR text first. That makes prompt injection materially worse, even though the new gh issue/pr view ... / gh issue view --comments behavior only needs reads. Prefer fetching the needed GitHub data on the runner, or pass a separate read-only token scoped just to those reads.

As per coding guidelines, "Verify secrets are not exposed and permissions are scoped."

Also applies to: 352-353, 377-378

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/amber-issue-handler.yml around lines 131 - 132, Remove the
full write-scoped GITHUB_TOKEN from the session environment injection: stop
passing "GITHUB_TOKEN" via the environment-variables payload and instead either
fetch required GitHub data on the runner before starting the model sessions
(using the job's token locally) or supply a separate read-only token scoped to
the minimal "issues/PR read" scopes; update the environment-variables entries
(the "environment-variables" key and its JSON) to exclude "GITHUB_TOKEN" and
apply the same change to the other occurrences mentioned (lines corresponding to
the other environment-variables blocks).


- name: Post-session labels and comment
if: steps.existing.outputs.skip != 'true'
Expand Down Expand Up @@ -178,6 +197,13 @@ jobs:
echo "type=pr" >> $GITHUB_OUTPUT
echo "url=https://github.com/${{ github.repository }}/pull/$NUMBER" >> $GITHUB_OUTPUT

TITLE=$(gh pr view "$NUMBER" --repo "${{ github.repository }}" --json title --jq '.title')
{
echo "title<<EOF"
echo "$TITLE"
echo "EOF"
} >> $GITHUB_OUTPUT

IS_FORK=$(gh pr view "$NUMBER" --repo "${{ github.repository }}" --json isCrossRepository --jq '.isCrossRepository')
echo "is_fork=$IS_FORK" >> $GITHUB_OUTPUT

Expand All @@ -188,6 +214,14 @@ jobs:
else
echo "type=issue" >> $GITHUB_OUTPUT
echo "url=https://github.com/${{ github.repository }}/issues/$NUMBER" >> $GITHUB_OUTPUT

TITLE=$(gh issue view "$NUMBER" --repo "${{ github.repository }}" --json title --jq '.title')
{
echo "title<<EOF"
echo "$TITLE"
echo "EOF"
} >> $GITHUB_OUTPUT

echo "is_fork=false" >> $GITHUB_OUTPUT

# Check for existing ambient-code:managed PR for this issue and get its session ID
Expand Down Expand Up @@ -243,14 +277,18 @@ jobs:

## Slack Notifications

When you need human attention — whether you hit the circuit breaker (3 retries),
you're stuck and can't proceed, or you use the AskUserQuestion tool — send a
Slack notification:
When you need human attention — circuit breaker, stuck, or before calling
AskUserQuestion — send a Slack notification. IMPORTANT: Always send BEFORE
calling AskUserQuestion (the session stops streaming on that call).
Use Slack mrkdwn link format: <URL|display text>. Example:

```bash
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"I need human attention\n*PR*: ${{ steps.context.outputs.url }}\n*Session*: '"$PLATFORM_HOST/projects/$AGENTIC_SESSION_NAMESPACE/sessions/$AGENTIC_SESSION_NAME"'\n*Reason*: <brief reason>"}' \
"$SLACK_WEBHOOK_URL"
TITLE=$(gh pr view ${{ steps.context.outputs.number }} --repo ${{ github.repository }} --json title --jq '.title')
PAYLOAD=$(jq -nc --arg text "🚨 *Need help with <${{ steps.context.outputs.url }}|PR #${{ steps.context.outputs.number }} — $TITLE>*
<reason — what you tried and why you're stuck>

<$PLATFORM_HOST/projects/$AGENTIC_SESSION_NAMESPACE/sessions/$AGENTIC_SESSION_NAME|View Session>" '{text: $text}')
curl -X POST -H 'Content-type: application/json' --data "$PAYLOAD" "$SLACK_WEBHOOK_URL"
```

The environment variables SLACK_WEBHOOK_URL, PLATFORM_HOST, AGENTIC_SESSION_NAMESPACE,
Expand Down Expand Up @@ -283,11 +321,15 @@ jobs:
unclear requirements, multiple valid approaches, missing context — you
MUST ask for clarification. IMPORTANT: Before calling AskUserQuestion,
ALWAYS send a Slack notification first (the session stops streaming when
AskUserQuestion is called, so the notification must go out before):
AskUserQuestion is called, so the notification must go out before).
Use Slack mrkdwn link format: <URL|display text>. Example:
```bash
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"I have a question about #${{ steps.context.outputs.number }}\n*Issue*: ${{ steps.context.outputs.url }}\n*Session*: '"$PLATFORM_HOST/projects/$AGENTIC_SESSION_NAMESPACE/sessions/$AGENTIC_SESSION_NAME"'\n*Question*: <brief summary of what you need>"}' \
"$SLACK_WEBHOOK_URL"
TITLE=$(gh issue view ${{ steps.context.outputs.number }} --repo ${{ github.repository }} --json title --jq '.title')
PAYLOAD=$(jq -nc --arg text "❓ *Question about <${{ steps.context.outputs.url }}|#${{ steps.context.outputs.number }} — $TITLE>*
<your question here>

<$PLATFORM_HOST/projects/$AGENTIC_SESSION_NAMESPACE/sessions/$AGENTIC_SESSION_NAME|View Session>" '{text: $text}')
curl -X POST -H 'Content-type: application/json' --data "$PAYLOAD" "$SLACK_WEBHOOK_URL"
```
Only send if SLACK_WEBHOOK_URL is set. Then call AskUserQuestion.
4. Implement the fix. Write tests if the area has existing test coverage.
Expand All @@ -299,17 +341,28 @@ jobs:
---
🤖 [Ambient Session]($PLATFORM_HOST/projects/$AGENTIC_SESSION_NAMESPACE/sessions/$AGENTIC_SESSION_NAME)
6. Add the `ambient-code:managed` label to the PR.
7. Ensure CI passes. If it fails, investigate and fix.
8. Do not merge. Leave the PR open for human review.
9. When you comment on the PR, include this footer at the end:
7. After creating the PR, send a Slack notification with a brief summary
of what you changed. Use Slack mrkdwn link format: <URL|display text>. Example:
```bash
TITLE=$(gh issue view ${{ steps.context.outputs.number }} --repo ${{ github.repository }} --json title --jq '.title')
PAYLOAD=$(jq -nc --arg text "🔧 *PR created for <${{ steps.context.outputs.url }}|#${{ steps.context.outputs.number }} — $TITLE>*
<PR_URL|View PR> · <$PLATFORM_HOST/projects/$AGENTIC_SESSION_NAMESPACE/sessions/$AGENTIC_SESSION_NAME|View Session>

<1-2 sentence summary of what you changed>" '{text: $text}')
curl -X POST -H 'Content-type: application/json' --data "$PAYLOAD" "$SLACK_WEBHOOK_URL"
```
Only send if SLACK_WEBHOOK_URL is set.
8. Ensure CI passes. If it fails, investigate and fix.
9. Do not merge. Leave the PR open for human review.
10. When you comment on the PR, include this footer at the end:
_🤖 [Session]($PLATFORM_HOST/projects/$AGENTIC_SESSION_NAMESPACE/sessions/$AGENTIC_SESSION_NAME)_
repos: >-
[{"url": "https://github.com/${{ github.repository }}", "branch": "main"}]
model: claude-opus-4-6
wait: 'true'
timeout: '0'
environment-variables: >-
{"SLACK_WEBHOOK_URL": "${{ secrets.SLACK_WEBHOOK_URL }}", "PLATFORM_HOST": "${{ secrets.PLATFORM_HOST }}"}
{"SLACK_WEBHOOK_URL": "${{ secrets.SLACK_WEBHOOK_URL }}", "PLATFORM_HOST": "${{ secrets.PLATFORM_HOST }}", "GITHUB_TOKEN": "${{ secrets.GITHUB_TOKEN }}"}

# Custom prompt: @ambient-code <instruction> — pass user's text
- name: Run custom prompt
Expand All @@ -334,7 +387,7 @@ jobs:
wait: 'true'
timeout: '0'
environment-variables: >-
{"SLACK_WEBHOOK_URL": "${{ secrets.SLACK_WEBHOOK_URL }}", "PLATFORM_HOST": "${{ secrets.PLATFORM_HOST }}"}
{"SLACK_WEBHOOK_URL": "${{ secrets.SLACK_WEBHOOK_URL }}", "PLATFORM_HOST": "${{ secrets.PLATFORM_HOST }}", "GITHUB_TOKEN": "${{ secrets.GITHUB_TOKEN }}"}

- name: Post check run on PR
if: >-
Expand Down Expand Up @@ -656,11 +709,16 @@ jobs:

## Slack Notifications

When you need human attention — circuit breaker, stuck, or using AskUserQuestion — send:
When you need human attention — circuit breaker, stuck, or before calling
AskUserQuestion — send a Slack notification. IMPORTANT: Always send BEFORE
calling AskUserQuestion. Use Slack mrkdwn link format: <URL|display text>.

TITLE=$(gh pr view {number} --repo {REPO} --json title --jq '.title')
PAYLOAD=$(jq -nc --arg text "🚨 *Need help with <https://github.com/{REPO}/pull/{number}|PR #{number} — $TITLE>*
<reason — what you tried and why you are stuck>

curl -X POST -H 'Content-type: application/json' \\
--data '{{"text":"I need human attention\\n*PR*: https://github.com/{REPO}/pull/{number}\\n*Session*: '"$PLATFORM_HOST/projects/$AGENTIC_SESSION_NAMESPACE/sessions/$AGENTIC_SESSION_NAME"'\\n*Reason*: <brief reason>"}}' \\
"$SLACK_WEBHOOK_URL"
<$PLATFORM_HOST/projects/$AGENTIC_SESSION_NAMESPACE/sessions/$AGENTIC_SESSION_NAME|View Session>" '{{text: $text}}')
curl -X POST -H 'Content-type: application/json' --data "$PAYLOAD" "$SLACK_WEBHOOK_URL"

Only send if SLACK_WEBHOOK_URL is set."""

Expand Down
Loading