Secrets Detection Automation: From Valid-Key Alert to Revoked and Rotated
GitGuardian tells you a valid AWS key is sitting in a repository at 09:14. At most teams, that key isn't revoked, rotated and redeployed until sometime the following week, if it happens at all. Detection is instant. Response is a multi-day human sprint that competes with everything else on the board, and every hour of that gap is an hour someone who cloned the repo can use the key.
Secrets detection automation is half a control if the other half, the revoke, rotate and redeploy loop, still runs at human speed. This is part three of our GitGuardian series. Part one covered why secrets keep landing in repos and why deletion isn't remediation. Part two wired ggshield into CI, drove the incidents workflow, queried the GitGuardian API by hand, and closed on the ceiling every DIY setup hits: detection and workflow automate cleanly, but the response across your cloud stays manual.
This part closes that gap with CloudThinker's security agent. It watches new incidents and honeytoken trips over a read-only token, triages by validity and blast radius, and executes the remediation plan step by step under your approval. GitGuardian stays your detection layer. CloudThinker is the response layer on top.
Why response, not detection, is the bottleneck
Part two got the detection layer to a good place: pre-commit hooks, CI scanning, the incidents API, honeytokens planted. What none of it automates is the work that stops the breach.
A single valid key starts a chain across systems GitGuardian can't see. Identify which cloud account the key opens. Find out what it has already accessed. Revoke it without breaking the service that legitimately uses it. Mint a replacement, push it into every consumer (secrets manager, CI variables, running deployments), and prove the old key is dead. That's four or five tools, two or three teams, and a change window. Multiply it by a backlog of a few hundred open incidents and the reason valid keys sit live for days is obvious. It isn't that nobody noticed.
The traditional fixes don't change that shape:
- Playbooks route and auto-resolve, but they act on GitGuardian's own data. They can't see your IAM, so they can't tell a sandbox key from a billing-account key.
- A scheduled valid-key query finds the incident faster. A person still does every step after it.
- A rotation script handles the one credential type it was written for. Leaks don't arrive in one type.
So the posture you want isn't "detect faster." It's a blast-radius-aware response loop attached to every valid incident and every honeytoken trip, running continuously.
Connecting GitGuardian: read-only, about five minutes
01Detection
GitGuardian
- Secret incidentsValidity, severity, occurrences
- Honeytoken eventsSource IP and user agent of each trip
- RepositoriesWhere each secret was committed
Read-only token
02Response
CloudThinker
- Triage continuouslyValidity first, honeytokens skip the queue
- Measure blast radiusPrincipal, permissions, calls since the leak
- Plan and executeRevoke, rotate, redeploy, verify
Writes go through Auto Mode
03Where keys live
Cloud and secrets
AWSIAM identity and CloudTrail history
Google CloudService accounts and audit logs
Vault or a secrets managerWhere the replacement is written
Writes granted separately
04Where the team works
Chat and tickets
Slack or TeamsFindings and per-step approvals
- JiraOwner and evidence on every incident
PagerDutyHoneytoken trips page immediately
Nothing new to watch
CloudThinker connects to GitGuardian with a personal access token scoped to read: incidents:read, honeytokens:read and the audit scopes. It's the same kind of token you created in part two, minus every write scope. It can't resolve, ignore or change incidents, and no cloud credentials are bundled in. Generate the token under API → Personal access tokens, paste it in, and the first sync pulls your open incident backlog. The GitGuardian connection guide has the exact scope list, so your security review can see what's granted before anything connects.
Blast radius needs the other side too. CloudThinker reads IAM and audit history through your existing read-only cloud connection. Write access (deactivating a key, writing a secret) is a separate, scoped grant, and only if you want approval-gated remediation at all.
Two streams, treated differently
Once connected, CloudThinker reads the same endpoints you scripted in part two (GET /v1/incidents/secrets and GET /v1/honeytokens) continuously instead of when someone remembers to run the curl.
- New secret incidents land in a triage queue, ordered by validity and severity, not by arrival time.
- Honeytoken trips skip the queue. A detection means a secret might be exposed. A trip means someone acted on stolen access. Trips escalate immediately, carrying the source IP and user agent from the trip event as the first evidence.
The point is cadence. A key that leaks at 09:14 is in triage at 09:14, not the next time an engineer runs the report.
One incident, end to end
01Signal
Incident opens
A new secret incident or honeytoken trip, picked up as it lands.
02Cut
Validity
Dead keys go to cleanup. Live keys move forward.
03Evidence
Blast radius
Which principal, what it can reach, and what it has called since the commit.
04Plan
Ordered steps
Revoke, rotate, redeploy, verify, each with its exact call and rollback.
05Close
Verified
Old key fails, new key works, incident resolved with evidence.
Here's the 09:14 incident worked the way the agent works it. The incident: an AWS access key, valid, critical severity, committed to billing-export in a config file.
Validity, confirmed. GitGuardian already says the key authenticates. The agent re-checks at the provider, because validity can flip between the scan and the response, and a key someone rotated an hour ago changes the whole plan.
Three readings. Before touching anything, it names what the key could be, and what each reading predicts:
| Reading | What it predicts | Check |
|---|---|---|
| Sandbox key, unused | Dev account, no recent use | iam get-access-key-last-used |
| Production key, legitimate use only | Service principal, calls from your own egress IPs, the API calls the service always makes | CloudTrail lookup-events by AccessKeyId since the commit |
| Production key, someone else using it | Calls from unfamiliar IPs, or calls the service never makes (ListBuckets, GetCallerIdentity from a new address) | Same CloudTrail query, grouped by source IP and event name |
What came back. The principal is billing-export-svc in the production account, with s3:GetObject on the billing export bucket. CloudTrail shows about 40 GetObject calls since the commit, all from the service's own NAT gateway, plus one GetCallerIdentity from an IP outside your ranges two days ago. That rules out the sandbox reading and leaves the third one live. The finding says so plainly: a production key with read access to billing data, one unexplained identity check from an unknown address, legitimate traffic that will break if the key is cut without a replacement.
That's the difference between a routine rotation and an incident that needs a security lead's attention, and it's the step GitGuardian alone can't take.
The plan. For each valid incident the agent drafts the response as an ordered, reviewable plan, not a single button:
- Rotate first. Create a second access key for
billing-export-svcwith the same permissions, so the service never loses access. - Redeploy. Write the new key into the secrets manager entry, the CI/CD variable and the running deployment's environment.
- Revoke. Deactivate the leaked key (
aws iam update-access-key --status Inactive), watch for errors from the service, then delete it. - Verify. Confirm the old key fails to authenticate, the new key works, and resolve the GitGuardian incident with
secret_revoked: trueand the evidence attached.
Each step names the exact resource, the exact call and a rollback note. Nothing executes on its own.
You decide what runs on its own
CloudThinker acts within Auto Mode, so you decide what runs on its own and what waits for approval. Reads (incidents, IAM, CloudTrail) never change anything. For secrets, approval can go step by step: the rotation, then the redeploy targets, then the revoke.
Every proposal, approval and executed step lands in the audit trail: incident, evidence, planned call, approver, timestamp.
What a first sync typically surfaces
The numbers below are illustrative, a composite first sync for a mid-market SaaS org with a couple of years of accumulated incidents. Yours will differ.
| Finding | Detail | Severity |
|---|---|---|
| Valid cloud keys, live | 7 incidents; AWS and GCP keys still authenticating | Critical |
| Honeytoken trip | 1 decoy AWS key used from an unfamiliar IP 3 days ago | Critical |
| Valid keys, non-prod | 12 incidents in dev and staging repos, still valid | High |
| High-blast-radius principal | 1 leaked key maps to a principal with broad S3 read | High |
| Stale or invalid secrets | ~180 incidents, keys already dead; cleanup, not response | Low |
| Unassigned open incidents | 240 total open, 0 with a named owner | Medium |
| Honeytokens planted | 4 active decoys; 2 repos with no coverage | Medium |
The shape is typical: a handful of live keys buried in a backlog of dead ones, one honeytoken trip worth more than the other 239 findings combined, and a backlog with no owners, which is how the live keys stayed live.
Why this beats the traditional approach
| Native tooling and scripts | With CloudThinker on top | |
|---|---|---|
| When a valid key leaks | An incident and a Slack message | A finding with principal, permissions and calls since the leak |
| Blast radius | Worked out by hand in the cloud console | Read from IAM and CloudTrail, attached to the incident |
| Honeytoken trips | A page with an IP address | A page with the IP and everything else it touched |
| Revoke and rotate | A human sprint across three systems | An ordered plan, approved per step |
| The backlog | Grows until someone budgets a cleanup | Triaged continuously, owners assigned |
The deeper difference is where the work stops. Native tooling stops at the edge of GitGuardian's own data. The response to a leaked secret happens in the account the secret opens, so the useful layer is the one that reads both sides and writes nothing without a person saying yes.
Prompts to try in your first session
CloudThinker is conversational. Ask in plain language, and each answer cites the evidence (the GitGuardian incident, the resolved IAM principal, the API-call timeline) so you verify rather than trust:
"List every valid secret incident, and for each live cloud key tell me which account it opens and what it has accessed since the leak."
"A honeytoken just tripped. Show me the source IP, what it tried, and everything else that IP has touched in our accounts."
"Draft the rotate, redeploy, revoke and verify plan for incident 12345. Hold for my approval on each step."
What the agent won't do
- It won't revoke, rotate or redeploy without approval. Every write needs explicitly granted write access and goes through Auto Mode.
- It won't resolve or ignore GitGuardian incidents on its own. The read-only token can't, and closing an incident stays a human decision tied to a verified fix.
- It won't act outside the audit trail. Every finding, plan, approval and executed call is logged with evidence and approver.
- It won't decide whether a leak is a reportable breach. It can show a key was live and used against your data. Whether that triggers a customer notification stays with your team.
From alert to closed loop
You know why secrets keep landing in repos, and you know how to detect and triage them with GitGuardian's native tooling. The gap left is the one this post opened with: detection is instant, response takes days, and the backlog wins. With a read-only agent on the incident and honeytoken streams, a valid key becomes a drafted, blast-radius-aware, approval-gated response the same hour it leaks, and a honeytoken trip becomes an immediate page with the access evidence attached.
Try CloudThinker free with 100 premium credits and no card required, connect GitGuardian read-only via the connection guide, and see your own incident backlog triaged by validity and blast radius within the hour.
