Quality and Security

Secrets and Credentials: Grant Access You Can Limit and Revoke

How to grant access through secrets and credentials that can be narrowed, observed, rotated and revoked, and what to do step by step when a secret leaks…

Chapter 53Quality and Security

A password, an application key and a temporary token are not just strings to be hidden. They are proofs on the strength of which a system accepts a particular identity and may permit specific actions. Handling them safely covers the whole cycle: who received access and why, where the values travel and where they are stored, how to detect a leak, how to replace or revoke them, and how to confirm that the old access is no longer in use.

After this unit the reader can:

  • distinguish identity, authentication and authorisation;
  • explain the difference between configuration and a secret, and understand why a .env file protects nothing on its own;
  • narrow the permissions, lifetime and environment of a credential, especially when an agent is the one asking for access;
  • describe the limits of protection offered by Git, logs, masking and pipeline secrets;
  • lay out the separate steps of storage, rotation, revocation and leak response;
  • verify that a replacement worked without revealing the key's value.

Here a secret means a value or material whose possession lets someone pass a check or obtain a privilege: for example, a password, an application programming interface (API) key, a token or a private key. Credentials are the proofs a system uses to confirm an identity or a right of access. All examples and key names in this unit are made up; no real secret is needed for learning. The exact capabilities of products depend on the specific service, account type and configuration.

Who is calling, how they prove it, and what they may do

Identity answers the question "who or what is making the request?": a person, an application, a service account or a workload. Authentication is checking the proof of that identity. Authorisation is the decision about which actions on which resources are permitted once the check has passed. Holding a valid token does not prove that its owner needs access to every action or every object.

A secret can be one of these proofs, but their properties differ. A password usually verifies a person and may come with accompanying sign-in rules. An API key gives a program a way to call a service; it may be tied to a user, a project or a service identity. An access token is often intended for a limited lifetime or set of actions, and a refresh token can obtain a new access token. A private key proves possession of a cryptographic key pair. None of these names, on its own, guarantees a short lifetime, narrow permissions, safe storage or automatic revocation.

When assessing a credential, establish each of the following separately:

Question What to record
Who is calling? A person, a service, an agent or a specific workload; who owns it and who is responsible for replacing it
For what? The one action needed and the resource it is performed on
What proof? A password, a static key, a temporary token, a certificate or a federated identity
How much access? Permitted actions, resources, environment, and whether it can read sensitive data
For how long? Lifetime, end condition, renewal method and review date
Where does it travel? Where it is created, stored, transmitted, used, logged and revoked
How do you verify a change? A safe signal of successful access, an audit log, a metric or a control request

Least privilege means granting only the actions and resources needed for a defined task, and reviewing access when the task is finished or changes. Read-only access can still expose private source code, personal data, configuration or a vulnerability. So "read-only" is a restriction on the kind of change, not a statement that the access is harmless.

Configuration describes how a program runs: for example, a service address or the name of an environment. A secret is a value whose compromise can grant access. A setting does not become a secret merely because of its variable name, and a secret does not stop being a secret because it was written into a settings file. A .env file is a common way to pass variables to a process during local development. It is not a secret store and does not encrypt its contents automatically. Environment variables can end up in child processes, debug output, a diagnostic snapshot or a log; the limits of their visibility depend on the host, process permissions and configuration. Do not print all environment variables for diagnostics. (See the terminal, the local environment and how programs run.)

OpenAI's documentation separately describes keys for the OpenAI API Platform specifically: a key must stay on the server side, and the API supports either a key or short-lived federated authentication where that has been configured. Anthropic's materials on the Claude API describe static keys, short-lived exchange through identity federation, and other methods for particular environments. These pages do not define how you sign in to ChatGPT, Codex or consumer Claude; do not carry the properties of one product over to another. For user keys on the OpenAI API Platform, the documentation offers All, Restricted or Read Only modes; managing service-account keys works differently. The Claude API distinguishes personal keys from service-account keys and lets you restrict a key to a workspace where needed. These are product-specific restriction mechanisms, not universal properties of keys. (OpenAI API: Authentication; OpenAI: Best Practices for API Key Safety; Anthropic: Claude API Authentication)

A storage location does not replace access restrictions

A secret should be kept in a place with controlled access, a log of who retrieved it, and a defined owner. For local development, that can be a developer's password manager or a controlled secret file excluded from commits. For a server, a secrets manager, the platform's credential store, or a mechanism that issues short-lived access. The concrete choice depends on the environment, the threat model and the team's ability to operate it. A "secrets manager" also needs narrow permissions, auditing and a recovery plan.

