Back to blog

How to Onboard a New Developer Without Giving Away Too Much Access

A practical approach to developer SSH onboarding that keeps people productive without handing out production access, shared accounts, and permanent keys by default.

Onboarding a new developer usually gets treated as a speed problem. They need the repo, the docs, the deploy process, staging, logs, maybe a quick look at something broken. So access gets added quickly.

That is fair enough. Nobody wants someone stuck on day one because they cannot do basic work. The trouble is that access added during onboarding has a habit of becoming permanent. Someone gets production "just for now", or lands on the shared deployer account because that is how the last hire was set up, or gets copied onto every server because nobody has time to work out the exact list. A few months later, nobody remembers why they have that level of access. It is one of the common SSH mistakes small teams make, and it starts earlier than most people think.

Least privilege does not need to be a slogan here. It is a practical habit: give people the access they need for the work they are doing now, and make it easy to add more later when there is a real reason. That keeps onboarding moving without quietly handing out more server access than anyone meant to.

Start with the work, not the job title

Granting access based on someone's role is where this often goes wrong. "New developer" is too broad. One person might only need frontend code. Another might be debugging deployments. Someone joining the platform team may genuinely need production. Someone else might only be on one client project.

Before you touch SSH, ask what they actually need to do in the first few weeks. Which project are they joining? Which environments will they work on? Do they need SSH at all, or will staging through a web UI and local setup cover them? Staging, production, or both? Do they need to deploy, read logs, touch a database, or use sudo? Is any of this temporary, and who owns approving the next bit later?

You do not need a formal process for this. A short checklist in the onboarding ticket is enough. The goal is simply to stop "new developer" turning into "access to everything".

Separate environments properly

Most teams already think about environments differently, but SSH access often fails to reflect that. A useful default looks something like this:

Environment Default for a new developer
Local development Yes, through normal setup
Shared development server Usually yes, if the team uses one
Staging Often yes, depending on the project
Production No by default
Client production No by default
Database servers No by default
Backup servers No by default
Monitoring or deployment servers Only if needed

That does not mean new developers can never reach production. It means production access should be a deliberate decision, not part of the welcome pack. If someone can do their work on staging, give them staging. It sounds obvious, and yet this is where a lot of SSH access gets messy, because granting everything is faster than deciding carefully. Client servers deserve the same caution: see SSH access for agencies managing client servers if that is part of your world.

Be specific about server accounts

SSH access is not only about which server someone can reach. It is also about which Linux account they land in. There is a big difference between alice@staging-web-01, deploy@staging-web-01, ubuntu@production-web-01, and root@production-web-01. They may all be "SSH access", but they do not carry the same risk.

When onboarding, avoid powerful shared accounts unless there is a clear reason. Accounts like root, ubuntu, admin, deployer, deploy, forge, www-data, and other project-wide shared users are convenient, but they make accountability harder. If five people log in as deployer, it is much harder to know who did what.

Named accounts are better where you can manage them: alice@staging-web-01, ben@staging-worker-01. If your team does rely on shared deployment accounts, be deliberate about who can use them and why.

Avoid direct root access

Direct root SSH should be rare. For most teams, a better pattern is that the developer logs in as themselves, uses sudo only if the role needs it, and treats sudo as a separate decision from SSH itself. That gives you more control and a better audit trail.

Needing to inspect logs is not the same as needing root. Membership of a group that can read logs may be enough. Needing to restart a service is not the same as unrestricted sudo. Permission for one specific service is often enough. Reading application logs, deploying code, restarting one service, running any command with sudo, and logging in as root are very different levels of access. Do not treat them as interchangeable.

Make production access a second step

For a lot of developers, production does not belong in day-one onboarding. A better sequence is: project, repo, docs, and local setup first; staging where needed; time to learn the deploy and debugging flow; production later only if the work genuinely requires it; and a short note on why it was granted.

That pause stops production access being copied across just because it is easier to match the previous developer's setup. It also gives the new person time to understand the system before they can touch the most sensitive environment. For a small team this can stay lightweight. You do not need a committee. You need a clear owner, something as simple as: production SSH needs approval from the project lead or team owner. Simple rules get followed. Vague expectations do not.

Use temporary access during onboarding

Onboarding is full of short-lived needs. Pairing for a few days, poking at an old system, shadowing an on-call shift, helping with a migration, debugging one issue, learning the release process. Useful for a week. Unnecessary after that.

If access is only needed for onboarding, give it an end date.

Access Reason End date
Staging SSH First week project setup End of week one
Production logs Shadowing an incident review Friday
Deploy account Learning the release process End of month
Client server Handover work Project handover date

Temporary access without an expiry date tends to become permanent access. That is especially true during onboarding, when everyone is busy making the person productive and cleanup rarely feels urgent later. How temporary SSH access should work covers this in more detail, and stale SSH keys is usually what you get when the expiry step never happens.

