[{"data":1,"prerenderedAt":422},["ShallowReactive",2],{"blog-how-to/github-secrets":3},{"id":4,"title":5,"body":6,"category":403,"date":404,"dateModified":404,"description":405,"draft":406,"extension":407,"faq":408,"featured":406,"headerVariant":409,"image":408,"keywords":408,"meta":410,"navigation":411,"ogDescription":412,"ogTitle":408,"path":413,"readTime":408,"schemaOrg":414,"schemaType":415,"seo":416,"sitemap":417,"stem":418,"tags":419,"twitterCard":420,"__hash__":421},"blog/blog/how-to/github-secrets.md","How to Use GitHub Secrets for Actions",{"type":7,"value":8,"toc":385},"minimark",[9,13,18,22,33,38,94,98,122,163,187,191,195,201,205,211,215,221,225,228,246,252,256,298,311,315,321,347,366],[10,11],"category-badge",{"category":12},"How-To Guide",[14,15,17],"h1",{"id":16},"how-to-use-github-secrets","How to Use GitHub Secrets",[19,20,21],"p",{},"Secure your CI/CD workflows with encrypted secrets",[23,24,25],"tldr",{},[19,26,27,28,32],{},"TL;DR:\nGo to Repository Settings → Secrets and variables → Actions. Add secrets with descriptive names like\nSTRIPE_SECRET_KEY\n. Access them in workflows using\n$",[29,30],"binding",{"value":31},"secrets.SECRET_NAME","\n. GitHub automatically masks secret values in logs.",[34,35,37],"h2",{"id":36},"types-of-github-secrets","Types of GitHub Secrets",[39,40,41,57],"table",{},[42,43,44],"thead",{},[45,46,47,51,54],"tr",{},[48,49,50],"th",{},"Type",[48,52,53],{},"Scope",[48,55,56],{},"Best For",[58,59,60,72,83],"tbody",{},[45,61,62,66,69],{},[63,64,65],"td",{},"Repository secrets",[63,67,68],{},"Single repo",[63,70,71],{},"Project-specific keys",[45,73,74,77,80],{},[63,75,76],{},"Environment secrets",[63,78,79],{},"Specific environment",[63,81,82],{},"Production vs staging keys",[45,84,85,88,91],{},[63,86,87],{},"Organization secrets",[63,89,90],{},"Multiple repos",[63,92,93],{},"Shared API keys across projects",[34,95,97],{"id":96},"step-by-step-setup","Step-by-Step Setup",[99,100,102,107],"step",{"number":101},"1",[103,104,106],"h3",{"id":105},"open-repository-settings","Open repository settings",[19,108,109,110,114,115,114,118,121],{},"Go to your GitHub repository and click ",[111,112,113],"strong",{},"Settings"," → ",[111,116,117],{},"Secrets and variables",[111,119,120],{},"Actions",".",[99,123,125,129,136,157],{"number":124},"2",[103,126,128],{"id":127},"create-a-new-secret","Create a new secret",[19,130,131,132,135],{},"Click ",[111,133,134],{},"New repository secret"," and enter:",[137,138,139,151],"ul",{},[140,141,142,145,146,150],"li",{},[111,143,144],{},"Name:"," Use SCREAMING_SNAKE_CASE (e.g., ",[147,148,149],"code",{},"STRIPE_SECRET_KEY",")",[140,152,153,156],{},[111,154,155],{},"Value:"," The actual secret value",[19,158,131,159,162],{},[111,160,161],{},"Add secret"," to save.",[99,164,166,170,177],{"number":165},"3",[103,167,169],{"id":168},"use-secrets-in-your-workflow","Use secrets in your workflow",[19,171,172,173,176],{},"Reference secrets in your ",[147,174,175],{},".github/workflows/*.yml"," files:",[178,179,184],"pre",{"className":180,"code":182,"language":183},[181],"language-text","name: Deploy\n\non:\n  push:\n    branches: [main]\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Deploy to Vercel\n        env:\n          VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}\n        run: vercel --prod --token=$VERCEL_TOKEN\n\n      - name: Run tests with API key\n        env:\n          STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }}\n        run: npm test\n","text",[147,185,182],{"__ignoreMap":186},"",[34,188,190],{"id":189},"common-workflow-examples","Common Workflow Examples",[103,192,194],{"id":193},"deploy-to-vercel","Deploy to Vercel",[178,196,199],{"className":197,"code":198,"language":183},[181],"- name: Deploy\n  env:\n    VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}\n    VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}\n    VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}\n  run: |\n    npm i -g vercel\n    vercel pull --yes --token=$VERCEL_TOKEN\n    vercel build --prod --token=$VERCEL_TOKEN\n    vercel deploy --prebuilt --prod --token=$VERCEL_TOKEN\n",[147,200,198],{"__ignoreMap":186},[103,202,204],{"id":203},"push-to-docker-registry","Push to Docker Registry",[178,206,209],{"className":207,"code":208,"language":183},[181],"- name: Login to Docker Hub\n  uses: docker/login-action@v3\n  with:\n    username: ${{ secrets.DOCKER_USERNAME }}\n    password: ${{ secrets.DOCKER_PASSWORD }}\n\n- name: Build and push\n  uses: docker/build-push-action@v5\n  with:\n    push: true\n    tags: user/app:latest\n",[147,210,208],{"__ignoreMap":186},[103,212,214],{"id":213},"environment-specific-secrets","Environment-Specific Secrets",[178,216,219],{"className":217,"code":218,"language":183},[181],"jobs:\n  deploy-staging:\n    runs-on: ubuntu-latest\n    environment: staging\n    steps:\n      - name: Deploy\n        env:\n          # Uses staging-specific secret\n          API_KEY: ${{ secrets.API_KEY }}\n        run: ./deploy.sh\n\n  deploy-production:\n    runs-on: ubuntu-latest\n    environment: production\n    steps:\n      - name: Deploy\n        env:\n          # Uses production-specific secret\n          API_KEY: ${{ secrets.API_KEY }}\n        run: ./deploy.sh\n",[147,220,218],{"__ignoreMap":186},[34,222,224],{"id":223},"setting-up-environments","Setting Up Environments",[19,226,227],{},"For different secrets per environment (staging, production):",[229,230,231,234,237,240],"ol",{},[140,232,233],{},"Go to Settings → Environments",[140,235,236],{},"Create environments (e.g., \"staging\", \"production\")",[140,238,239],{},"Add secrets to each environment",[140,241,242,243],{},"Reference the environment in your workflow with ",[147,244,245],{},"environment: production",[247,248,249],"tip-box",{},[19,250,251],{},"Pro tip:\nAdd protection rules to production environments, like requiring manual approval before deploying.",[34,253,255],{"id":254},"security-best-practices","Security Best Practices",[137,257,258,270,276,282,292],{},[140,259,260,263,264,266,267],{},[111,261,262],{},"Use specific names:"," ",[147,265,149],{}," not ",[147,268,269],{},"API_KEY",[140,271,272,275],{},[111,273,274],{},"Limit scope:"," Use repository secrets unless you need org-wide access",[140,277,278,281],{},[111,279,280],{},"Rotate regularly:"," Update secrets periodically and after any exposure",[140,283,284,287,288,291],{},[111,285,286],{},"Never echo secrets:"," Don't use ",[147,289,290],{},"echo $SECRET"," in workflows",[140,293,294,297],{},[111,295,296],{},"Be careful with forks:"," Secrets aren't available in fork PRs by default",[299,300,301,304],"warning-box",{},[19,302,303],{},"Secrets and Pull Requests",[19,305,306,307,310],{},"For security, secrets are not passed to workflows triggered by pull requests from forks. This prevents malicious PRs from stealing your secrets. Use ",[147,308,309],{},"pull_request_target"," carefully if you need secrets in PR workflows.",[34,312,314],{"id":313},"using-github-cli","Using GitHub CLI",[178,316,319],{"className":317,"code":318,"language":183},[181],"# Set a secret\ngh secret set STRIPE_SECRET_KEY\n\n# Set from a file\ngh secret set GOOGLE_CREDENTIALS \u003C credentials.json\n\n# List secrets (names only, not values)\ngh secret list\n\n# Delete a secret\ngh secret delete OLD_SECRET\n\n# Set an environment secret\ngh secret set API_KEY --env production\n",[147,320,318],{"__ignoreMap":186},[322,323,324,331,341],"faq-section",{},[325,326,328],"faq-item",{"question":327},"Can I see the value of a secret after saving?",[19,329,330],{},"No, GitHub encrypts secrets and never displays them again. If you need to verify or change a secret, you must update it with the new value. There's no way to retrieve the original.",[325,332,334],{"question":333},"Are secrets visible in workflow logs?",[19,335,336,337,340],{},"GitHub automatically masks secret values in logs, replacing them with ",[147,338,339],{},"***",". However, if your code transforms the secret (base64 encode, split, etc.), the transformed value might not be masked.",[325,342,344],{"question":343},"What's the difference between secrets and variables?",[19,345,346],{},"Secrets are encrypted and hidden, used for sensitive data like API keys. Variables are plain text and visible, used for non-sensitive configuration like feature flags or environment names.",[19,348,349,352,357,358,357,362],{},[111,350,351],{},"Related guides:",[353,354,356],"a",{"href":355},"/blog/how-to/hide-api-keys","How to Hide API Keys"," ·\n",[353,359,361],{"href":360},"/blog/how-to/secret-scanning","How to Enable Secret Scanning",[353,363,365],{"href":364},"/blog/how-to/environment-variables","Environment Variables Guide",[367,368,369,375,380],"related-articles",{},[370,371],"related-card",{"description":372,"href":373,"title":374},"Clean secrets from your git history after accidental commits. Learn to use BFG Repo Cleaner and git filter-branch to rem","/blog/how-to/remove-secrets-git-history","How to Remove Secrets from Git History",[370,376],{"description":377,"href":378,"title":379},"Emergency guide for rotating compromised API keys without downtime. Step-by-step instructions for Stripe, OpenAI, Supaba","/blog/how-to/rotate-api-keys","How to Rotate API Keys - Emergency Response Guide",[370,381],{"description":382,"href":383,"title":384},"Step-by-step guide to sanitizing user input. HTML sanitization, XSS prevention with DOMPurify, server-side sanitization,","/blog/how-to/sanitize-input","How to Sanitize User Input",{"title":186,"searchDepth":386,"depth":386,"links":387},2,[388,389,395,400,401,402],{"id":36,"depth":386,"text":37},{"id":96,"depth":386,"text":97,"children":390},[391,393,394],{"id":105,"depth":392,"text":106},3,{"id":127,"depth":392,"text":128},{"id":168,"depth":392,"text":169},{"id":189,"depth":386,"text":190,"children":396},[397,398,399],{"id":193,"depth":392,"text":194},{"id":203,"depth":392,"text":204},{"id":213,"depth":392,"text":214},{"id":223,"depth":386,"text":224},{"id":254,"depth":386,"text":255},{"id":313,"depth":386,"text":314},"how-to","2026-01-15","Complete guide to GitHub Secrets for GitHub Actions. Store API keys, access tokens, and sensitive data securely in your CI/CD workflows.",false,"md",null,"yellow",{},true,"Store API keys and tokens securely in GitHub Actions workflows.","/blog/how-to/github-secrets","[object Object]","HowTo",{"title":5,"description":405},{"loc":413},"blog/how-to/github-secrets",[],"summary_large_image","F_DXcbbyIj8XD21uZPmIaONrswWf4P0m9IYG62ZfNr8",1775843928285]