Conversation
|
👋 Hey @p-datadog, please fill "Change log entry" section in the pull request description. If changes need to be present in CHANGELOG.md you can state it this way **Change log entry**
Yes. A brief summary to be placed into the CHANGELOG.md(possible answers Yes/Yep/Yeah) Or you can opt out like that **Change log entry**
None.(possible answers No/Nope/None) Visited at: 2026-02-12 18:13:07 UTC |
|
|
To be added: when creating a pull request description, always use the template in the repo when creating a pull request description, change log section should be written for customers and reflect whether there are customer-visible changes in the diff |
|
● # GitHub Actions Security Guidelines When creating or modifying GitHub Actions workflows, follow these security principles and validation steps. Security Principles1. Prevent Template InjectionNever directly interpolate GitHub context variables into shell commands: # BAD - Vulnerable to injection
run: |
COMMENT="${{ github.event.comment.body }}"
git pull origin ${{ github.head_ref }}
Always use one of these safe patterns:
# GOOD - Use env variables (GitHub escapes these)
env:
COMMENT_BODY: ${{ github.event.comment.body }}
BRANCH: ${{ github.head_ref }}
run: |
echo "Comment: $COMMENT_BODY"
git pull origin "$BRANCH"
# GOOD - Use actions/github-script for user input
- uses: actions/github-script@<hash>
with:
script: |
const comment = context.payload.comment.body;
// Process safely in JavaScript
2. Use Minimal Permissions
Always specify explicit permissions at the job level:
jobs:
my-job:
permissions:
contents: write
pull-requests: write
issues: write # Only what you need
Never use permissions: write-all or omit permissions when the job needs them.
3. Avoid Dangerous Triggers
- Prefer pull_request over pull_request_target
- If using pull_request_target or issue_comment, add explicit permission checks
- Add # zizmor: ignore[dangerous-triggers] with justification if necessary
4. Pin Action Versions
# GOOD - Pinned to SHA
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# BAD - Mutable tag
uses: actions/checkout@v6
5. Handle User Input Safely
Any data from these contexts is user-controllable and potentially malicious:
- github.event.comment.body
- github.event.issue.title
- github.event.issue.body
- github.event.pull_request.title
- github.event.pull_request.body
- github.head_ref (branch names)
- github.event.pull_request.head.ref
Always pass these through env: or use actions/github-script.
Validation Checklist
After creating or modifying a workflow:
1. Run yamllint
yamllint .github/workflows/your-workflow.yml
2. Check for template injection
- Search for ${{ github.event in run: blocks
- Ensure all such variables go through env: or github-script
3. Review permissions
- Each job should have explicit permissions:
- Check that permissions are minimal
4. Verify action pins
- All uses: should reference SHA hashes with version comments
5. Check for dangerous patterns
- No eval or command execution of user input
- No secrets passed to untrusted code
- No pull_request_target without permission checks
Common Vulnerabilities
Injection in Branch Names
# BAD
run: git checkout ${{ github.head_ref }}
# GOOD
env:
BRANCH: ${{ github.head_ref }}
run: git checkout "$BRANCH"
Injection in PR Titles
# BAD
run: echo "Processing PR: ${{ github.event.pull_request.title }}"
# GOOD
- uses: actions/github-script@<hash>
with:
script: |
const title = context.payload.pull_request.title;
console.log(`Processing PR: ${title}`);
Command Construction
# BAD
run: |
COMMENT="${{ github.event.comment.body }}"
if [[ "$COMMENT" == "/deploy"* ]]; then
deploy
fi
# GOOD
- uses: actions/github-script@<hash>
with:
script: |
const comment = context.payload.comment.body;
if (comment.startsWith('/deploy')) {
// Safe string comparison in JavaScript
}
Tools
- yamllint: YAML syntax validation
- actionlint: GitHub Actions linting (if available)
- zizmor: Security auditing (when available in CI)
When zizmor is not locally available, manually verify the patterns above, especially template-injection vulnerabilities.
References
- https://docs.zizmor.sh/
- https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions
|
|
● # GitHub Actions Workflow Creation Checklist Follow these steps IN ORDER when creating or modifying GitHub Actions workflows. Phase 1: Security Design (Before Writing Code)1. Identify User-Controllable InputsList all inputs that can be controlled by external users:
Rule: NEVER interpolate these directly into 2. Choose Safe PatternsFor each user-controlled input, use ONE of: Pattern A: Environment Variables (Preferred for Simple Cases) env:
USER_INPUT: ${{ github.event.comment.body }}
run: |
echo "Processing: $USER_INPUT"
Pattern B: GitHub Script (Preferred for Complex Logic)
- uses: actions/github-script@<hash>
with:
script: |
const input = context.payload.comment.body;
// Process safely in JavaScript
NEVER do this:
run: |
COMMENT="${{ github.event.comment.body }}" # ❌ INJECTION RISK
3. Design Permission Model
Workflow Level:
# Default permissions for all jobs
permissions: {}
Job Level (Required for Each Job):
jobs:
my-job:
permissions:
contents: read # Only what you need
pull-requests: write
issues: write
List needed permissions:
- contents: read/write - Repository access
- pull-requests: read/write - PR operations
- issues: read/write - Issue/PR comments
- actions: read - Workflow metadata
Phase 2: Implementation
1. File Structure Template
name: Workflow Name
on:
trigger_type:
types: [created]
# Default permissions for all jobs
permissions: {}
jobs:
job-name:
runs-on: ubuntu-22.04
permissions:
contents: read
# ... minimal needed permissions
steps:
# ...
2. Shell Script Rules
A. Always Quote Variables
# ✅ GOOD
run: echo "value" >> "$GITHUB_OUTPUT"
# ❌ BAD
run: echo "value" >> $GITHUB_OUTPUT
B. Group Multiple Redirects
# ✅ GOOD
run: |
{
echo "key1=value1"
echo "key2=value2"
echo "key3=value3"
} >> "$GITHUB_OUTPUT"
# ❌ BAD
run: |
echo "key1=value1" >> "$GITHUB_OUTPUT"
echo "key2=value2" >> "$GITHUB_OUTPUT"
echo "key3=value3" >> "$GITHUB_OUTPUT"
C. Avoid Heredocs in YAML
# ✅ GOOD - Use echo with command grouping
run: |
{
echo "Line 1"
echo "Line 2"
cat other_file.txt
} > output.txt
# ❌ BAD - Heredocs confuse YAML parsers
run: |
cat > output.txt <<EOF
Line 1
Line 2
EOF
D. Use Environment Variables for GitHub Contexts
# ✅ GOOD
env:
PR_NUMBER: ${{ needs.job.outputs.pr-number }}
REPO: ${{ github.repository }}
run: |
gh pr view "$PR_NUMBER" --repo "$REPO"
# ❌ BAD
run: |
PR_NUMBER="${{ needs.job.outputs.pr-number }}"
gh pr view "$PR_NUMBER" --repo "${{ github.repository }}"
3. Step IDs
Rule: Every step ID must be unique across the entire job.
# ✅ GOOD
- name: Check A
id: check-a
- name: Check B
id: check-b
# ❌ BAD
- name: Check A
id: check
- name: Check B
id: check # Duplicate!
4. Action Pinning
# ✅ GOOD
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# ❌ BAD
uses: actions/checkout@v6
5. File Handling for Complex Content
For multiline user content (PR descriptions, etc.):
# ✅ GOOD - Write to file, then use --body-file
run: |
echo "$PR_BODY" > /tmp/body.txt
gh pr create --body-file /tmp/body.txt
# ❌ BAD - Pass directly (breaks with quotes/special chars)
run: |
gh pr create --body "$PR_BODY"
Phase 3: Validation (Run Every Time)
1. YAML Syntax
yamllint --strict .github/workflows/your-workflow.yml
Fix all errors before proceeding.
2. Action Linting
actionlint .github/workflows/your-workflow.yml
Common actionlint/shellcheck issues:
- SC2086: Unquoted variable → Add quotes: "$VAR"
- SC2129: Multiple redirects → Use { cmd1; cmd2; } >> file
- Expression evaluation errors → Check ${{ }} syntax
3. Manual Security Review
Check EVERY run: block for:
- No direct interpolation of user input (github.event.*)
- All variables quoted: "$VAR" not $VAR
- Using env vars or github-script for user data
Check workflow structure:
- Top-level permissions: {} exists
- Each job has explicit permissions: block
- No over-scoped permissions (write when read is enough)
4. Changelog Entry (Repository-Specific)
For DataDog/dd-trace-rb:
**Change log entry**
None. This is an internal tooling change for maintainers, not customer-visible.
Format: Must start with "None/No/Nope" for opt-out, or "Yes/Yeah/Yep" followed by message.
Phase 4: Common Patterns Reference
Pattern: Permission Check with Comment Trigger
on:
issue_comment:
types: [created]
permissions: {}
jobs:
check:
runs-on: ubuntu-22.04
permissions:
contents: read
issues: write
pull-requests: read
steps:
- uses: actions/github-script@<hash>
with:
script: |
const { data: perm } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: context.actor
});
const hasPermission = ['admin', 'write'].includes(perm.permission);
if (!hasPermission) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: '❌ Permission denied'
});
}
core.setOutput('has-permission', hasPermission);
Pattern: Safe Command Parsing
- uses: actions/github-script@<hash>
with:
script: |
const comment = context.payload.comment.body;
const isCommand = comment.startsWith('/mycommand');
core.setOutput('is-command', isCommand);
Pattern: Multiline Output
env:
DATA: ${{ steps.previous.outputs.data }}
run: |
echo "$DATA" > /tmp/data.txt
# Process file safely
Validation Checklist Summary
Before submitting PR, verify:
- yamllint --strict passes
- actionlint passes (including shellcheck rules)
- Top-level permissions: {} present
- Each job has explicit minimal permissions: block
- No direct interpolation of user input in run: blocks
- All shell variables quoted: "$VAR"
- Multiple redirects use command grouping { }
- All step IDs unique
- All actions pinned to SHA hashes with version comments
- Changelog entry follows repository format
- No heredocs (use echo grouping instead)
Remember
1. Security first - Design permissions and input handling before writing code
2. Quote everything - Shell variables, especially $GITHUB_OUTPUT
3. Explicit permissions - Both workflow-level and job-level
4. Validate early - Run linters after every change, not just at the end
5. User input is hostile - Always assume malicious content in github.event.*
|
|
When asked to create a pull request description, always start with the pull request template in this repository. Write the description to be relevant to a developer performing the code review. Be concise in the description: use one sentence for each relevant point. When writing summary or motivation, there may be multiple relevant points; state each of them, with one sentence each. For the change log entry, always consider the changes from the user/customer's point of view only. Note: telemetry is an internal tool and telemetry changes are not customer-visible unless explicitly stated otherwise. |
|
If user requested information from a specific web page, and you are not able to fully read that web page for any reason, ALWAYS notify the user of your failure to access the page, explicitly state that you do not have the actual page content, and if you make any suggestions or propose changes explain what your proposal is based on other than the page contents. |
What does this PR do?
Adds claude instructions file
Motivation:
Where claude did not do what I want I asked it to make a note for itself to get it right next time
Change log entry
Additional Notes:
The entire file is claude-generated and probably should be revised before merging
How to test the change?