Keep SSH keys personal

Each developer should use their own SSH key. Shared private keys, one team-wide key, copying someone else's key, reusing an old key from a previous company, dumping keys in shared drives, sending them over Slack or email, and unlabelled keys with no clear owner are all ways to make the next incident harder than it needs to be. What happens when an SSH key is compromised is a lot less painful when you can point at one person and one key.

A better setup: each person generates their own key pair, the private key stays on their machine, the public key goes only where needed, the key has a clear label, old keys get removed when replaced, and lost or compromised keys get revoked quickly. Comments like alice-macbook-2026, ben-framework-laptop, or sarah-workstation-ed25519 are not a security boundary, but they help the next human who opens authorized_keys. The SSH keygen command generator is a quick way to produce a sensible Ed25519 command if you want a consistent default.

Record why access exists

A line in authorized_keys tells you that access exists. It does not tell you much else. For every new developer, it helps to write down the person, team or project, server, Linux account, reason, who approved it, whether it is temporary, and a review or expiry date.

That can live in your ticketing system, internal docs, a spreadsheet, or an access tool. The exact system matters less than having somewhere reliable to look. Six months later you do not want to be asking whether anyone knows why a particular key is on the production box. Auditing authorized_keys and auditing SSH access across a fleet both get a lot easier when that context already exists.

Give access in layers

A practical way to onboard is to layer access over time rather than guessing everything on day one.

Day one usually covers repos, local docs, project tools, chat, the development environment, and staging if the work needs it. Production SSH, database and backup servers, root, broad sudo, and client production are usually better left out.

In the first week, add access based on what they are actually doing: staging logs, project-specific servers, deployment tooling, maybe read-only production visibility if that is appropriate, and any specific service access that keeps coming up.

Around the first month, review what they really needed. Remove temporary onboarding access. Keep permanent access only where it is justified. Check whether production is still required. Confirm their key and account setup is clear, and that access matches their real responsibilities.

This staged approach is safer than front-loading everything, and it makes later cleanup less awkward because temporary access was labelled temporary from the start.

Make requesting more access easy

Least privilege only works if getting more access is not painful. If every reasonable request turns into a fight, people will work around the process.

A good request is short: what they need, which account, why, how long, and who can approve it. Something like:

Request: SSH access to staging-worker-01 as alice
Reason: Debugging queue worker issue on Project Atlas
Duration: Until Friday
Approver: Project lead

That is enough for a small team to decide. The process should be quick, but not invisible.

Review access after onboarding

The end of onboarding is a good moment to clean up while the context is still fresh. Did they get temporary access, and do they still need it? Did production get added during onboarding, and was that meant to stick? Are they on a named account, any shared accounts, any client servers? Do they have sudo? Is their key labelled clearly, and is the access written down somewhere?

Ten minutes is often enough. The same discipline that helps with developer offboarding works in reverse here: decide what stays, remove what was only for the ramp-up, and leave a record.

A simple access matrix

For small teams, a light matrix is often enough to stop over-granting.

Person Server Account Access type Reason Expiry
Alice staging-web-01 alice SSH Project onboarding Permanent
Alice staging-worker-01 alice SSH Queue debugging Friday
Alice prod-web-01 alice SSH + limited sudo Release shadowing End of month
Ben client-a-staging ben SSH Client project Project end
Chris prod-db-01 None No access Not required N/A

It makes access easier to discuss, and it makes overbroad access obvious. If a new frontend developer somehow has SSH to production database servers, the matrix shows it. Without one, that access may sit quietly in a server file until someone happens to notice.

Where GrantSSH fits

GrantSSH is for teams that want this kind of control without turning SSH into a large infrastructure project. You keep normal SSH, but manage access more deliberately: which person, which server, which Linux account, temporary or scheduled access where it fits, central removal when access is no longer needed, authorized_keys kept in sync by the agent, and useful activity such as logins and sudo usage. The features page covers the access control, scheduling, and auditing side in more detail.

That matters during onboarding because new developers often need access gradually. Staging today, production later, temporary access to a client server for one handover. Managing that without copying keys around by hand, and hoping the cleanup happens later, is the whole point.

A better onboarding habit

Good developer onboarding should help people become productive quickly. It should also avoid quietly handing out server access they do not need.

In practice that means starting with the work they are doing, giving access only to the servers and accounts required, keeping production and direct root out of the default pack, preferring named accounts, treating sudo as its own decision, putting expiry dates on temporary access, recording why access exists, and reviewing it once onboarding is done.

None of that needs to be slow or bureaucratic. It just needs to be intentional. The best onboarding process is one where a new developer can get moving quickly, and the team can still answer a simple question later: does this person still have the right access, and nothing more?

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