Back to blog

Contractor SSH Access Without Forgotten Keys

Short-term contractor SSH access often outlives the project. Why manual key management creates forgotten keys, and how expiry and cleanup should be built in from the start.

Contractor access is one of the easiest SSH problems to create.

Not because anyone is being careless. Usually it happens for perfectly sensible reasons.

A freelancer joins a project.
A contractor needs to fix something on a client server.
Someone needs access for a week of support work.
A specialist needs to jump onto a box to debug a problem.

So someone adds their SSH key.

The work gets done, the project moves on, and everyone gets busy with the next thing.

Then, months later, someone asks a simple question:

Did we ever remove that contractor's SSH access?

And the answer is often something like:

"Probably?"
"I think so."
"It should have been in Ansible."
"Was that on the staging server or production too?"
"Which key was theirs again?"

That is the problem.

Temporary SSH access has a bad habit of becoming permanent.

The problem with "just add their key"

The normal manual process is simple enough.

A contractor sends over their public key. Someone logs into a server, opens an authorized_keys file, pastes the key in, saves it, and tells them to try connecting.

Maybe that happens on one server. Maybe it happens on five. Maybe the key goes into a shared account like ubuntu, deployer, or root. Maybe it gets added through Ansible, Terraform, a shell script, a hosting panel, or whatever system the team happens to use.

At the time, it feels fine.

The problem is what happens later.

Contractors are often brought in for short, specific pieces of work. That might be a client project, an incident, a migration, a bug fix, or a one-off piece of maintenance.

Their need for access usually has a natural end date.

But the SSH key does not.

Unless someone remembers to remove it, that key can sit there long after the work is finished.

Forgotten keys are not always obvious

The awkward thing about stale SSH access is that it does not usually announce itself.

A forgotten contractor key does not break the build.
It does not show up in the UI.
It does not necessarily trigger an alert.
It just sits in an authorized_keys file.

That means teams often only notice during an audit, an offboarding review, a client security question, or when someone happens to inspect a server and sees a key they do not recognise.

By that point, nobody may remember why it was added.

Was it for a contractor?
An old employee?
A deployment key?
A temporary support job?
Someone's old laptop?
A key copied from another server years ago?

This is where SSH access gets messy.

The issue is not that SSH is bad. SSH is great. The issue is that manual access management relies heavily on memory, comments, old notes, and people doing cleanup later.

And "later" is where a lot of security hygiene goes to die.

Contractor access should have an expiry date

When a contractor needs SSH access, the question should not only be:

Which server do they need?

It should also be:

When should this access end?

That sounds obvious, but a lot of SSH workflows do not have a natural place to record it.

An authorized_keys file can tell you which keys are allowed, but it does not tell you why they were added, who approved them, which project they relate to, or when they should be removed.

That is why temporary access so often becomes indefinite access.

For contractor work, expiry should be part of the access itself.

Examples:

  • Give a contractor access until the end of the week.
  • Give a freelancer access only during a maintenance window.
  • Give a developer access to a staging server for a short project.
  • Give an external specialist access while they are debugging an issue.
  • Give a client-side developer access for the duration of a handover.

Once the need ends, access should end too.

Not because someone remembered.
Not because someone added a calendar reminder.
Not because someone eventually got around to cleaning up keys.

It should just expire.

The GrantSSH approach

GrantSSH is built around keeping normal SSH, but making access easier to manage.

A contractor can still use their own SSH client and their own SSH key. There is no new way of connecting to learn, no bastion host to route through, and no proprietary SSH workflow to adopt.

Instead, GrantSSH helps you manage the access around SSH.

You can choose who gets access, which server they can access, which Linux account they can use, and when that access should be active.

That means contractor access can be granted for the actual period it is needed.

When the access window ends, GrantSSH removes that access automatically.

So instead of copying a key into authorized_keys and hoping someone remembers to remove it later, you can make the expiry part of the permission from the start.

Why this matters for agencies and dev teams

Contractor SSH access is especially common in agencies, software companies, and small development teams.

Agencies may have client servers, staging servers, production boxes, legacy projects, freelancers, and external specialists moving in and out of different projects.

Software teams may bring in contractors for migrations, infrastructure work, audits, cover, urgent fixes, or short-term development.

Freelancers may work with other freelancers or subcontractors on client projects.

In all of these cases, access tends to be fluid.

People come and go.
Projects start and end.
Servers change hands.
Work gets passed between teams.
Old environments stick around longer than expected.

If SSH access is managed manually, it is very easy for the real state of access to drift away from what everyone thinks the state of access is.

That drift is the danger.

Not because every stale key will be misused, but because you cannot confidently say who still has access.

Normal SSH still matters

One reason we built GrantSSH the way we did is that we did not want to replace SSH.

For many teams, SSH is already the right tool. Developers know how to use it. Servers are already set up for it. Public key authentication is already part of the workflow.

The last thing a small team wants is to turn a straightforward access problem into a big infrastructure project.

That is why GrantSSH is not trying to be a bastion host, SSH proxy, VPN, or enterprise access platform.

Those tools have their place, but they can be too heavy for teams that simply want better control over who can SSH into which server, and for how long.

GrantSSH is designed to be less intrusive than that.

Keep normal SSH.
Keep users' private keys on their own machines.
Keep the connection direct.
Use GrantSSH to manage the access rules and cleanup.

Visibility after access is granted

Managing contractor SSH access is not only about adding and removing keys.

It is also useful to know what happened while access was active.

GrantSSH can log SSH activity, including when someone connects and when they use sudo.

That gives teams a clearer view of contractor access without needing to turn their SSH setup into a full session-recording platform.

For many small teams, the useful questions are fairly basic:

  • Did the contractor log in?
  • When did they connect?
  • Which server did they access?
  • Did they use elevated privileges?
  • Is their access still active?
  • When does it expire?

Having those answers in one place is a big step up from digging through server logs after the fact or relying on someone's memory.

The real goal: less cleanup later

The best time to clean up contractor access is when you grant it.

That might sound backwards, but it is the core idea.

If you know access is temporary, give it a schedule.

If you know a contractor only needs one server, scope it to that server.

If you know they only need a specific Linux account, do not add them everywhere.

If you know the work ends on Friday, do not leave the key sitting there until someone remembers.

Good access management is not only about locking things down. It is about matching access to the actual need.

Contractors often need access quickly, and that is fine. GrantSSH is not trying to slow that down.

It is trying to stop quick access from becoming forgotten access.

A simpler way to handle contractor SSH access

Contractor access should not require a huge enterprise platform.

But it also should not rely on copied keys, old notes, and hope.

GrantSSH sits in the middle.

It gives teams a practical way to grant SSH access, set expiry dates, keep authorized_keys clean, and see useful activity around server access.

So the next time a contractor needs to jump onto a server, the process can be simple:

Add them.
Choose the server and account.
Set when access should end.
Let them use normal SSH.
Let GrantSSH clean it up afterwards.

Because temporary SSH access should not become permanent just because everyone got busy.

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