What to do if a password is leaked: a response runbook
A runbook for a leaked password or key: contain it, check sign-in logs in Entra ID, Google Workspace and CloudTrail, decide on UK GDPR notice, prevent a repeat.
On this page
If a password is leaked, change it first and investigate second. Then end any sessions and tokens it has already produced, check that nobody has added their own MFA method or a mail-forwarding rule, and read the sign-in logs for the account from the moment of the leak. Only once you know whether it was used do you decide who needs to be told. Most leaks end at the first step: rotated within the hour, logs clean, cause fixed.
This runbook is for the person who has just found out: a password pasted into a Slack channel, an AWS key committed to a public repository, a breach notification from a service, a laptop left on a train, a colleague who typed their password into a page that wasn’t Microsoft’s. It’s written in four stages, contain, assess, notify, prevent, with a checklist at the end to print or paste into the incident ticket.
Before you start: how bad could this be
Spend two minutes on this; it decides how fast everything else needs to go.
| Question | Lower urgency | Drop everything |
|---|---|---|
| Where did it leak? | An internal channel or mailbox | A public repository, a paste site, a phishing page, another company’s systems |
| What does it reach? | One low-value app | Email, the identity provider, cloud admin, the password manager, banking |
| Is MFA on the account? | Yes, phishing-resistant | No, or it’s a key or token where MFA doesn’t apply |
| Is there sign of use? | None yet | Unfamiliar sign-ins, new rules, unexpected charges |
A key in a public GitHub repository is the most urgent case of all. Bots watch public commits for credentials continuously, so treat it as used until the logs say otherwise.
Contain: rotate, revoke, check what’s been added
1. Change the credential
For a user account, reset the password. For an API key or access key, the order depends on whether there’s sign of abuse. If there isn’t, create the new key, deploy it, then revoke the old one, as described in sharing API keys and .env files. If there is, revoke the old key immediately and accept the outage.
If the same password is used anywhere else, change it there too. Reuse turns one leak into several.
2. End sessions and tokens it has already produced
A new password doesn’t always end sessions that are already open, and a revoked key doesn’t always invalidate credentials issued from it.
-
Entra ID. Revoke the user’s sessions, which invalidates their refresh tokens:
Revoke-MgUserSignInSession -UserId user@example.comAccess tokens already issued can keep working for an hour or so, unless the app supports continuous access evaluation.
-
Google Workspace. In the Admin console, open the user’s Security section, reset their sign-in cookies, and revoke any app passwords.
-
AWS. Deactivate the leaked access key:
aws iam update-access-key --user-name deploy-bot \ --access-key-id AKIAEXAMPLE --status InactiveTemporary credentials the attacker may have obtained with it keep working until they expire. For an IAM role, Revoke active sessions in the role’s page in the IAM console adds a policy that denies every request made with credentials issued before that moment.
-
GitHub and other SaaS. Revoke the personal access token or OAuth token, and check for new SSH keys or deploy keys.
3. Check what has been added
Attackers who get into an account set up a way back in. Look for:
- New MFA methods. An authenticator app or phone number the user doesn’t recognise. In Entra ID, the user’s Authentication methods page lists them, and the audit log records “User registered security info”.
- Mailbox rules and forwarding. Rules that forward or delete mail are the classic sign of a compromised mailbox, used to hide replies while invoices are redirected. In Exchange Online,
Get-InboxRule -Mailbox user@example.comlists them. - OAuth consents. Third-party apps granted access to mail or files.
- New accounts and keys. In AWS, CloudTrail events such as
CreateUser,CreateAccessKeyandCreateLoginProfile, and instances launched in regions you don’t use.
Remove anything you didn’t put there, then change the password again if you found something, since they may have read the first new one.
Assess: did anyone use it, and what could it reach
Now read the logs from the earliest moment the credential could have been exposed, not from when you noticed.
-
Entra ID. Sign-in logs in the Entra admin centre, filtered to the user, covering interactive and non-interactive sign-ins. Look at IP address, location, client app and device. Sign-in logs are kept for 7 days on Entra ID Free and 30 days with P1 or P2, so export them now.
-
Google Workspace. Reporting > Audit and investigation > User log events for sign-ins, and the Gmail log events for mail activity.
-
AWS. CloudTrail event history covers the last 90 days of management events at no cost:
aws iam get-access-key-last-used --access-key-id AKIAEXAMPLE aws cloudtrail lookup-events \ --lookup-attributes AttributeKey=AccessKeyId,AttributeValue=AKIAEXAMPLE \ --start-time 2026-09-30T00:00:00Zlookup-eventssearches one region at a time, so repeat it with--regionfor each region you use, and any you don’t. -
The app itself. Most SaaS tools have an audit or activity log. For a shared login, it can’t tell you which person was behind a sign-in, which is one more reason to replace shared logins with named accounts.
Then write down what the credential could reach: the data in that system, and any other credentials stored there. A compromised mailbox that contains emailed passwords is a leak of all of those too; why not to send passwords over email explains why. A compromised password manager account is the worst case of all.
If the credential was sent as a ShareShield link, the secret’s status shows whether it was opened, and the audit log records when and from which IP address. If you run IT for clients, password sharing for IT teams and MSPs shows the same log used as evidence for an auditor.
You should end this stage with one of three answers: exposed but not used, used by someone who shouldn’t have, or can’t tell. “Can’t tell”, usually because logs had already rolled over, gets treated as “used” when you decide on notification.
Notify: who needs to know, and when
Inside the company, tell the account’s owner, whoever leads IT or security, and your data protection lead if you have one, as soon as you’ve contained it. Don’t wait for the full picture.
The ICO, only if there’s been a personal data breach. Under UK GDPR Article 33, a controller reports a personal data breach to the ICO within 72 hours of becoming aware of it, unless it’s unlikely to result in a risk to people’s rights and freedoms. A leaked password on its own is not automatically a personal data breach. It becomes one when someone unauthorised accessed, or may have accessed, personal data with it. If you’re not sure, the ICO has an online self-assessment. If you don’t have every detail within 72 hours, Article 33 lets you report what you know and add the rest later.
Whatever you decide, record it. Article 33(5) requires you to document every personal data breach, including the ones you don’t report, and your reasoning.
The people affected, if the breach is likely to put them at high risk (Article 34). Your customers, if you process their data and your contract says when you must tell them; a processor must tell the controller without undue delay. Your insurer, if you have cyber cover; most policies want early notice.
Say it accurately. What happened, when, what the credential could reach, what you’ve seen in the logs, what you’ve done, and what you don’t know yet. “We have no evidence it was used” is honest when it’s true. “No data was accessed” is a claim you can only make if your logs cover the whole period.
Prevent: find out why it was shared there
The useful question isn’t who leaked it. It’s why someone needed to put a password in a Slack channel, a repository or an email, and why that was the easiest way to do it.
- It was shared to get a job done. Give people a quicker safe route: shared vaults in the password manager, and one-time links for anyone outside it. How to send a password securely is the version to hand round.
- It was committed to code. Turn on secret scanning and push protection in GitHub, and move the value to a secret manager.
- It was phished. Move the account to phishing-resistant MFA (passkeys or FIDO2 keys) and ask why the page wasn’t blocked.
- It was a shared login. Replace it with named accounts where the service allows.
Keep the review blameless. People who are punished for reporting a leak stop reporting them, and the ones you don’t hear about are the ones that hurt.
The checklist
Contain:
- Credential changed, and anywhere the same password was reused
- Sessions revoked (Entra ID, Google Workspace, SaaS)
- Keys deactivated; role sessions revoked in AWS
- MFA methods reviewed; unknown ones removed
- Mailbox rules and forwarding checked
- OAuth consents, app passwords, new keys and accounts checked
- Password changed again if anything had been added
Assess:
- Time of first possible exposure recorded
- Sign-in and audit logs exported from that time
- Each sign-in accounted for
- What the credential could reach listed, including other credentials stored there
- Outcome recorded: not used, used, or can’t tell
Notify:
- Account owner, IT or security lead and data protection lead told
- Personal data breach decision made and reasoning recorded
- ICO notified within 72 hours of awareness, if required
- Affected people, customers and insurer told, if required
Prevent:
- Root cause written down: why it was shared there
- A safer route put in place for that job
- Ticket closed with dates, owners and no secret values in it
Send the next one as a link that expires.
ShareShield turns a password, key or file into a link that opens once and is then deleted. You can send a text secret without an account.
