Product

Secrets Detection Automation: From Valid-Key Alert to Revoked and Rotated

GitGuardian finds the valid key in minutes; revoking and rotating it takes days. Part three shows CloudThinker reading both GitGuardian and the cloud account the key opens, measuring blast radius, and running rotate, redeploy, revoke and verify with approval on every step.

8 min read
Cover Image for Secrets Detection Automation: From Valid-Key Alert to Revoked and Rotated

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

GitGuardianGitGuardian

  • Secret incidentsValidity, severity, occurrences
  • Honeytoken eventsSource IP and user agent of each trip
  • RepositoriesWhere each secret was committed

Read-only token

02Response

CloudThinkerCloudThinker

  • 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

  • AWSAWSIAM identity and CloudTrail history
  • Google CloudGoogle CloudService accounts and audit logs
  • VaultVault or a secrets managerWhere the replacement is written

Writes granted separately

04Where the team works

Chat and tickets

  • SlackSlack or TeamsFindings and per-step approvals
  • JiraOwner and evidence on every incident
  • PagerDutyPagerDutyHoneytoken trips page immediately

Nothing new to watch

GitGuardian finds the secret. The response happens where the credential lives, so the agent reads both.

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.

Step three is the one GitGuardian can't do alone: it needs the cloud account the key opens.

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:

ReadingWhat it predictsCheck
Sandbox key, unusedDev account, no recent useiam get-access-key-last-used
Production key, legitimate use onlyService principal, calls from your own egress IPs, the API calls the service always makesCloudTrail lookup-events by AccessKeyId since the commit
Production key, someone else using itCalls 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:

  1. Rotate first. Create a second access key for billing-export-svc with the same permissions, so the service never loses access.
  2. Redeploy. Write the new key into the secrets manager entry, the CI/CD variable and the running deployment's environment.
  3. Revoke. Deactivate the leaked key (aws iam update-access-key --status Inactive), watch for errors from the service, then delete it.
  4. Verify. Confirm the old key fails to authenticate, the new key works, and resolve the GitGuardian incident with secret_revoked: true and 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.

FindingDetailSeverity
Valid cloud keys, live7 incidents; AWS and GCP keys still authenticatingCritical
Honeytoken trip1 decoy AWS key used from an unfamiliar IP 3 days agoCritical
Valid keys, non-prod12 incidents in dev and staging repos, still validHigh
High-blast-radius principal1 leaked key maps to a principal with broad S3 readHigh
Stale or invalid secrets~180 incidents, keys already dead; cleanup, not responseLow
Unassigned open incidents240 total open, 0 with a named ownerMedium
Honeytokens planted4 active decoys; 2 repos with no coverageMedium

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 scriptsWith CloudThinker on top
When a valid key leaksAn incident and a Slack messageA finding with principal, permissions and calls since the leak
Blast radiusWorked out by hand in the cloud consoleRead from IAM and CloudTrail, attached to the incident
Honeytoken tripsA page with an IP addressA page with the IP and everything else it touched
Revoke and rotateA human sprint across three systemsAn ordered plan, approved per step
The backlogGrows until someone budgets a cleanupTriaged 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.

gitguardiansecuritysecretsleakedcredentialsaiagentcloudthinker