How to Set Up Deployment Keys
How to Set Up Deployment Keys
Introduction: Why Deployment Keys Matter
Deployment keys are a cornerstone of secure, automated code deployment. When you need a machine — a CI runner, a staging server, or a deployment agent — to pull code from a repository without human interaction, deployment keys provide a secure, auditable, and scalable solution. Unlike username/password or long-lived personal tokens, SSH public/private key pairs let you grant access to a single repository or service account with limited scope, reducing blast radius if credentials are compromised. In this guide you’ll learn how deployment keys work, how to generate and manage them securely, how to add them to popular Git hosts, and how to automate and audit their use across CI/CD pipelines. Practical examples, security trade-offs, and troubleshooting tips are included so you can adopt best practices in production.
How Deployment Keys Work Under the Hood
At the core, a deployment key is an SSH key pair: a private key stored securely on the client (server or CI runner) and a public key registered with the Git host. When the client connects, the SSH protocol uses public key cryptography to authenticate without transmitting secrets. The host verifies the signature created by the private key against the registered public key and grants access if they match.
Technically, SSH uses asymmetric algorithms such as RSA, ECDSA, or Ed25519. Ed25519 is increasingly recommended for its performance and security properties. Keys have metadata (comment, key type) and can be configured with options on the server side, like forced commands, from=host restrictions, and no-pty/no-agent-forwarding to limit their capabilities.
A few important concepts:
- Private key: Never shared. Protect with strict filesystem permissions and optional passphrases.
- Public key: Safe to publish; uploaded to the repository or account.
- Authorized keys: Where Git hosts store public keys associated with access control.
- Key scope: Per-repo vs. account-level keys. Per-repo keys minimize exposure.
Because SSH sessions can be logged and keys can be tied to specific repositories, deployment keys help create an auditable access model. When designing access, prefer single-repo deployment keys for least privilege unless multiple repositories share identical deployment lifecycle requirements.
Generating and Managing SSH Keys Securely
Generating keys correctly and protecting private material is essential. Use modern algorithms and follow hardened practices:
-
Choose the right algorithm:
- Prefer Ed25519 for new keys:
ssh-keygen -t ed25519 -C "deploy@prod" - If compatibility requires RSA, use RSA 4096:
ssh-keygen -t rsa -b 4096 -C "deploy@prod"
- Prefer Ed25519 for new keys:
-
Use descriptive comments and naming:
- Store keys with names like
/etc/ssh/deploy-repoA_ed25519so you can tell keys apart. - Add key comments such as
"deploy-key: repo-A staging".
- Store keys with names like
-
Protect private keys:
- Restrict file permissions:
chmod 600 /path/to/private_key - Consider passphrases when an automated agent supports unlocking (e.g., an SSH agent with secure key storage), but carefully weigh automation vs. manual entry.
- Use hardware-backed stores or HSMs (e.g., YubiKey, cloud KMS) for high-value deployments.
- Restrict file permissions:
-
Centralize secrets management:
- Integrate keys into a secrets manager (e.g., HashiCorp Vault, cloud KMS) when possible and reference them at runtime rather than embedding plain keys on disk.
- For containers and ephemeral runners, inject keys at build/start time with short-lived credentials.
-
Limit key scope:
- Generate a unique key per service/repo/runner whenever feasible to enable targeted revocation.
- Avoid using the same private key across multiple environments.
-
Document key lifecycle:
- Log creation date, owner, intended use, and rotation schedule in an asset register.
Operational tips: rotate keys on a regular cadence (see later section), disable older keys before removing them, and monitor for orphaned keys on the Git host. For managing many keys and servers, consult Server Management resources for processes and tooling that streamline lifecycle management.
Adding Deployment Keys to Popular Git Hosts
Most Git hosting platforms provide a way to add SSH deployment keys to a repository or project. The exact steps differ but the principle is the same: upload the public key and optionally name it and restrict its privileges.
- GitHub: Add the public key under repository Settings → Deploy keys. You can check Allow write access if necessary (use sparingly). GitHub also supports deploy keys at the repository level so each repo can have dedicated keys.
- GitLab: Add keys under Project → Settings → Repository → Deploy Keys. GitLab supports enabling a key across multiple projects if you need cross-repo access.
- Bitbucket: Use Repository settings → Access keys to add public keys.
When adding a key:
- Use a clear name to identify the machine or pipeline.
- Prefer read-only by default (uncheck or omit write permissions).
- If the platform supports IP restrictions or metadata, add them to reduce misuse.
Example best practices:
- Create a dedicated service account with an associated deploy key for production deployments only when CI needs push capability (tags, releases). For read-only clone operations, avoid giving write access.
- Keep an inventory of which keys map to which runner or server. If you use a fleet of ephemeral runners, automate key provisioning rather than manually registering many key pairs.
For repository and automation workflows, tie key usage patterns into your CI/CD processes. If you need guidance on integrating these practices into continuous delivery pipelines, review Deployment best practices for workflow examples and templates.
Using Read-Only Versus Read-Write Keys
Choosing between read-only and read-write deployment keys is a key security decision:
- Read-only keys: Recommended default for build agents and servers that only need to clone or fetch repositories. They limit blast radius — even if the key is compromised, an attacker cannot push code back to the repository.
- Read-write keys: Required only when the automation must perform pushes, create tags, or write artifacts back to the repo. Examples: release automation that tags commits, auto-merge bots, or when performing remote repository maintenance.
Advantages and disadvantages:
- Read-only: + Lower risk, + Easier compliance, − Cannot perform release tasks.
- Read-write: + Flexible, supports advanced automation, − Higher risk if leaked.
Mitigations for write-capable keys:
- Restrict which branches can be updated via branch protection rules.
- Use forced commands or Git host features to limit what the key can do where supported.
- Implement approval gates in CI for any action that pushes changes.
Tip: Separate duties by creating multiple keys with clearly defined responsibilities — one read-only key for building, another read-write key strictly for release tasks, each with short, auditable lifespans. This approach aligns with the principle of least privilege and helps satisfy compliance controls outlined by authorities such as the SEC when discussing operational security policies for regulated entities (SEC).
Automating Key Deployment in CI/CD
Automation is where deployment keys shine — but it must be done securely.
Patterns for automation:
- Ephemeral keys: Generate keys dynamically for each pipeline run, register the public key programmatically with the Git host (valid for a short time), use the key, then revoke it. This reduces the window of exposure.
- Secrets injection: Store the private key in a secure CI secret store (encrypted environment variables or secret files). The runner writes the key to disk with strict permissions at job start and removes it at job end.
- SSH agent forwarding: For some systems, forwarding a private key from a secure host to an ephemeral runner via an SSH agent avoids storing the private key on the runner.
Implementation steps:
- Place the private key in your CI secret environment (encrypted variable or secret store).
- In the pipeline job, write the private key to a file, set
chmod 600, and startssh-agentto load it. - Add host verification: populate
~/.ssh/known_hostswith the Git host fingerprint to avoid MITM risks (usessh-keyscanor pinned fingerprints). - Use per-job teardown to securely delete keys and clear agent cache.
Example GitHub Actions pattern:
- Store private key in Secrets.
- Use an action/step to add the key to
ssh-agentand configureknown_hosts. - Clone using SSH remote URL.
For orchestration at scale, consider integrating with centralized secret stores (Vault, AWS Secrets Manager) and pipeline libraries that encapsulate secure key handling. For monitoring and observability of automated deployments, see DevOps monitoring strategies to instrument and alert on suspicious key usage.
Evaluating Security Risks and Mitigations
Deployment keys reduce some risks but introduce others. Primary threats include key leakage, compromised runners, and misconfigured access.
Key risks and mitigations:
- Key leakage (private key exposure): Mitigate via hardware-backed keys, strong filesystem permissions, passphrases when practical, and storing keys only in trusted secret managers.
- Compromised runner or CI: Use ephemeral keys, isolate build environments (container sandboxes), and enforce least privilege. Monitor builds for anomalous network activity.
- Over-permissive keys: Avoid account-level or global keys. Use per-repo keys and narrow scopes to reduce impact.
- Reuse of keys across environments: Never reuse the same private key for multiple repositories or environments. Unique keys make forensic analysis and rotation simpler.
- Insufficient audit trails: Ensure Git host logs and CI logs capture which key or service performed actions. Enable repository-level audit logs where available.
Technical mitigations:
- Enforce branch protection and signed commits for critical branches to detect unauthorized pushes even when a key has write access.
- Pin host keys in
known_hoststo prevent man-in-the-middle attacks. - Use SSH certificate authorities (CAs) where possible to issue short-lived SSH certs to machines instead of static keys; SSH certificate workflows scale better in large fleets.
When assessing risk, quantify potential impact: which repositories contain sensitive secrets or production code? Prioritize hardened controls and rotation where risk is highest — see the next section for lifecycle practices.
Auditing and Rotating Deployment Keys Regularly
Good key hygiene requires logging, auditing, and rotation. Create a formal lifecycle policy:
Inventory and audit:
- Maintain a keyed register of all active deployment keys with metadata: owner, creation date, purpose, associated host/runner, and last rotation.
- Use Git host APIs to list keys programmatically and reconcile with your inventory.
- Enable and review audit logs on the Git host to track key usage and suspicious patterns.
Rotation policies:
- Rotate keys at least every 90 days for high-sensitivity systems; for lower-risk systems, 180 days may be acceptable. Tailor intervals to risk appetite.
- For shared or write-capable keys, consider shorter rotation windows and automatic renewal.
- Implement a rolling rotation: add a new key, verify functionality, then remove the old key to avoid downtime.
Revocation and incident response:
- Revoke compromised keys immediately via the Git host UI or API.
- Replace the key on the client and update secrets in CI.
- Conduct a post-incident review to identify root cause and remediation.
Automation aids:
- Use scripts or orchestration tools to automate key rotation and verification across environments.
- Integrate rotation with secrets management systems for zero-downtime swaps.
Audit example: A scheduled job that queries the Git host API for deploy keys, cross-references your inventory, and raises alerts for orphaned or expired keys. For monitoring practices and alerting strategies around key usage and CI activity, refer to DevOps monitoring strategies.
Troubleshooting Common Deployment Key Problems
When deployment fails due to SSH key issues, these are the typical problems and fixes:
-
Permission denied (publickey)
- Verify the private key is readable by the process and has 600 permissions.
- Ensure the public key is correctly added to the repository/project and not mismatched.
- Check
ssh -vvv git@github.comoutput to see which key is offered.
-
Host key verification failed
- Populate
~/.ssh/known_hostswith the correct host fingerprint usingssh-keyscanor manual pinning. - Avoid disabling strict host key checking in production; instead, pin the expected fingerprint.
- Populate
-
Wrong user/remote URL
- Confirm the remote uses the SSH URL (
git@github.com:org/repo.git) rather than HTTPS. - For GitLab, ensure you’re addressing the correct domain and project.
- Confirm the remote uses the SSH URL (
-
Key not accepted by Git host
- Confirm the key type is supported (some hosts may reject very old or tiny RSA keys).
- Ensure no duplicate public keys exist in conflicting contexts (e.g., account-level key vs. deploy key).
-
Time-limited or ephemeral keys expired
- If you use temporary keys, ensure the pipeline registers public key and revokes it at teardown; check timing windows.
-
CI runner lacks SSH agent
- Load the private key into
ssh-agentor configure the SSH client withIdentityFilein~/.ssh/config.
- Load the private key into
Common diagnostic steps:
- Increase SSH verbosity:
GIT_SSH_COMMAND="ssh -vvv" git clone ... - Validate public key fingerprint locally:
ssh-keygen -lf /path/to/public_key - Check repository access logs (if available) for authentication errors.
Comparing Alternatives: Tokens, Apps, and Keys
Deployment keys are one of several options to authenticate automation to Git hosts. Compare alternatives:
-
SSH Deployment Keys
- Pros: Strong cryptographic authentication, easy per-repo scoping, fits existing SSH workflows.
- Cons: Key management overhead, potential for leakage if not handled correctly.
-
Personal Access Tokens (PATs)
- Pros: Fine-grained scopes (on some platforms), easy to use with HTTPS, supports API access.
- Cons: Often paired to a user account (higher privilege), can be accidentally used interactively; harder to limit to a single repo on some platforms.
-
OAuth Apps / OAuth2 Tokens
- Pros: Centralized app permissions, revocable, can offer granular scopes depending on provider.
- Cons: More complex to set up, may require web callbacks and user consent flows.
-
Machine/User Accounts (service accounts)
- Pros: Centralized identity, easier to audit if properly configured.
- Cons: If a service account has broad access, compromise is severe.
-
SSH Certificates (via CA)
- Pros: Issue short-lived certs, highly scalable, no need for long-lived static keys.
- Cons: More complex infrastructure: need a CA and signing workflow.
Recommendation: For simple cloning and automated builds, prefer per-repo SSH deployment keys or short-lived tokens depending on platform features. For large organizations with many hosts and dynamic instances, move toward SSH certificate authorities or centralized service accounts with strict controls. When comparing options, weigh operational complexity, auditability, and blast radius.
For a deeper look at how deployment patterns fit into broader deployment and server practices, consult our resources on Deployment best practices and Server Management resources.
Conclusion
Deployment keys are a pragmatic, secure way to grant machine-level access to repositories without relying on human credentials. When designed correctly — unique keys per service, minimal privileges (prefer read-only), ephemeral where possible, protected in secret stores, and rotated regularly — they reduce risk and enable robust automation. Pair deployment keys with logging, branch protections, and CI controls to create a defense-in-depth strategy. For teams operating at scale, consider advanced approaches like SSH certificate authorities, hardware-backed keys, and centralized secrets management. Remember that key management is an ongoing process: inventory, audit, and rotation are not optional if you want to maintain a secure deployment posture. For implementation patterns, CI integrations, and monitoring guidance, our articles on DevOps monitoring strategies provide practical next steps.
By following the technical recommendations in this guide, you’ll be able to set up, manage, and audit deployment keys in a way that balances automation needs with security best practices — improving reliability and reducing incident impact.
FAQ: Common Questions About Deployment Keys
Q1: What is a deployment key?
A deployment key is an SSH public/private key pair used to grant machine-to-repository access for automated systems. The private key stays on the client (CI runner or server) and the public key is registered with the Git host to authenticate without passwords. Deployment keys are commonly scoped per-repository to enforce least privilege.
Q2: How do deployment keys differ from personal access tokens?
Deployment keys use public-key cryptography (SSH) and are typically tied to a single repository or host. Personal access tokens (PATs) use token-based authentication, often with user-associated scopes and API access. PATs can be more granular on some platforms but may carry higher privilege if linked to a human account. Choose keys for SSH workflows and PATs for API-heavy automation where HTTPS is preferred.
Q3: How should I store and rotate deployment keys?
Store private keys in a secure secrets manager or use hardware-backed solutions (HSMs, YubiKey) for high-value assets. Enforce strict permissions (chmod 600) and inject keys at runtime into ephemeral runners. Rotate routinely — for sensitive systems consider every 90 days — and automate rotation workflows where possible. Keep a centralized inventory of key metadata for audits.
Q4: Are read-only deployment keys safe for production builds?
Yes. Read-only deployment keys are safer for build and test pipelines because they prevent pushes back to the repository. For production builds that only need to clone artifacts, prefer read-only keys to minimize risk. Use write-capable keys only when necessary and enforce branch protection and approvals.
Q5: What should I do if a deployment key is compromised?
Immediately remove or revoke the public key from the Git host, rotate the private key, and invalidate any sessions or tokens associated with the runner. Conduct an incident response to determine the breach vector, re-evaluate permissions, and consider introducing stronger controls (ephemeral keys, HSMs, or SSH certificates). Notify stakeholders per your security policy and document remediation steps.
Q6: Can deployment keys be used for multiple repositories?
Some platforms allow a single key to be shared across multiple repositories, but this increases exposure. Prefer unique keys per repository to ensure targeted revocation and minimal blast radius. If many repos require identical access, consider a service account or SSH certificate approach with stricter governance.
Q7: What regulations or compliance concerns apply to deployment keys?
While deployment keys themselves aren’t typically regulated, their misuse can lead to data breaches that trigger regulatory reporting. Organizations in regulated industries should align key management with control frameworks and consider referencing guidance from regulators like the SEC for operational risk practices. For definitions and deeper regulatory context, consult authoritative sources such as SEC and educational resources like Investopedia.
External references and further reading:
- For high-level definitions of SSH and public-key authentication, see Investopedia.
- For contemporary security reporting and incident examples that underscore the importance of key hygiene, check TechCrunch.
- Official regulatory guidance and organizational risk considerations are available from SEC.
If you want, I can provide step-by-step command examples for GitHub, GitLab, or Bitbucket tailored to your CI system (GitHub Actions, GitLab CI, Jenkins, etc.) — tell me which platform you use and I’ll generate a runnable playbook.
About Jack Williams
Jack Williams is a WordPress and server management specialist at Moss.sh, where he helps developers automate their WordPress deployments and streamline server administration for crypto platforms and traditional web projects. With a focus on practical DevOps solutions, he writes guides on zero-downtime deployments, security automation, WordPress performance optimization, and cryptocurrency platform reviews for freelancers, agencies, and startups in the blockchain and fintech space.
Leave a Reply