You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .cursor/rules/reusable-workflows.mdc
+86Lines changed: 86 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -417,6 +417,92 @@ uses: some-action/tool@main # use a specific tag or SHA
417
417
- Never print secrets via `echo`, env dumps, or step summaries
418
418
- Complex conditional logic belongs in the workflow (not in composites) — full log visibility
419
419
420
+
### pull_request_target — NEVER checkout fork code
421
+
422
+
- NEVER use `actions/checkout` with `ref: ${{ github.event.pull_request.head.ref }}` or `ref: ${{ github.event.pull_request.head.sha }}` in `pull_request_target` workflows
423
+
- If `pull_request_target` is needed (e.g., labeling, commenting), it MUST NOT run any code from the fork (no build, no test, no script execution from the PR branch)
424
+
- Prefer `pull_request` trigger over `pull_request_target` unless write permissions to the base repo are explicitly required
425
+
- NEVER use `secrets: inherit` in workflows triggered by `pull_request_target` — it exposes all repository secrets to fork code
426
+
427
+
### Expression injection — sanitize ALL untrusted inputs
428
+
429
+
NEVER use these directly in `run:` steps:
430
+
431
+
```yaml
432
+
# ❌ All of these are injectable — NEVER interpolate directly in run:
433
+
${{ github.event.pull_request.title }}
434
+
${{ github.event.pull_request.body }}
435
+
${{ github.event.issue.title }}
436
+
${{ github.event.issue.body }}
437
+
${{ github.event.comment.body }}
438
+
${{ github.event.head_commit.message }}
439
+
${{ github.event.head_commit.author.name }}
440
+
${{ github.event.commits[*].message }}
441
+
${{ github.event.discussion.title }}
442
+
${{ github.event.discussion.body }}
443
+
${{ github.event.review.body }}
444
+
${{ github.head_ref }}
445
+
${{ github.event.pages[*].page_name }}
446
+
```
447
+
448
+
If any of these values are needed in a `run:` step, pass them through an environment variable:
449
+
450
+
```yaml
451
+
# ✅ Safe — shell variable, not template injection
452
+
env:
453
+
PR_TITLE: ${{ github.event.pull_request.title }}
454
+
run: echo "$PR_TITLE"
455
+
```
456
+
457
+
### workflow_run — treat artifacts as untrusted
458
+
459
+
- Workflows triggered by `workflow_run` MUST NOT trust artifacts from the triggering workflow blindly
460
+
- Validate/sanitize any data extracted from artifacts before use in shell commands or API calls
461
+
- Never extract and execute scripts from artifacts without verification
462
+
463
+
### Permissions — principle of least privilege
464
+
465
+
- ALWAYS declare explicit `permissions:` block at workflow level
466
+
- Default to `contents: read` — only escalate per-job when needed
467
+
- NEVER use `permissions: write-all` or leave permissions undeclared (defaults to broad access in public repos)
- NEVER use self-hosted runners for `pull_request` or `pull_request_target` from public repos — a fork can execute arbitrary code on the runner
504
+
- Self-hosted runners are only safe for `push`, `workflow_dispatch`, `schedule`, and other non-fork triggers
505
+
420
506
### Reserved names — never use as custom secret or input names
421
507
422
508
GitHub reserves the `GITHUB_*` prefix for all built-in variables and the `ACTIONS_*` prefix for runner internals. Declaring a custom secret or input with these names causes the job to fail silently or be ignored:
Copy file name to clipboardExpand all lines: .github/workflows/build.yml
+48-1Lines changed: 48 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -122,14 +122,24 @@ on:
122
122
description: 'Force multi-platform build (amd64+arm64) even for beta/rc tags'
123
123
type: boolean
124
124
default: false
125
+
docker_build_args:
126
+
description: 'Newline-separated Docker build arguments to pass to docker build (e.g., "APP_NAME=spi\nCOMPONENT_NAME=api"). Forwarded to docker/build-push-action build-args.'
127
+
type: string
128
+
required: false
129
+
default: ''
125
130
build_context_from_working_dir:
126
131
description: 'Use the component working_dir as Docker build context instead of build_context. Useful for independent modules (e.g., tools with their own go.mod).'
127
132
type: boolean
128
133
default: false
134
+
enable_cosign_sign:
135
+
description: 'Sign container images with cosign keyless (OIDC) signing after push. Requires id-token: write permission in the caller.'
0 commit comments