Remove a Previous Developer's Access to Your Code Repository
For agency customers who need to lock down a code repository after a developer leaves. This runbook shows how to confirm whether they still have access, remove it through the repository dashboard first, rotate any exposed credentials, and verify they can no longer clone, push, or deploy.
TL;DR — If a previous developer still has access to your code repository, the fastest safe response is: remove their user from the repository owner account or organization, revoke outside collaborator access, then rotate any deploy keys, personal access tokens, and CI/CD secrets they may have used. Removing the account alone is often not enough if machine keys or automation tokens still work. Reading time: ~6 min
The scenario
It is a normal Tuesday afternoon: you ask your new developer to add a small fix, and they notice an unfamiliar name still listed under repository access. You check your inbox and find the old developer was still copied on commit notifications last week. Nobody is saying anything is wrong yet, but you now have an awkward and urgent question: can they still clone the code, push changes, or trigger deployments? You need a clean answer quickly, without breaking your live site.
Symptoms
- In your repository provider's dashboard, the previous developer still appears under users, members, collaborators, or access lists.
- Audit logs (activity history showing security-relevant actions) show recent events from their account, such as:
member.added
repo.access_granted
git.clone
git.push
deploy.triggered
ssh_key.used
personal_access_token.used
- Your CI/CD system (build-and-deploy automation) still shows runs triggered by their user identity.
- They can still successfully clone or pull the repository.
- They can still push to a branch, open a pull request, or approve changes.
- A deploy still works from an old machine key even after you remove their user account.
- You find credentials in settings such as:
Deploy key: active
SSH key: last used 2 days ago
Personal access token: active
Webhook secret: unchanged since offboarding
Likely causes
| Cause | How common | Quick check |
|---|---|---|
| Their user account is still a member/collaborator on the repo or organization | Very common | In your provider's dashboard: Repository/Organization Settings → Access/Members/Collaborators |
| Their SSH key or deploy key is still attached | Very common | In your provider's dashboard: Repository Settings → Deploy keys or User Settings → SSH keys |
| A personal access token or app token they created is still active | Common | In your provider's dashboard: Settings → Developer settings / Access tokens / Authorized apps |
| CI/CD or hosting still uses credentials they set up | Common | In your CI/CD or hosting dashboard: Project Settings → Environment variables / Secrets / Deploy keys |
| Shared credentials were used instead of named user accounts | Less common | Search your password manager or internal docs for generic logins like "dev@", "github@", or shared SSH keys |
Step-by-step diagnosis
-
Check direct repository access first.
- Dashboard path: in your repository provider's dashboard, open the repository, then go to Settings → Access, Collaborators, Members, or Manage access (wording varies by provider).
- What confirms the problem: you see the previous developer listed with any role, even read-only.
- Jump to: Fixes → Their user account is still a member/collaborator on the repo or organization.
-
Check organization or team access.
- Dashboard path: Organization/Workspace Settings → Members or Teams, then open the team that owns the repository.
- What confirms the problem: the person is not on the repo directly, but is still in a team/group that grants repository access.
- Jump to: Fixes → Their user account is still a member/collaborator on the repo or organization.
-
Check deploy keys and SSH keys.
- Dashboard path: Repository Settings → Deploy keys; also check the user's profile or organization settings for SSH keys if your provider exposes last-used details.
- What confirms the problem: an SSH key is active, especially one with write access or unclear ownership, or a key shows recent use.
- Jump to: Fixes → Their SSH key or deploy key is still attached.
-
Check tokens and authorized apps.
- Dashboard path: Settings → Developer settings, Access tokens, Personal access tokens, Fine-grained tokens, OAuth apps, or Authorized applications (names vary).
- What confirms the problem: an active token created by that user, or an app/integration they installed that still has repository scope.
- Jump to: Fixes → A personal access token or app token they created is still active.
-
Check CI/CD and hosting secrets.
- Dashboard path: in your CI/CD or hosting provider's dashboard, open the project, then Settings → Environment variables, Secrets, Deploy keys, Service connections, or Source control integration.
- What confirms the problem: the project uses a token, SSH key, or linked account owned by the previous developer.
- Jump to: Fixes → CI/CD or hosting still uses credentials they set up.
-
Check for shared credentials.
- Look in your password manager or internal handover doc for generic logins and keys.
- If you have a local copy of the infrastructure repo, you can also search for old usernames or key comments:
grep -RniE "old.name|old@email.com|BEGIN OPENSSH PRIVATE KEY|ghp_|glpat-|xoxp-" .
- What confirms the problem: you find a shared login, copied private key, or a token stored outside the provider dashboard.
- Jump to: Fixes → Shared credentials were used instead of named user accounts.
View as text
[You] ---- 1. check repo access ----> [Repo Provider] | | | 2. check team/org membership | 3. check keys/tokens v v [Org/Team] [Keys/Tokens] | | | 4. if clean, check CI/CD | 5. rotate if active v v [CI/CD or Host] ---- 6. verify no access ----> [Closed]
Fixes
Their user account is still a member/collaborator on the repo or organization
- Remove direct repository access.
- Dashboard path: Repository Settings → Access/Collaborators/Members → find the user → Remove.
- Remove organization or team membership if present.
- Dashboard path: Organization Settings → Members or Teams → find the user → Remove from organization/team.
- If your provider supports it, force sign-out or revoke active sessions for that user from the organization security page.
- If branch protection (rules that control who can push to protected branches) lists them by name, remove that exception.
If you prefer CLI and your provider supports it, use the provider's official CLI. Example with GitHub CLI for a direct collaborator:
gh api -X DELETE /repos/OWNER/REPO/collaborators/USERNAME
Verify it worked:
The user no longer appears under repository or organization access, and a fresh audit log view shows no active permissions for them.
Their SSH key or deploy key is still attached
⚠️ Removing or rotating a deploy key can break automated deployments until you update the replacement key in your hosting or CI/CD system.
- Remove old deploy keys from the repository.
- Dashboard path: Repository Settings → Deploy keys → Delete any key you cannot confidently map to a current system.
- Remove old SSH keys from organization or user settings if your provider allows admin review.
- Create a new key pair for the service that actually needs access.
ssh-keygen -t ed25519 -C "ci-deploy-2026-10" -f ./ci_deploy_key -N ""
- Add the new public key (
ci_deploy_key.pub) as a deploy key or machine user key. - Update the private key in your CI/CD or hosting dashboard secret store.
Verify it worked:
ssh -T git@github.com
You should see the expected service account identity, not the previous developer's account.
A personal access token or app token they created is still active
⚠️ Revoking a token can stop builds, deployments, or integrations immediately if that token is in use.
- Revoke the old token.
- Dashboard path: Settings → Access tokens / Developer settings / Authorized apps → Revoke or Delete.
- If the token belongs to an integration they installed, uninstall that app or reduce its repository scope.
- Create a replacement token under a company-owned account or service account, with the smallest scope needed.
- Update every place that used the old token: CI/CD secrets, hosting provider source-control connection, webhook sender, or automation tool.
Example of updating a local .env template for CI (do not commit real secrets):
REPO_TOKEN=replace-with-new-service-token
Verify it worked:
The old token shows as revoked/deleted, and the next build/deploy succeeds using the new service account.
CI/CD or hosting still uses credentials they set up
⚠️ Changing source-control or deploy credentials can pause deployments until the new connection is tested.
- In your CI/CD or hosting dashboard, open the project.
- Go to Settings → Environment variables / Secrets / Source control / Deploy keys.
- Replace any token, SSH key, or linked repository account owned by the previous developer.
- Reconnect the repository using a company-owned admin or service account.
- Trigger a test build from the dashboard.
If your pipeline uses a secret name like GIT_SSH_KEY or REPO_TOKEN, replace its value there rather than editing application code.
Verify it worked:
A manual test build completes successfully, and the build log shows the repository checkout/authentication step succeeded with the new credential.
Shared credentials were used instead of named user accounts
⚠️ Rotating shared credentials may log out current staff or break unattended jobs until everyone updates their saved credentials.
- Identify every shared credential: generic email logins, shared SSH keys, saved browser passwords, and tokens in password managers.
- Change the password on the shared account, or preferably disable it and create named accounts for each person.
- Rotate any shared SSH keys or tokens.
- Update CI/CD, hosting, and local documentation with the new named-account process.
If you need to search a repo for accidentally committed secrets before rotating them:
grep -RniE "ghp_|glpat-|BEGIN OPENSSH PRIVATE KEY|aws_access_key_id|api[_-]?key" .
Verify it worked:
No active system depends on the old shared credential, and each current team member now appears under their own named account.
Prevention
- Use named accounts only; no shared logins.
- Put this in your offboarding checklist:
Remove from repo
Remove from org/team
Revoke tokens
Delete SSH/deploy keys
Rotate CI/CD secrets
Verify audit log
- Use a company-owned service account for automation.
- Label keys clearly when you create them:
ssh-keygen -t ed25519 -C "service-account-ci-prod-2026-10" -f ./prod_ci_key -N ""
- Review access monthly.
- In your provider's dashboard, export or review Members/Collaborators and compare it to your current staff list.
- Keep a simple spreadsheet with columns:
Name | Role | Repo access | Last reviewed | Owner
- Alert on security-relevant audit events.
- In your logging or SIEM (security monitoring) tool, alert on events like:
{
"events": ["member.added", "member.removed", "ssh_key.used", "token.created", "deploy_key.added"],
"notify": "ops@yourcompany.com"
}
- Keep branch protection and CODEOWNERS in place.
- Example
CODEOWNERSfile:
- Example
* @your-company/engineering-leads
infra/ @your-company/devops
- This does not remove access by itself, but it reduces the chance of silent changes landing during a transition.
- Store secrets only in your secret manager or CI/CD secret store, not in code or shared docs.
- Add a CI check for obvious leaked credentials:
grep -RniE "ghp_|glpat-|BEGIN OPENSSH PRIVATE KEY|api[_-]?key" . && exit 1 || exit 0
- Run that in CI on pull requests so accidental secret commits are blocked early.
This article was written by an AI system and published pending human review. Verify anything you intend to act on.
Have a project in mind?
Get an instant AI price estimate for it, or talk directly to our team.
One email a month on what we learn building with AI