By Productivities Team • Riyadh, Saudi Arabia
How to Paste a Service Account JSON Key into a GitHub Actions Secret (Without Breaking It)
If you've ever wired up a Google Indexing API job, a Firebase Admin SDK action, or any GitHub workflow that needs a Google Cloud service account, you've probably hit this wall: you save the JSON key as a repository secret, the workflow runs, and it instantly fails with something like SyntaxError: Unexpected token in JSON at position 162.
Nine times out of ten, the JSON itself is fine. The problem is invisible line breaks that survived inside the secret value.
Why GitHub Secrets Hate Multi-Line JSON
A service account key looks like this when you download it from Google Cloud:
{
"type": "service_account",
"project_id": "my-project",
"private_key_id": "abc123…",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIB…\n-----END PRIVATE KEY-----\n",
"client_email": "[email protected]",
…
}
Notice the \n sequences inside private_key — those are escaped newlines, just two characters. They are perfectly valid inside a JSON string. But the file also contains real, physical newlines between every key/value pair (the pretty-printed indentation). Those real newlines are what GitHub stores as line breaks in the secret value.
When your workflow code does JSON.parse(process.env.MY_SECRET), the JSON parser sees the structural newlines and rejects them. JSON allows whitespace between tokens, so technically multi-line JSON should parse — but in practice, most CI environments mangle multi-line secrets in subtle ways: trailing whitespace gets stripped, the last newline is dropped, or the value gets re-quoted by a shell.
The Fix: Compact It to a Single Line First
The bullet-proof solution is to flatten the JSON to one line before pasting it into the secret. Compact JSON has zero structural whitespace, so there's nothing for the secret store, the shell, or the runner to corrupt.
You can do this in a terminal:
jq -c . service-account.json | pbcopy # macOS
node -e "console.log(JSON.stringify(require('./service-account.json')))" | xclip # Linux
But you have to install jq, you have to remember the exact command, and on a borrowed machine you may not be allowed to run any of that.
The One-Click Way (No Terminal, No Upload)
Open our JSON Formatter, paste the contents of your service account file, and click Compact (1 line). The output will be a single line where every embedded newline inside private_key stays correctly escaped as \n. Copy it, paste it into your GitHub secret, and your workflow will parse it on the first try.
Why this is safe:
- 100% in-browser. The JSON never leaves your device — no server, no analytics on the payload, no logs. The whole tool is a static React page processing the string locally.
- Validated, not just stripped. Compact mode parses your JSON first. If the file is corrupt or has trailing commas, you'll get a clear error before you ever copy anything.
- Escaping is preserved. Real newlines inside string values (like the PEM block in
private_key) are kept as\nescapes, exactly asJSON.parseexpects them on the other side.
Step-by-Step
- Download the JSON key from Google Cloud Console → IAM & Admin → Service Accounts → Keys.
- Open the file in any text editor and copy its entire contents.
- Go to the JSON Formatter and paste it into the input.
- Click Compact (1 line). You'll see a green confirmation toast.
- Click the copy button.
- In GitHub: Settings → Secrets and variables → Actions → New repository secret. Name it (e.g.
INDEXING_SERVICE_ACCOUNT) and paste the single-line value. - Re-run the workflow. It should now parse cleanly.
Where Else This Helps
The same single-line trick is required (or strongly recommended) for:
- GitLab CI/CD variables, Bitbucket Pipelines, CircleCI contexts
- .env files read by Node.js, Python, Deno — most parsers refuse multi-line values
- Cloudflare Workers, Vercel, Netlify, AWS Lambda, Google Cloud Run environment variable panels
- Docker
--envflags and most Kubernetes secret manifests
Common Pitfalls After You Paste
- Don't wrap the value in quotes. GitHub stores it as-is. Adding outer
"…"makes the parser see a JSON-encoded JSON string and you'll need toJSON.parsetwice. - Don't trim the trailing
}. Sometimes a copy-paste loses the final character. If parsing fails, log the last 10 characters of the secret in CI to confirm it ends with}. - Rotate the key after debugging. If you ever pasted the key into a chat, a screenshot, or a public terminal during debugging, treat it as compromised and create a new one.
Ready to flatten your key? Open the JSON Formatter and click Compact (1 line) — it takes about three seconds and saves a lot of broken builds.
Share this article
Try the tool mentioned in this article
JSON Formatter