
A subcontractor's build created a credential. An API key, a token, a cloud user, a webhook secret, a password sitting in a file. Tonight, three things, and you do them in an account you or the client administer. List that credential, including where it was written down. Revoke it, or rotate it, without asking the person who created it. Then prove the old value fails: a call that used it is rejected, and you have written where a copy of the old value might still sit. If the list, the revoke, or the proof requires the partner's laptop, the credential is still theirs. Your name is on the product.
This is the secret the build minted after it was let in. It is not the decision, on day one, of which human may enter which system. That decision — one account per person, a register, an expiry — is what access to give a subcontractor. A clean register of people can sit next to a key the pipeline created, hardcoded, with no owner and no expiry. The register will not show it, because it is not a person. It is also not the afternoon you decide whether a new vendor may read the client's text. Before a tool reads the client's text is the account you open before the first document is sent. A key already committed to the repository is the document that already left. None of this is a finding that a federal control catalogue applies to a commercial agency. The blanks in the control are the point. The shape of the duty is what transfers.
NIST SP 800-53 Rev. 5, September 2020, updated 10 December 2020, control IA-5, says to manage system authenticators. The clause that matters tonight is (d): establish and implement administrative procedures "for initial authenticator distribution, for lost or compromised or damaged authenticators, and for revoking authenticators." The discussion names what an authenticator is: "passwords, cryptographic devices, biometrics, certificates, one-time password devices, and ID badges," and "device authenticators include certificates and passwords." It then says the quiet part about how software arrives: "Developers may deliver system components with factory default authentication credentials (i.e., passwords) to allow for initial installation and configuration. Default authentication credentials are often well known, easily discoverable, and present a significant risk." And, later in the same discussion: "Authenticator management includes issuing and revoking authenticators for temporary access when no longer needed" (NIST, SP 800-53 Rev. 5). A key created so a deploy could finish is temporary access. The procedure for revoking it is the agency's to write. NIST does not name your client's cloud, and it does not fill in the time period in IA-5(f), which is an assignment: change or refresh authenticators on an organization-defined interval or when organization-defined events occur. If the only interval anyone can quote is "when the partner remembers," you have not made the assignment. You have left it blank.
The enhancement that matches a secret in a repository is IA-5(7). "Ensure that unencrypted static authenticators are not embedded in applications or other forms of static storage." The discussion is short and it is the whole test: "In addition to applications, other forms of static storage include access scripts and function keys. Organizations exercise caution when determining whether embedded or stored authenticators are in encrypted or unencrypted form. If authenticators are used in the manner stored, then those representations are considered unencrypted authenticators." A token that the program reads out of the file and sends as the credential is being used in the manner stored. Calling the file "config" does not encrypt it. A secrets manager you never wired up, mentioned in a comment above the hardcoded value, does not encrypt it either. IA-5(5) is the delivery rule beside it: require developers and installers "to provide unique authenticators or change default authenticators prior to delivery and installation." The discussion says this extends the install-time change "by requiring developers and/or installers to provide unique authenticators or change default authenticators for system components prior to delivery and/or installation." On a subcontract, the installer is the partner. Prior to delivery means before the change ships under your name, which is the same afternoon as reading their change before it ships. A diff you did not open can be the place the static authenticator is embedded.
How often those values leak, and how long they keep working, is measured by a company that sells the detection. GitGuardian's State of Secrets Sprawl 2025 says: "In 2024, we found 23,770,171 new hardcoded secrets added to public GitHub repositories. This figure represents a 25% surge in the total number of secrets from the previous year." On generic secrets, the same report: "In 2024, 58% of all detected secrets were generic, a jump from 49% in 2023." Generic, in their definition on that page, includes hardcoded passwords, database connection strings, custom authentication tokens, and encryption keys stored in plaintext — the values that do not match a known vendor pattern (GitGuardian, State of Secrets Sprawl 2025). 23,770,171 is a count of secrets they detected in public commits, not a count of agencies, and not a count of keys in your client's account. 58% is a share of detected secrets, not a share of repositories. 25% is the year-over-year change in that count. GitGuardian sells secrets detection and describes itself as the most-installed application on the GitHub Marketplace. That description is theirs.
The private-repository comparison is a different denominator, and the report says so. "This year, we compared our findings from public GitHub with anonymized customer data." The section is titled as private repositories being 8 times more likely to contain secrets. The shares the report prints are 4.6% of public repositories containing a secret, and 35% of private repositories containing hardcoded secrets. Thirty-five divided by 4.6 is not the integer 8. Quote the two shares, and treat the title as their label for the comparison, not as a third measurement. The 35% sits on anonymized customer data, so it is not a census of every private repository on GitHub. A narrower cut in the same section: AWS IAM keys "appear as plaintext in 8% of the private repos we researched but appear in only 1.5% of public repos." Eight and 1.5 are those key types in the repos they researched. They are not a probability that your partner's pull request contains an AWS key. MongoDB credentials, a different type, are 18.8% of detected secrets in public repositories and 3.9% in private ones. A type that dominates public leaks is not the type that dominates the customer set. Read the row you are quoting.
Two further figures are about secrets that stayed valid, and about a sample of repositories where an editor extension was configured. "70% of valid secrets detected in public repositories in 2022 remain active today." That sentence is 2022, public, and only the secrets that were valid when detected. A nearby sentence says an analysis of over 115,000 initially valid secrets found that "a significant number remain active long after their initial detection." "A significant number" is not the 70%, and the report does not print 70% of 115,000. Do not multiply them. On Copilot, the report says a sample of approximately 20,000 repositories where Copilot was allowed and active included over 1,200 that leaked at least one secret, "6.4% of the sampled repositories," and that this incidence "is 40% higher than what we observe across all public repositories, which stands at 4.6%." The appendix names the sample as 19,151 public repositories, selected because a dev-container configuration listed the GitHub Copilot extension. Approximately 20,000 and 19,151 are the same study described two ways. The 40% is their description of 6.4 against 4.6, not a separate experiment. The selection is an extension named in a config file, not a list of everyone who used the product. It is not your partner's laptop, and it is not a finding that a coding assistant caused a key you have not looked for.
A vault does not close the list. The report examined 2,584 public repositories whose CI configuration indicated a secrets manager was available. 132 "had leaked at least one secret in 2024, representing 5.1% of the studied repositories." It then says the numbers "are not directly comparable" with the overall public rate, because repositories that use a secrets manager "are more likely to handle sensitive information," while many public repositories never deal with secrets at all. 5.1% is 132 out of that 2,584. It is not evidence that a secrets manager increases leaks, and it is not evidence that naming a vault in CI means the key in the pull request was stored there. On permissions of leaked tokens they examined, the report prints 99% of GitLab API keys with either full access (58%) or read-only access (41%), and 96% of GitHub tokens with write access, 95% of them full repository access. Those are shares of the leaked tokens in that analysis. They are not shares of every token your client has issued. What you take from the set is smaller. A credential can be old, valid, and broader than the job that needed it. None of those three is something you learn by asking the partner if they were careful.
Do the three proofs against one credential you can point at, not against the idea of secrets. First, the list. In the cloud account, the CI project, and the repository the client owns, you can see the key, the token, or the user the build added. You can name the file and the line, or the console page. A partner who says "it's in our one-password" has described their vault. You have not listed the credential until you have opened the place it is used. Second, the revoke. You disable or rotate it from the account you administer. IA-5(d)'s procedure is this action, written down: who may revoke, and the event that requires it. A deploy that fails because you rotated the key is a successful test of the wrong system. The product has to keep running on the new value, which means the running system reads the value from somewhere you can change. Third, the proof. A request that still presents the old value is rejected. You have tried it. And you have a line for the copies: the CI log that printed it, the chat where someone pasted it, the laptop you cannot search. If the third line says "unknown," the old value is not retired. It is retired in the one place you checked.
Three moves that look like revocation and leave the old value working. Minting a second key beside the first, so the invoice has a new name and the leaked one still authenticates. Deleting the line in the repository and force-pushing, which hides the file and leaves the credential valid at the vendor until you revoke it there. Asking the partner to "rotate when they can," which is the assignment blank, still blank. The model-vendor organization — the workspace that holds production keys and the setting for whether prompts are kept — is a different root, and it is what to keep when you subcontract AI. A key the application uses to call that vendor is this article. Both can be true on the same afternoon, and revoking one does not revoke the other. Agency engagements of this kind sit under the non-disclosure we would sign with a client, so they are not on this site as case studies. A case study is the wrong shape for a secret anyway. The proof is a rejected call, and a rejected call does not belong in a portfolio.
There is a version of this where hiring the revoke path is the wrong purchase. The work is not sold, so there is no client account and no credential a build could have minted. The client asked to meet the people who will write the code, and the conversation you are in is that introduction, not a leaked key. The room only has a slide. Or the buyer wants a template policy and does not have a repository to open. A policy that names IA-5 and has never listed a key is a brochure. The criteria for choosing a firm, when that is the actual decision, are the ones on the page for a top saas development company. They do not rank anyone, including us.
When the build has already created a credential you cannot see, the missing object is specific. An account you administer, a list of the values the build added, and a revoke you can perform while the partner is offline. A white label software development partner that expects this will put the cloud account and the repository in the client's organization, or in yours, before the first deploy, because a key created in an account you cannot open cannot be revoked by the person whose name is on the invoice. One that can only rotate secrets from a laptop it takes home is telling you who the vendor will call. Where the next slice is one capability and the acceptance sentence names the credential, an AI integration sprint is the shape that can require the three proofs as the definition of done. Where you are not sure which accounts the current engagements already depend on, a two-week AI readiness assessment maps systems and security before anyone scopes a rebuild. The findings are yours. They are not a promise that a leaked-secret rate applies to you, and they are not a rate.
Before you tell the client the environment is locked, do the three proofs on one real credential. List it where it lives. Revoke it without the person who minted it. Show that the old value fails, and write the copies you could not search. A key you cannot name is still a way in. The screen that says the deploy is green does not say who else can still call.
Find this useful? Tell Google to show you more of it.
