My cloud credentials file got exposed. What should I do?
Cloud credential files — GCP service account keys, AWS credentials files, Firebase config files — are long-lived static keys with potentially broad permissions. An attacker who obtains one can make API calls as your application or service account, often with administrative capabilities. This needs to be contained immediately.
Go to your cloud console right now and disable the exposed key.
Automated scanners continuously monitor GitHub, public web servers, and paste sites for cloud credentials. Keys found in public repositories are typically exploited within minutes. The cloud console revocation takes 30 seconds — do that first, then read this guide.
// the 60-second version
- Disable or delete the exposed key in your cloud provider's IAM console immediately.
- Create a replacement credential with the minimum permissions the application needs.
- Review cloud audit logs for API calls made with the compromised credential.
- Replace static credentials with instance roles or workload identity going forward.
01Understand what was exposed
The impact depends on which file was exposed and what permissions that credential carries. Here are the most common cases:
- GCP
serviceAccountKey.json— a downloaded JSON key file for a GCP service account. Contains the private key used to sign requests. If the service account has broad roles (Editor, Owner, roles/storage.admin), an attacker can read all your GCS buckets, query BigQuery, interact with Compute Engine, and more. - AWS
~/.aws/credentials— contains one or more access key ID / secret access key pairs. Permissions depend on what IAM policies are attached to the corresponding user or role. - Firebase
google-services.jsonorfirebase.json— Firebase client-side config files may contain API keys and project identifiers. While these are less sensitive than service account keys, exposed Firebase Realtime Database or Firestore rules without proper authentication can lead to data exposure. - Azure Service Principal credentials — a JSON file with
clientId,clientSecret,tenantId— full authentication for an Azure service principal.
GitHub watches for and automatically revokes some cloud credentials (AWS keys in particular) when they're committed. But public web server exposure bypasses this protection entirely — those automated systems only watch git pushes.
02Revoke the credentials immediately
Each cloud provider has a different revocation path:
# list keys for the service account gcloud iam service-accounts keys list \ --iam-account=my-sa@my-project.iam.gserviceaccount.com # delete the specific key gcloud iam service-accounts keys delete KEY_ID \ --iam-account=my-sa@my-project.iam.gserviceaccount.com
# deactivate first (preserve evidence) aws iam update-access-key \ --access-key-id AKIAIOSFODNN7EXAMPLE \ --status Inactive # then delete aws iam delete-access-key \ --access-key-id AKIAIOSFODNN7EXAMPLE
For Azure, delete the client secret in Azure Active Directory under App Registrations > the relevant app > Certificates & secrets.
03Create replacement credentials with minimal permissions
When creating replacement credentials, take the opportunity to apply the principle of least privilege — give the new credential only the permissions the application actually needs:
# create a new key for the service account gcloud iam service-accounts keys create new-key.json \ --iam-account=my-sa@my-project.iam.gserviceaccount.com # verify the service account's roles are minimal gcloud projects get-iam-policy my-project \ --flatten="bindings[].members" \ --filter="bindings.members:my-sa@my-project.iam.gserviceaccount.com"
Store the new credential securely — not in the web root, not in a repository. Use environment variables, a secrets manager, or your cloud platform's native secret store.
04Review cloud audit logs for unauthorised activity
Determine the exposure window and look for API calls made with the compromised credential during that period:
# query Cloud Audit Logs for the service account's activity
gcloud logging read \
'protoPayload.authenticationInfo.principalEmail="my-sa@my-project.iam.gserviceaccount.com"' \
--limit=100 \
--format="table(timestamp,protoPayload.methodName,protoPayload.requestMetadata.callerIp)"
Look for: data reads from storage buckets you didn't authorise, API calls from unusual geographic regions, resource creation (VM instances, storage buckets, IAM policies), and any calls to IAM methods that might indicate an attempt to create persistent access.
05Replace static credentials with instance roles or workload identity
Static credential files are an anti-pattern for cloud-native applications. Every major cloud platform provides a way to authenticate without storing a credential file:
- AWS — use EC2 Instance Profiles or ECS Task Roles. The SDK automatically uses the instance metadata service to get temporary credentials. No credential file needed.
- GCP — use the default service account attached to a Compute Engine instance or GKE node pool. Code running on GCP doesn't need a key file — the metadata server provides tokens automatically.
- Kubernetes — use Workload Identity (GKE) or IAM Roles for Service Accounts (EKS) to bind Kubernetes service accounts to cloud IAM roles without any key files.
- GitHub Actions — use OIDC federation to authenticate to AWS or GCP without storing any static secret in the repository at all.
If you must use static credentials (e.g., for local development), store them in the platform's native credential store (~/.aws/credentials with restricted permissions, not in the project directory) and ensure the directory is in .gitignore and excluded from deployment.
Was this guide useful?
These playbooks are free to read and share. If a heads-up ever saved you a bad week, you can say thanks — or jump into the other guides.