An environment variable can deliver a value from such a store to a program, but it does not determine who else reads the process memory, whether a child command inherits it, whether it lands in an error trace, or whether a container image preserves it. Choose the delivery mechanism together with the boundaries of the process, the logs and the host. Do not put a secret into command-line arguments, a Uniform Resource Locator (URL), an error message, a recorded example or a diagnostic dump if a safer way to pass it exists.

A short-lived credential or workload identity federation can reduce the number of long-lived keys: the system exchanges a trusted workload credential for a token with a limited lifetime. This removes the need to store a separate static key in that chain, but trust in the identity provider, the exchange rules and the permissions of the issued token all remain critical. A short lifetime does not compensate for excessive permissions, and federation does not automatically make a weak incoming credential safe. Support for and names of such mechanisms vary between products. The Open Worldwide Application Security Project (OWASP) describes secrets management as a full lifecycle, not just the choice of a store. (OWASP Secrets Management Cheat Sheet; Anthropic: Workload Identity Federation)

Separate credentials at least by environment and purpose: local development, testing and production must not quietly share one long-lived key. Define the owner, the permitted actions, the review or expiry date, the storage location, the consumers and the revocation procedure. Do not create untracked "spare" copies: unknown copies are hard to find after a leak.

Git stores history, not intent

A .gitignore file asks Git not to add a not-yet-tracked file to new changes. That rule does not remove a file that is already tracked, and it does not erase a secret from an earlier commit. Making a repository private does not revoke a key either, nor does it take copies away from people who had access. Clones, forks, archives, continuous integration/continuous delivery (CI/CD) logs, uploaded artefacts and caches can all hold separate copies.

When you find a secret in Git, do not paste it into a pull request (PR) comment, a tracker issue or a message to an agent "for confirmation". Instead of the value, record the type and owner of the credential, where it appeared, the approximate time, the scope of access and the steps already taken. If you need to identify one of several versions, use a controlled inventory or a fingerprint that does not reveal the secret itself.

The fix has to be split into two goals: stop the access and remove the copies. Deleting the line from the latest version or rewriting history does not cancel a secret that has already been copied. Editing history can reduce its visibility in the controlled repository, but forks, clones, caches and external copies may remain. If history cleanup is needed, plan it with the repository owner after revoking or replacing the active key, and check the consequences of rewriting for collaborators. (GitHub: Remediating a leaked secret)

An automation pipeline has its own trust boundaries

In CI/CD, secrets can be available to a job that does not need them, to a third-party extension step, to a log or to an artefact. Secrets management in GitHub Actions offers different storage levels — repository, environment and organisation — and lets you restrict environment secrets with rules. By default, a pull_request event from a fork does not receive ordinary secrets; this is not a universal guarantee for every event type and configuration. It is especially dangerous to run unreviewed code from a fork in a privileged event context such as pull_request_target or workflow_run, where the job may have secrets or write permission. Check the specific workflow and its chain of steps. (GitHub: Using secrets in GitHub Actions; GitHub: Secure use reference; GitHub: Securely using pull_request_target)

Log masking reduces accidental display; it is not an access boundary. The system can hide a known exact value but does not guarantee it will catch every transformation, splitting into pieces, encoding, or a leak through a side channel. GitHub explicitly warns that automatic log redaction is not complete protection; if a new derived representation of a secret is created, it may need its own masking, and even that does not replace isolating the step. A third party to which the workflow passed a secret can print it or send it over the network. Restrict secrets and write permission to specific automation jobs, review third-party actions and do not print values. (GitHub: Secure use reference; GitHub: Workflow commands)

Full case: a decoded value appeared in a log

