Back to blog

Common SSH Access Mistakes Small Teams Make

Ten predictable SSH access mistakes small teams make, from shared keys and forgotten offboarding to weak audit trails and unmanaged contractors, plus a simple policy to fix them.

SSH access often starts out simple.

One person creates a server, adds a public key, and gets on with the job. Then the team grows. Another developer needs access. A contractor is brought in for a few weeks. Someone leaves. A second production server appears.

Before long, nobody is completely sure who can access what, which keys are still valid, or who is responsible for cleaning it all up.

This is especially common in small teams because SSH access rarely feels like a problem until something goes wrong. The good news is that most issues come from a handful of predictable mistakes.

1. Sharing SSH keys

A shared SSH key might seem convenient. You create one key pair, give the private key to everyone who needs access, and add the public key to the server.

The problem is that the server can no longer tell those people apart.

If the key is used to log in, you know someone with a copy accessed the server, but you may not know who. If one person leaves the team, you have to replace the key for everyone. If the private key is copied into a password manager, shared drive, chat message, or deployment script, it can become difficult to track where it ended up.

Every person should use their own SSH key.

That gives you a clear connection between a key and its owner. It also means you can remove one person's access without disrupting the rest of the team.

The same principle applies to automated systems. CI jobs, deployment tools, monitoring services, and backup systems should have their own credentials rather than reusing a developer's personal key.

2. Forgetting to remove access when someone leaves

Offboarding is one of the most common SSH access problems.

A developer leaves the company, their application accounts are disabled, and their email is shut down. Their SSH key, however, may still be sitting in authorized_keys across several servers.

This often happens because nobody has a complete list of the systems they could access. The team removes the obvious accounts but misses an old staging server, a database host, or a machine that is rarely touched.

SSH access should be part of every offboarding checklist.

At a minimum, the process should cover:

  • Production servers
  • Staging and development servers
  • Bastion hosts
  • Database servers
  • Cloud virtual machines
  • Internal tools and appliances
  • Deployment and CI systems
  • Shared service accounts

It is also worth reviewing access when someone changes roles. A person moving away from infrastructure work may no longer need the same level of server access, even if they are still part of the company.

Removing unnecessary access is not a sign of distrust. It is basic account hygiene. For a deeper look at the workflow, see developer SSH offboarding.

3. Having no useful audit trail

When everyone connects using individual operating system accounts and individual keys, SSH logs can provide useful information about who logged in and when.

That becomes much harder when teams share keys, use shared accounts, or make changes manually without recording them anywhere.

A useful audit trail should help you answer questions such as:

  • Who currently has access to this server?
  • Who approved that access?
  • When was it granted?
  • When was it last reviewed?
  • Which key belongs to which person?
  • When was access removed?
  • Who changed the access configuration?

You do not need an enormous compliance system to improve this. Even a small amount of structure helps.

Keep a central record of servers, users, keys, and access decisions. Make access changes through a consistent process. Avoid relying on someone's memory or an old chat thread as your only record.

Logs are also much more useful when people are not sharing accounts. A login from deploy or ubuntu tells you very little if half the team uses the same credentials.

If you are starting from scattered keys, how to audit SSH access across your fleet and how to audit authorized_keys files cover practical first steps.

4. Giving too many people production access

Small teams often give broad production access because it feels easier.

Everyone is trusted, everyone may occasionally need to fix something, and creating more restrictive access takes time. The result is that developers, contractors, support staff, and external agencies may all end up with direct access to production.

The issue is not just the risk of malicious activity. Most incidents are caused by mistakes.

Someone runs a command on the wrong server. A script is tested against production instead of staging. A database change is made without a backup. A private key is stored insecurely on a personal laptop.

Production access should be limited to people who genuinely need it.

That may still be most of the engineering team in a very small company, but it should be a deliberate decision rather than the default.

Consider separating access by environment and responsibility:

  • Most developers may need staging access
  • Fewer people may need production access
  • Database access may be restricted separately
  • Contractors may only need access to specific servers
  • Emergency access may be granted temporarily when required

It is also worth reviewing whether someone needs full shell access at all. In some cases, access to logs, deployment tools, dashboards, or a restricted command is enough. When access is only needed for an incident window, time-limited SSH for on-call work is usually a better default than standing production keys.

5. Leaving contractor access unmanaged

Contractors create a particular access-management problem because their work is often temporary, but their access is granted in the same permanent way as an employee's.

A contractor may need production access for a migration, server rebuild, security review, or short development project. Once the work is finished, their key is easy to forget.

Contractor access should have a clear owner inside the company.

That person should know:

  • Why the contractor needs access
  • Which servers they need
  • What level of access is required
  • When the work is expected to finish
  • Who is responsible for removing the access

Grant the narrowest access that allows them to do the work. Avoid adding a contractor's key to every server because it is quicker than working out what they actually need.

It is also sensible to agree an expiry or review date when access is first granted. A calendar reminder is better than hoping someone remembers three months later. Temporary SSH access and contractor SSH access without forgotten keys dig into that pattern in more detail.

If the contractor returns for another project, grant access again based on the new requirements rather than leaving old access active indefinitely. For a product-shaped version of this workflow, see temporary SSH access for contractors.

