Skip to main content
Least-Privilege Deployment Keys on VPS - Virtarix Blog

Least-Privilege Deployment Keys on VPS

June 5, 2026 · Blog / Technical Guides

The safest deployment key is not simply a strong key. It is a credential attached to one automation identity, accepted by one intended system, and authorised to perform only the deployment steps that system actually needs.

A useful design therefore starts with the task rather than the credential format. Map what the pipeline must read, write, and execute; separate source access from server access; record who owns every identity; and prove that a revoked key and an out-of-scope action both fail. This guide provides that operating model for a self-managed VPS.

Start with the deployment task

Describe one deployment from trigger to verification before creating a credential. Name the automation system, repository, environment, destination host, destination path, service, and health check. Then list every required action and mark everything else as unnecessary.

For example, a release pipeline might need to:

  1. Read one repository or download one built artefact.
  2. Connect to one deployment account on one host.
  3. Write a new version beneath one application release directory.
  4. Run a reviewed deployment wrapper that performs a fixed set of file and service actions.
  5. Switch the application to the new release.
  6. Read the resulting status and health-check output.

That task does not automatically require permission to administer the source-control organisation, delete branches, change repository settings, open an unrestricted root shell, read another application's secrets, modify every service, or access production data directly. Treat each additional permission as a separate requirement that needs an owner and reason.

Do not use the word “deploy” as a permission boundary. Translate it into concrete objects and actions: read repository A; write beneath release path B; execute wrapper C; restart service D; read log or health result E. If the pipeline also runs migrations, uploads assets, clears a cache, or updates a worker, record those as distinct steps with their own failure and rollback behavior.

Prefer narrow credentials

Create a separate non-personal identity for each automation system and security boundary. A production pipeline and a staging pipeline should not share a key merely because they deploy the same application. Two independent automation platforms should not present the same credential. A routine deployment must never reuse a root key or an operator's personal key.

This separation answers three questions during an incident: which system authenticated, which scope should be disabled, and which unaffected workflows can continue. A label such as deploy-production-web is more useful than an anonymous key copied between several jobs, provided the same stable identity appears in the inventory and authentication logs.

Keep the private key or token in the automation platform's protected secret store, not in the repository, build artefact, container image, command output, or shared chat. Install or register only the corresponding public credential at the destination where public-key authentication is used. Limit who can read or replace the stored secret, and prevent untrusted pull requests or forked jobs from receiving production credentials.

Do not make routine deployment depend on a shared human account. Operators need attributable personal access for investigation and approval; automation needs a distinct service identity for repeatable execution. Removing a person's access should not break the pipeline, and rotating the pipeline credential should not remove an operator's recovery path.

Separate read and write access

Use read-only source or dependency credentials when the pipeline only fetches code, packages, or images. Source-control administration, release publishing, package deletion, secret management, and production deployment are different capabilities. Do not place all of them behind one token because one workflow happens to touch each system.

Separate the permissions into layers:

  • Source and dependency access: read the named repository, package, or image; do not grant organisation administration or unrelated repository access.
  • Build or release publication: write only to the intended artefact or package destination when this pipeline owns publication.
  • Host authentication: connect as the named deployment identity on the intended host and environment.
  • Host deployment: write only to the application-owned release paths and perform the reviewed service actions required by the deployment.
  • Runtime access: keep application database, API, and service credentials separate from the credential that transports a release to the host.

Avoid solving host permissions by allowing an unrestricted privileged shell. Where a deployment step genuinely needs elevation, expose the smallest reviewed operation that performs that step and keep its configuration under change control. The deployment identity should not be able to edit the rule or replace the privileged helper it invokes.

OpenSSH authorized_keys options can narrow how a public key enters a host, but their available syntax and behavior depend on the OpenSSH version and surrounding server configuration. Do not copy an option string from an unrelated server. Check the documentation for the exact installed version, test the effective SSH configuration, and test both permitted and denied paths. These entry restrictions also do not reduce privileges inside an allowed command or repair unsafe ownership, writable scripts, broad sudo rules, or credentials that the deployed process can read.

