Hardcoded secrets in GitHub Actions increase security risk and surface area for breaches. This blog walks through how to replace them with Doppler’s doppler run command, enabling dynamic, secure secret injection at runtime. You'll improve auditability, reduce exposure, and streamline your CI/CD workflows.
GitHub Actions and popular CI/CD tooling like it have changed the way organizations' development workflows look and have greatly reduced time to market. But let's be honest: managing secrets within them can feel like handling a bomb that can go off at any minute. Hardcoding credentials directly into your workflows, forgetting the .gitignore, or simply pushing the wrong commit is easy to do. Human error will always come into play sooner or later; it's not a matter of if, but when.
The numbers do not lie; over 12.8 million secrets were leaked in GitHub repos in 2024. Reports like GitGuardians' 2024 annual State of secret sprawl confirm that this is a persistent headache among organizations of all sizes. Even some of the largest organizations in the world have had this problem at least once. CVE-2024-26052, where the Azure CLI commands would leak secrets within GitHub Actions Logs.
The numbers do not lie; over 12.8 million secrets were leaked in GitHub repos in 2024. Reports like GitGuardian's 2024 annual State of Secret Sprawl confirm that this is a persistent headache among organizations of all sizes. Even some of the largest organizations in the world have encountered this problem at least once. CVE-2024-26052, where the Azure CLI commands would leak secrets within GitHub Actions logs, exemplifies this issue.
Committing secrets, even to GitHub's encrypted storage, means those secrets are static and often long-lived within the environment workflow, increasing the attack surface of your application and its data. What if there were a way to fetch secrets using JIT (Just-In-Time), directly within your GitHub Actions runtime, without ever having to store them in your codebase or repo secret settings? This is where Doppler comes into play. This blog will walk you through setting up your GitHub Actions security by replacing static, plaintext secrets with Doppler's runtime-secure fetch capabilities. We will discard the risky practices and show you how to hydrate secrets securely and dynamically, exactly when your workflow needs them. Let's go.
Instead of fetching secrets during your workflow run, this method automatically pushes secrets from your chosen Doppler project and config directly into the native GitHub Actions Secrets storage for your repository or organization. Your workflow then accesses these secrets just like any other GitHub Action Secret.
Let's get into configuring the sync within your Doppler dashboard:
Log in to Doppler, go to your Project, and select "Syncs".
Click to add the GitHub Actions integration.
You'll be guided through authorizing Doppler to access your desired GitHub repositories (you can grant access to specific repos or all).
From here, you will be able to configure the GitHub integration. You have the option of choosing between GitHub features like Actions, Dependabot, and Codespaces, selecting which repository secret to target, as well as which Doppler configuration to target.
This will result in you having a synced integration between Doppler and your GitHub secrets within your repository settings.
Once the sync is active, accessing your secrets in your ./github/workflows/your-workflow.yml can be done using the ${{ secrets.SOME_KEY }} notation that is built into GitHub .yml syntax.
Notice how clean that is? No extra setup steps for Doppler CLI, no doppler run commands. The secrets managed in Doppler are securely available just like standard GitHub secrets because, thanks to the sync, they are standard GitHub secrets, benefiting from automatic masking and avoiding runtime API calls to Doppler.
For the majority of workflows needing access to secrets managed in Doppler, this direct sync integration offers the best balance of security, performance, and ease of use.
While syncing secrets directly to GitHub Actions is often the preferred route, there might be scenarios where it's not ideal (e.g., needing secrets from many different Doppler configs dynamically, or organization policies restricting direct integration). For these cases, Doppler provides a dedicated GitHub Marketplace Action: Fetch Doppler Secrets.
This action runs as a step within your workflow. It authenticates to Doppler using a Service Token (which you store in GitHub Secrets), fetches the required secrets from your specified Doppler project/config, and makes them available as outputs for subsequent steps in the same job. Crucially, it also automatically registers these fetched secrets for masking in GitHub Actions logs.
Advantages:
Disadvantages:
Let's walk through using the Fetch Secrets Action:
(Same as before) Make sure the secrets your workflow needs (e.g., APIKEY, DATABASEURL) are configured in the correct Project and Config within your Doppler dashboard.
(Same as before) This Action needs credentials to fetch secrets.
(Same as before) This is the only credential you store directly in GitHub for this method.
The Fetch Secrets Action provides a good middle ground when the direct Sync integration isn't feasible, offering automatic masking while still centralizing secret management in Doppler. However, always consider the potential impact of API calls during workflow runs compared to the Sync method.
You might encounter or want to consider using the Doppler CLI directly within your workflow via the doppler run command. This command injects secrets fetched from Doppler as environment variables specifically for a single command execution.
You install the Doppler CLI in a workflow step, then prefix the command that needs secrets with doppler run. Authentication typically uses a service token stored in GitHub Secrets.
While doppler run offers precise, just-in-time injection, it comes with significant caveats in the context of GitHub Actions:
Direct use of doppler run might be considered only if:
For most standard GitHub Actions workflows, prefer the Sync Integration (Method 1) for its robustness and automatic masking, or the Fetch Secrets Action (Method 2) as a reliable alternative that also handles masking. Only resort to direct doppler run (Method 3) if you have a compelling reason and are prepared to handle the manual masking requirements carefully.
By integrating Doppler's runtime secret fetching into your actions, you are reducing a massive risk to the SDLC (Software Development Life Cycle) of your application. It's time to stop leaving your keys under the doormat and elevate to the next generation of application security. If you are ready to start securing your workflows today, try Doppler for free and make sure to look at our official documentation.
Even encrypted secrets in GitHub can be exposed through logs or misuse. Static credentials increase the attack surface and are often long-lived.
Trusted by the world’s best DevOps and security teams. Doppler is the secrets manager developers love.