A public notice from the Spotless maintainers in September 2026 described a leak in GitHub Actions logs. While the publishing system was being changed, a workflow decoded a stored value and wrote it to the GITHUB_ENV environment file. In the logs of subsequent steps, GitHub Actions displayed the value in group headers, including the password of a Sonatype/Maven Central token; the encoded value known to the masker did not match the decoded one. The maintainers also reported that during debugging they had temporarily removed the branch restriction on publishing. The logs were accessible for roughly 28 hours; after discovery, the team reported containment in roughly 25 minutes. Separately, they mentioned an encrypted release-signing subkey stored with GNU Privacy Guard (GPG); according to the maintainers, its passphrase and the master key did not leak. The team treated the token as copied, revoked and replaced it, removed the encoded values, paused publishing and checked the releases. This is a report by the project owners, not an independent forensic investigation. (Spotless, security notice #3089)

Decision and actions: treat an exposed secret as compromised; stop jobs that could print it again; revoke or replace the active credential; review logs and artefacts; check usage and access; then change the workflow so that it passes the value in the form the consumer expects, without printing it. Confirm that the replacement works, and only then resume publishing in the agreed order.

Observable result: the old key no longer authorises requests; the new key grants only the needed action; logs do not show the value; the owner has checked the access log and the status of releases. The case shows why protection must be tied to the flow of data rather than to a line in the masking settings: the transformation produced a different value. It does not prove that all CI tools share the same flaw, or that masking is useless.

GitHub Push Protection can block some supported secrets before they enter a repository, but its coverage and availability depend on the secret type and configuration. It is an additional barrier for Git, not proof that a log, an artefact, a third-party action or any other source contains no secret. (GitHub: Push protection)

An agent gets a tool and boundaries, not a password to "remember"

There is no need to give an agent a password in a prompt so that it "remembers" it, and a key should not be pasted into an example, a task message or a log. A Markdown instruction can ask the agent to protect a secret, but on its own it is not a technical access control. Control is set by the permissions of the environment, the tools, the account and the store. If an agent can call a tool that already has access, its actual capabilities are defined by that tool and by the permissions of the tool's identity. This extends the distinction between an instruction and a technical restriction covered in the instruction hierarchy and in the Model Context Protocol (MCP) for Claude.

Before giving an agent access, name the one action it needs, one resource, the environment and the time required. Prefer a narrow tool, a controlled request or a temporary identity over a broad long-lived key. Reading a private repository may be enough for the task, but it still exposes all the code it can reach and potentially sensitive data. After the task, remove the temporary permission and check the access log if the platform provides one. When access cannot be restricted or observed, do not consider a secret safe merely because it is not visible in the text of the conversation.

Full case: an admin token to read one repository

An agent asks for a personal token with organisation-admin rights in order to read one private repository. First clarify exactly which files and which operation it needs. If viewing the code is enough, set up a separate service identity, or another available mechanism, that can read only the target repository and grants neither write access nor organisation management. If the product does not support that kind of narrowing, use a controlled export of the needed files or a manual review, provided this fits the data policy.

Observable result: the agent reads the needed files, while a test attempt to change the repository or read another target resource is rejected; the log shows the expected identity. If the system allows only broader access, the owner documents the residual scope and either chooses a different route or consciously approves it through the organisation's process. "Read-only" does not mean "no risk": code, secrets in the repository and internal structure can also be sensitive. Exact permission names differ between systems, so do not substitute permission syntax you have not verified.

Rotation, revocation and recovery are different steps

Rotation is a managed move of consumers to new credentials. Revocation is ending the validity of the old ones. Recovery after a leak is a broader process that also covers determining the access and the copies, checking for abuse, removing the cause and monitoring after the replacement. Creating a new key, switching all consumers and revoking the old key are three different events. In some systems revocation does not take effect instantly; check the provider's actual behaviour.

For a planned rotation: list the consumers and owners, check the lifetime and permissions, create new credentials with the needed scope, place them in a controlled store, verify with a test or control request, switch the consumers, check metrics and logs, and then revoke the old credentials. Keep an unused old key under observation only for as long as policy and risk allow. Do not leave transitional access without an end date.

For a suspected leak, assume the secret may have been copied. Identify the key's owner and capabilities; revoke it or apply an emergency replacement following the provider's procedure; stop further printing; check usage logs and the scope of access; find the consumers and copies; create new credentials in a safe place; fix the source of the leak; and verify recovery. If keys must coexist for continuity, such an overlap period is acceptable only with an assessed threat, a strict deadline and usage monitoring. During an active attack, fast revocation may take priority over continuity.

There is no universal rotation period for every key. Risk, lifetime, observability and the cost of a wrongful revocation all differ; follow the rules of the system owner and the provider. OWASP recommends managing the full lifecycle of and access to secrets rather than relying on an arbitrary calendar interval. (OWASP Secrets Management Cheat Sheet; OpenAI: Best Practices for API Key Safety)

Read provider logs within their intended purpose

Usage signals and administrative event logs answer different questions. For the OpenAI API Platform, the Usage Dashboard shows API usage and costs, while the Audit Logs API records administrative and configuration events, including the key lifecycle; audit logging has to be enabled separately. OpenAI also notes that audit logs do not contain the content of API requests and responses, and that their retention period has no fixed guarantee; if you need a long-term history, export it to your own controlled store. (OpenAI: Reviewing API usage and costs; OpenAI: Admin and Audit Logs API)

For the Claude API, Claude Platform materials describe managing keys and organisation reports through the Admin API. For eligible organisations, the Compliance API provides an Activity Feed: a Claude Console Admin API key can read only that feed, while broader Compliance API access uses other key types and depends on the product and permissions. Exporting the audit log as CSV in Claude Enterprise settings is a separate feature. Do not assume that any API key opens a full log of requests or their text. Combine the provider's available signals with your own de-identified application logs, without recording authentication headers or request bodies unnecessarily. (Anthropic: Admin API; Anthropic: Compliance API)

Full case: a planned replacement of an import key

A daily background import from a supplier uses a long-lived read key. The owner has a list of the two workflows and the one backup environment where this key is stored. Before the replacement, the team checks whether the supplier can issue a separate key that reads only the needed dataset, and whether its use is logged.

The owner creates the new key, writes it to the store for the designated environment and runs one control import without displaying the request header or the key's value. When the check succeeds, the owner switches the main and backup workflows and watches the number of records received, authentication errors and the time of the last successful import. After the expected cycle has passed, the owner revokes the old key and checks that requests with the old access are rejected while those with the new one keep working.

Observable result: both workflows complete the import, the new data matches the expected count, use of the old key has stopped or is being rejected, and the old key is invalid. If the supplier allows only one key at a time, or the import cannot be verified in parallel, the team chooses an agreed maintenance window and a recovery plan. The "create — verify — switch — revoke" sequence reduces the risk of error but does not guarantee zero downtime for every service.

A complete response plan when a secret lands in a PR

Suppose an agent added a .env file containing a key to a branch and opened a PR. Do not repeat the value in a comment or report, do not ask the agent to hide it under a different name, and do not stop at deleting the file in the latest commit.

  1. Stop further spread. Through an approved private channel, notify the repository owner and the person responsible for the secret. Restrict access to the PR according to the response procedure. Stop automation or build jobs that could copy the file into logs or artefacts. Do not summarise the file's contents in a public comment.
  2. Determine what was exposed. Review the changes in a controlled way; establish the owner, purpose, permissions, environment, time, lifetime and every possible consumer. Do not test someone else's key by calling an external service without the owner's permission.
  3. End or replace the access. If the key is active, notify the owner and apply the revocation or emergency-replacement procedure. Set priorities by the permissions and the potential for abuse; the fact that the PR has not been merged does not make an exposed key safe.
  4. Find copies and usage. Check commit history, forks, clones, logs, artefacts, caches, notifications and local copies within the telemetry available. Review usage logs from the time of the first possible exposure, if the service provides them. The absence of an audit record does not prove the absence of access.
  5. Change the source. Remove the file from the current version, add the correct ignore rule, confirm that the file is no longer tracked, and move the active secret into the approved store. Delete artefacts and logs according to the platform's rules, without promising to erase copies that have already been downloaded.
  6. Clean history if needed. End the key's validity first. Agree on rewriting history with the repository owner, take forks and clones into account, warn collaborators and check the available copies. Cleanup reduces accidental further exposure but does not restore secrecy.
  7. Remove the cause and verify the result. Restrict the access of the agent and of automation steps, add a supported scanner or push protection for secrets, and review templates and instructions. Use a fake teaching value to check that the file and logs are rejected; never use a real key in a test.

Expected result: the old key no longer works; current consumers use a proper replacement, or the service has been stopped in a controlled way; the available usage logs and copies have been checked; the file is not added again; the owner knows what remains unknown. If the secret belongs to a third-party organisation or supplier, involve its owner through an agreed process. This list is a teaching response plan, not a substitute for an organisation's incident policy.

Summary

Protecting a secret means managing identity, permissions, the places it passes through and the lifetime of access. A .env file, a private repository, log masking or cleaned history do not revoke a key. Grant the minimum necessary permissions for a limited time, keep the value in a controlled place, do not hand it to an agent in a prompt, and split rotation into creating a replacement, verifying it, switching over and revoking the old access. After a leak, assume the secret has been copied, and check both the access and the copies you can reach.

Sources and further reading

Materials checked on 10 October 2026. Documentation for cloud and API products changes; before configuring anything, verify the account type, the current permissions and the documentation for your specific system.