GitHub can now scan your workflow logs for secrets
GitHub Actions logs can expose deployment credentials, and the new scanner adds a useful safety net with clear limits.
The leak is not always in the repository
A secret does not need to be committed to Git before it becomes an incident. A deployment command, a Laravel stack trace, or an infrastructure tool can print an environment variable straight into a workflow log. This is easy to do while debugging php artisan, Composer, SSH, Docker, or a cloud integration.
GitHub can now scan GitHub Actions workflow logs for exposed secrets. Scanning happens after a new workflow run finishes, and findings are added to the repository’s Secret Scanning alerts. Each alert can point to the workflow file and to the specific log line where the value was printed. (docs.github.com)
That matters for people running self-hosted runners in a homelab. The important control point is the workflow log held by GitHub Actions, rather than the operating system hosting the runner. A Laravel pipeline can run on your own hardware and still create a security alert if its logs are sent to GitHub.
This is an enterprise policy, not a repository toggle
This feature is disabled by default. An enterprise owner has to open Policies, go to Advanced Security, and enable Secret scanning for Actions workflow logs from the All repositories dropdown. Secret Scanning must also be enabled in each repository that should be covered. (docs.github.com)
For private and internal repositories, Secret Scanning is available through GitHub Secret Protection. Before enabling log scanning, I would check which repositories already have that protection enabled and who is allowed to change it. Otherwise, it is too easy to assume the whole estate is covered when it is not.
Stopping the value from reaching the log is still the first line of defense
Detection after the fact is useful, but it does not replace careful workflow design. GitHub Actions provides the add-mask workflow command to redact a value from logs, and it must be registered before the value can be printed. It is useful when a deployment script creates a short-lived credential during a run. (docs.github.com)
- name: Prepare temporary credential
shell: bash
run: |
DEPLOY_TOKEN="$(./scripts/create-deploy-token)"
echo "::add-mask::$DEPLOY_TOKEN"
./scripts/deploy.sh "$DEPLOY_TOKEN"I would not use this as a way to pass secrets between jobs. Masking applies per job, and a masked value cannot be used as an output. When separate jobs need a temporary credential, fetch it from a proper secret store in the job that needs it.
The important limitations
During the public preview, workflow-log scanning only detects provider patterns. It does not cover generic patterns, custom patterns, AI-detected secrets, or values that GitHub Actions has already masked. An internal password, a custom connection string, or a home-grown token format may therefore remain undetected. (docs.github.com)
There is no backfill for older workflow runs either: only runs completed after enablement are scanned. Alerts generated from logs also do not send notifications during the preview, so somebody needs to review the repository’s Secret Scanning alerts directly. This is not real-time monitoring, and it is definitely not a reason to print environment variables while debugging. (docs.github.com)
Incident handling needs to change
When an alert appears, deleting the log or rerunning the job is not the first fix. Treat the credential as exposed, rotate or revoke it immediately, then find the command that printed it and fix the workflow. GitHub’s guidance for Secret Scanning alerts also prioritizes rotating the affected credential. (docs.github.com)
For Laravel projects, I would review deployment commands, .env generation, database access, Forge-style service tokens, SSH keys, and container registry credentials first. The operational rule is straightforward: if a value can authenticate, it should never be part of output intended for people to read.
Source: GitHub Changelog
Official documentation: Secret scanning