All guides

CI and deployment

GitHub Actions security for vibe-coded apps

Review workflow token permissions, pull_request_target, secret handling, third-party actions, and release jobs before an AI-generated workflow reaches production.

ScanMySaaS Editorial Team9 min readUpdated August 13, 2026

A GitHub Actions file is production code with credentials. It can publish a package, deploy an app, write to the repository, and read any secret explicitly provided to the job.

AI coding tools are good at producing a workflow that passes. They cannot decide how much authority that workflow should have without a clear security boundary from you.

Make token permissions explicit

Start read-only. Declare contents: read at workflow level, then grant a narrower write permission only to the release job that needs it. Avoid permissions: write-all. A test job does not need the same authority as a deployment job.

Treat pull request code as hostile input

The pull_request_target event runs in the context of the base repository. That makes it useful for trusted labeling or commenting, but dangerous when the job checks out and executes code from a fork. A contributor can change a build script, test command, or package hook and use the privileged job to reach secrets or a writable token.

Use pull_request for untrusted builds. If you need a privileged follow-up action, split it into a separate workflow that consumes a small, verified artifact and never executes pull request code.

Pin the software inside the workflow

A tag such as v4 can move. GitHub documents a full-length commit SHA as the immutable way to reference an action. Review the SHA in the action's repository, pin it, and leave the friendly version in a comment so automated dependency updates remain understandable.

  • Pin third-party actions to reviewed full commit SHAs.
  • Limit which actions and reusable workflows the repository may run.
  • Keep Dependabot or Renovate updates reviewable instead of auto-merging workflow changes.

Secrets can leave without appearing in a log

GitHub masks known secret values in normal logs, but masking is not a security boundary. A compromised command can send a secret over the network or transform it before printing. Pass secrets only to the step that needs them, avoid shell tracing, and do not hand deployment credentials to ordinary test jobs.

Primary source

Check your repository

See which of these issues are visible now.

ScanMySaaS reads a bounded set of security-relevant files from a public GitHub repository. It never runs repository code or reveals matched secret values.

Scan a public repository