6. Having unclear ownership

SSH access tends to become messy when nobody owns the process.

The infrastructure may have been created by one developer, maintained by another, and occasionally changed by whoever was available at the time. Each person assumes someone else is keeping track.

Every server should have a clear owner, even if ownership is informal.

The owner does not need to personally approve every login. They should, however, be responsible for making sure access is appropriate, documented, and reviewed.

For each server or group of servers, decide:

  • Who is responsible for access decisions?
  • Who can add or remove users?
  • Who reviews existing access?
  • Who handles offboarding?
  • Who should be contacted during an incident?

This becomes more important when a team uses external hosting providers, managed services, freelance administrators, or several separate cloud accounts.

Ownership should also cover shared accounts. If a team continues to use accounts such as root, ubuntu, or deploy, someone needs to be responsible for controlling which keys are attached to them.

7. Editing authorized_keys manually everywhere

There is nothing inherently wrong with editing an authorized_keys file. For one server and one or two people, it may be perfectly manageable.

Problems appear when the same process is repeated manually across many servers.

Keys are copied between machines. Comments are inconsistent or missing. Old keys remain because nobody is sure whether they are still in use. One server is updated while another is forgotten.

If you manage access manually, use a consistent format and process.

For example:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... [email protected]

A useful comment should identify the key owner or purpose. Avoid comments such as laptop, new key, or admin, which may not mean much six months later.

For larger setups, consider managing keys through configuration management, infrastructure code, an identity-aware access system, or a dedicated SSH access tool. The important part is having a reliable source of truth rather than a collection of unrelated files.

GrantSSH is designed for this sort of situation. It gives small teams a central place to manage people, public keys, servers, and permissions without turning SSH access into a large infrastructure project. How GrantSSH works walks through the permission and agent model.

8. Treating public keys as permanent

SSH public keys do not normally expire on their own.

Once a key has been added to a server, it may remain valid until someone removes it. That can lead to keys surviving for years, even after the original laptop has been replaced or the owner has forgotten the key exists.

Teams should periodically review active keys.

Ask users to confirm which keys they still use. Remove duplicates, abandoned keys, and keys linked to old devices. Encourage people to use modern key types, such as Ed25519, where supported. Our guide to stale SSH keys covers how they accumulate and how to clean them up.

Private key security matters too. Keys should be protected with appropriate file permissions and, in most cases, a passphrase. They should not be pasted into tickets, chat messages, documentation, or shared storage.

A key rotation policy does not need to be complicated. The priority is being able to identify keys and remove them quickly when a device is lost or compromised. If you are inspecting keys during a review, the SSH key inspector and authorized_keys analyzer can help make sense of what is already on a host.

9. Using the root account for routine access

Direct root access is common on small servers, particularly when they are first created.

It is convenient, but it removes an important layer of accountability and protection. Every command runs with full privileges, and logs may show that root connected without making it clear which person was responsible.

Where practical, give each person their own account and use sudo for administrative tasks.

This provides a clearer audit trail and reduces the chance of destructive commands being run accidentally. It also makes it easier to apply different permissions to different users.

Some environments still require shared system accounts, particularly for deployments or automation. These should be treated as service accounts with a clearly defined purpose, not as general login accounts for the whole team.

10. Only reviewing access after an incident

Access reviews are easy to postpone because they rarely feel urgent.

The problem is that the longer you wait, the harder the review becomes. People forget why access was granted, servers change ownership, and old keys become difficult to identify.

A lightweight review every few months is usually enough for a small team.

For each server, check:

  • Which people have access
  • Which keys are installed
  • Whether each person still needs that access
  • Whether any contractors have finished their work
  • Whether former team members have been removed
  • Whether the server still has a clear owner
  • Whether any shared keys or accounts can be replaced

You should also review access after major changes, such as a team restructure, infrastructure migration, security incident, or change of hosting provider.

A simple SSH access policy for small teams

You do not need a long policy document. A few clear rules can prevent most of the problems covered above.

A reasonable starting point is:

  1. Every person uses their own SSH key.
  2. Keys must be clearly linked to an owner.
  3. Access is granted only to the servers required for someone's work.
  4. Production access is limited and reviewed regularly.
  5. Contractor access has an internal owner and review date.
  6. SSH access is removed during offboarding.
  7. Every server has a responsible owner.
  8. Access changes are recorded somewhere central.
  9. Shared accounts and keys are avoided where possible.
  10. Existing access is reviewed at least every few months.

The exact process matters less than consistency. A simple system that the team actually follows is better than a detailed policy that exists only in a document.

Final thoughts

Most SSH access problems are not caused by SSH itself. They come from access being granted informally, copied between servers, and forgotten over time.

Small teams do not need enterprise identity infrastructure to improve this. Start by giving everyone their own key, limiting production access, assigning clear ownership, and including SSH in your offboarding process.

Once manual tracking becomes difficult, move the information into a central system. That could be configuration management, an internal tool, or a service such as GrantSSH.

The goal is straightforward: you should be able to see who has access, understand why they have it, and remove it without searching through every server by hand.

Next steps

Take control of your SSH access

GrantSSH gives teams a clear, auditable way to grant and revoke SSH access. Create your account and get started in minutes.

← Back to blog