Safeguard
Developer Tools•

How do you store a certificate or key file as a GitHub Actions secret?

Small files go in as base64 secrets. Over 48 KB, GitHub suggests encrypting the file and storing the passphrase. Masking caveats and safer choices.

Safeguard Security Team
4 min read

For a small binary file such as a signing certificate, base64 encode it, store the text as a secret, and decode it on the runner. For files over 48 KB, GitHub documents an encrypted file workaround with the passphrase stored as a secret. Base64 is encoding, not encryption, and the larger workaround loses log redaction.

The small file route

GitHub's secrets guide describes this for small binary blobs:

base64 -w 0 signing-cert.p12 > cert.b64   # copy the text into the secret

In the workflow, decode it into a temporary path with restricted permissions, use it, and delete it. The docs show the decode step with the base64 decode flag.

The guide includes a warning worth repeating: base64 only converts binary to text, and is not a substitute for actual encryption. The secret store provides the protection, not the encoding.

The over 48 KB route

Secrets larger than 48 KB need a workaround. The docs describe it: encrypt the file with gpg, commit the encrypted file to the repository, store the passphrase as a secret, and decrypt in a workflow step.

There is an important catch, stated plainly in the guide: when using this workaround, GitHub does not redact secrets that are printed in logs. The decrypted content is not a registered secret, so any accidental print is visible.

ApproachBest forRedactionMain risk
Base64 secretSmall certificates and keys under the limitApplies to the stored valueEncoded variants of the value may not match the mask
Encrypted file plus passphrase secretLarge filesNot applied to decrypted contentPrinted content shows in logs
Fetch from a secrets manager at run timeAnything sensitive or sharedDepends on how you handle itNeeds a trust setup and access policy

Masking and derived values

GitHub's guidance says redaction depends on exact matches. If you transform a secret, for example by base64 encoding it again, or building a signed token from it, register the derived value as a secret too. You can mask non-secret sensitive values with the add-mask command. Do not put several values in one JSON or YAML blob; create a separate secret for each value.

Steps to do it safely

  1. Ask whether the file must be in CI at all. A signing key might be better kept in a managed signing service or secrets manager and fetched with short lived credentials.
  2. If you store it, use an environment secret with required reviewers and a branch rule, not a repository wide secret.
  3. Decode to a temporary location, set tight file permissions, and delete after use.
  4. Never print the file or its decoded text. Check logs after the first run.
  5. Avoid passing the content on a command line. GitHub notes command line processes may be visible to other users; use environment variables or standard input instead.
  6. Rotate the certificate or key on a schedule and when anyone with write access leaves.

Alternatives worth a look

Cloud key management and secrets manager integrations let a job use a key without ever holding its bytes, for example by asking a service to sign. Where your toolchain supports it, that removes the file from the runner.

Quick check

Is a base64 secret safer than a plain one?

No. It is only a way to fit binary data into a text field. The safety comes from the secret store and the access rules around it.

What happens if a secret is not set?

An expression that references it returns an empty string, so a typo can fail quietly. Check that the decoded file exists before using it.

Safeguard policies and gates can review pull requests that add credential handling to workflows. A free scan is at gold.safeguard.sh/scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.