Keep a key and identity inventory

Use two linked views of the same inventory so the fields remain readable on narrow screens. The identity view records purpose and authority; the lifecycle view records custody and removal. Use the same stable key or identity label in both.

Key/identity Purpose Scope Owner
deploy-production-web Publish the web application release Production web repository; web host; application release path; named service action Platform owner
deploy-staging-web Publish and verify a staging release Staging repository and staging host only Application owner
break-glass-production Recover access when routine paths are unavailable Documented emergency administration path Security owner
Swipe to view the full table
Key/identity Stored in Created Last verified Revocation method
deploy-production-web Production CI secret store Record actual date Record latest positive and negative test Remove destination authorisation, disable source token, then run the revoked-key test
deploy-staging-web Staging CI secret store Record actual date Record latest positive and negative test Remove staging authorisation and disable the staging token
break-glass-production Separate emergency credential store Record actual date Record latest controlled exercise Replace emergency credential and invalidate every prior copy
Swipe to view the full table

Replace the example values with actual identities, repositories, hosts, paths, owners, dates, and system-specific revocation steps. “Delete the key” is not a sufficient method when copies may exist in both a CI platform and one or more destination systems. Name each place that must reject the old credential.

Inventory API tokens, repository deploy keys, SSH public keys, signing identities, package credentials, and cloud or control-plane credentials separately. One row should represent one revocable identity, not a vague collection such as “all production keys.”

Rotate and remove old keys

Rotation is complete only when the replacement works and the previous credential has been proved unusable. Use a staged procedure:

  1. Confirm the credential's owner, complete scope, storage location, and current consumers from logs and configuration.
  2. Create a new credential for the same narrow identity or a replacement identity with the approved scope.
  3. Add the new public credential or token to the exact destinations that require it.
  4. Run a controlled deployment or non-destructive authentication test with the new credential.
  5. Observe the expected identity, paths, service actions, and health result in logs.
  6. Remove or disable the old credential at every destination and secret store.
  7. Attempt the same bounded authentication with the old credential and record the expected denial.
  8. Confirm the next normal deployment uses the new identity, then update the inventory date and evidence link.

Do not leave the old key active “just in case.” If rollback requires a credential, define and protect that credential as part of the rollback procedure rather than retaining an undocumented duplicate. Trigger an immediate rotation when a private key or token may have been exposed, an automation platform changes, a scope was broader than intended, the owner leaves or changes role, a destination is retired, or logs show unexplained use.

A calendar can provide a review prompt, but a fixed interval alone does not prove safety. Review whether the credential is still used, whether its scope still matches the task, whether its owner is current, whether the stored copy is controlled, and whether revocation was last tested successfully.

Keep emergency access separate

Break-glass access is for recovering control when routine deployment and normal operator paths are unavailable. It must not be the credential that the deployment pipeline uses every day.

Store the emergency credential separately from CI secrets, restrict who can retrieve it, and record every access request, retrieval, use, and replacement. Define the conditions that authorise use, who approves it, how the operator reaches the host or control plane, which actions are allowed, how evidence is retained, and when the credential must be rotated after use.

Exercise the recovery procedure in a controlled window. The test should prove that an authorised operator can retrieve the current credential, reach the intended recovery path, identify the affected system, and relinquish access afterward. It should also prove that the routine pipeline cannot retrieve or silently substitute the emergency credential.

Keep provider-account recovery, server login, source-control recovery, and application recovery distinct. One emergency key should not become a universal bypass across every system.

Validate permitted and denied paths

A successful deployment proves only that one positive path worked. Least privilege also requires evidence that unwanted paths fail without locking out the intended workflow.

For each deployment identity, test and record:

  • the intended repository or artefact can be read, while an unrelated repository cannot;
  • the intended host and environment accept the credential, while another environment does not;
  • the approved release path can be written, while another application's path cannot;
  • the reviewed service action succeeds, while an unrelated privileged action is denied;
  • the current credential produces attributable authentication and deployment logs;
  • a removed credential is rejected after revocation;
  • a personal operator key cannot silently stand in for the automation identity; and
  • the emergency credential is unavailable to the routine pipeline.

Use a safe test target for denial checks. Do not attempt a destructive operation merely to prove it is blocked. Record the time, identity, target, expected result, actual result, log reference, and reviewer. Re-run the checks after permission, operating-system, OpenSSH, CI-platform, repository, host, or deployment-wrapper changes.

Deployment key checklist

  • Define the exact repository, artefact, host, environment, path, service action, and health check for the deployment.
  • Give every automation system and environment a separate non-personal identity.
  • Keep personal, routine automation, runtime, and emergency credentials separate.
  • Grant read-only source and dependency access where writes are unnecessary.
  • Separate deployment permission from source-control, package, and organisation administration.
  • Avoid an unrestricted root key or privileged shell for routine deployment.
  • Store private credentials only in the approved automation secret store and keep them out of repositories, images, artefacts, logs, and chat.
  • Record every identity in the purpose, scope, owner, storage, creation, verification, and revocation inventory.
  • Test the replacement credential before removing the old one.
  • Remove the old credential from every destination and prove it is rejected.
  • Test at least one safe denied path for each important boundary.
  • Audit break-glass access separately and rotate it after use or suspected exposure.
  • Revalidate after identity, scope, owner, platform, host, SSH, or deployment-process changes.

When a VPS is the right fit

A self-managed VPS is appropriate when the team wants control over operating-system users, SSH configuration, filesystem permissions, deployment paths, services, and logs—and has an owner capable of operating those controls. That control makes narrow deployment identities possible; it does not create them automatically.

Virtarix supplies self-managed server infrastructure and Linux plans with full root access. The customer remains responsible for credentials, access control, operating-system and application security, updates, monitoring, backups, recovery, and incident response. A root credential is therefore an administrative starting point, not the right routine deployment credential.

Choose the server only after the deployment design names its identities, scopes, owners, logs, revocation path, recovery path, and validation checks. If the team cannot maintain those controls, use a service whose provider explicitly owns the required management work.

FAQs

Why should each pipeline have its own deployment identity?

Separate identities make activity attributable and revocation bounded. If one pipeline is compromised or retired, its credential can be disabled without stopping unrelated deployments or removing an operator's access.

How often should a deployment key be rotated?

Use the organisation's approved schedule as a review trigger, and rotate immediately after suspected exposure, excessive scope, owner or platform change, unexplained use, or destination retirement. A scheduled replacement is incomplete until the new credential works and the old one is proved unusable.

How do we revoke a key without causing an outage?

Add and test the replacement first, confirm the expected identity and deployment result in logs, then remove the old credential from every accepting system. Run a negative test with the old credential and observe the next normal deployment with the replacement.

Can authorized_keys restrictions enforce the whole policy?

No. They may narrow the SSH entry path when supported and correctly configured for the installed OpenSSH version, but they do not constrain an unsafe allowed command, writable helper, broad privilege rule, or secret that the resulting process can access. Test the complete permission chain.

Should a deployment pipeline use the server's root key?

No. A routine pipeline should use its own narrow identity and only the host actions required for that deployment. Keep administrative and emergency access separate, attributable, and independently revocable.

What should happen when a deployment system is retired?

Disable its source, package, host, and control-plane credentials; remove its destination authorisations; archive the relevant audit evidence; and test that the retired identity is rejected. Update the inventory so no owner mistakes an abandoned key for an active dependency.

Peter French
About the Author Peter Frenchis the Managing Director at Virtarix, with over 17 years in the tech industry. He has co-founded a cloud storage business, led strategy at a global cloud computing leader, and driven market growth in cybersecurity and data protection.