Treat every OIDC client_secret as a privileged credential, not a configuration value. Store it in a managed secrets system, keep it out of source control and logs, and remove it from any browser-facing code. If the application is a native app or SPA, use PKCE instead of a static secret.
How to think about an OIDC client secret in production
An OIDC client_secret is not a harmless app setting. It is the secret that proves a client is entitled to act as that client, so production handling should follow the same discipline used for any privileged credential. The core questions are where it is stored, who can read it, how it is injected at runtime, and whether the app type should be using it at all.
For confidential clients, the secret belongs in a managed secrets system and should only reach the runtime through controlled injection. Keep it out of source control, build artifacts, chat, tickets, and logs, and make sure no browser-delivered code can expose it. If the app is public, such as a SPA or native app, the safer answer is usually to avoid a static client secret and use PKCE with the appropriate OIDC flow.
That distinction matters because OIDC client type drives the security model. A client secret can be reasonable for a backend service that can keep a credential private, but it is a poor fit for software that ships to an end user’s device or runs in the browser. When teams blur that boundary, they turn an authentication control into a reusable secret that is easy to copy, replay, and abuse.
Why secret placement and client type matter
The main failure mode is simple: once a client secret is embedded in code or delivered to the browser, it stops being a secret. At that point, anyone who can inspect the app package, intercept runtime traffic, or read front-end code may recover it. If the secret is also long-lived, the exposure window is even worse because there is no natural expiry forcing rotation.
Backend and service-to-service patterns are different. A server-side OIDC client can keep a secret off the user path, but the surrounding system still needs vaulting, access control, rotation, and monitoring. NHIMG’s Machine-to-Machine OAuth (Client Credentials) Guide is useful here because it focuses on securing client credentials for service authentication, including how to think about secret handling, binding, and validation.
For teams that want a broader reference point, the OIDC and OAuth model itself is worth revisiting. The client secret is part of the trust relationship between the client and the authorization server, and the exact flow should determine whether that trust can be represented safely by a shared secret or should move to a stronger mechanism such as PKCE, private key JWT, or mutual TLS. NHIMG’s OAuth 2.0 and OpenID Connect Guide for Identity Teams is a useful companion for that decision.
When you need a secret-free pattern for public clients, use the browser and native-app guidance already built into the standards. The key practitioner judgement is not “can we hide the secret well enough,” but “does this client type have a defensible place to keep one at all?”
What secure handling looks like in practice
Secure handling starts with minimizing where the secret exists. Store it in a managed secrets system, grant read access only to the runtime that needs it, and prefer short-lived delivery into memory over hardcoded configuration. If the application is part of a larger service estate, treat the secret as one piece of the broader credential lifecycle, not as a one-off deployment variable.
Operationally, the secret should be excluded from repositories, images, CI output, exception traces, analytics events, and support bundles. If a secret has already reached a browser bundle, client app package, or public repo, assume exposure and rotate it rather than trying to prove whether it was misused. NHIMG’s Secrets Management Guide is the best fit for the broader control pattern, while the Secret Sprawl Challenge is useful for understanding how hardcoded credentials and pipeline leakage create persistent exposure.
For readers who want a vendor-neutral standard reference, the OAuth base specification and the OIDC core spec both reinforce the client’s role in the protocol. The most relevant point is not the label of the secret, but the trust boundary it represents. If the boundary cannot be enforced by the client environment, the design should change rather than the secret-handling process being stretched to fit.
Risk and Threat Considerations
The biggest risk is credential reuse after disclosure. A leaked OIDC client secret can let an attacker impersonate the client, request tokens, and pivot into whatever APIs or user data the client is allowed to access. The exposure can be accidental, through logs or front-end code, or deliberate, through source theft or environment compromise.
Failure mechanism: Shared secrets in public or broadly distributed clients are easy to extract, and long-lived secrets often remain valid long after the original leak.
Impact: Attackers may obtain unauthorized token issuance, application impersonation, and downstream access to protected APIs or tenant resources until the secret is rotated and any exposed sessions or tokens are addressed.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP Non-Human Identity Top 10 addresses the attack and risk surface, while NIST SP 800-53 Rev 5 and OWASP ASVS set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP Non-Human Identity Top 10 | NHI-02 — Secret Leakage | OIDC client secrets are privileged secrets that must not leak into code, logs or browsers. |
| NHI-07 — Long-Lived Secrets | Static OIDC client secrets create persistent exposure if they are not rotated or replaced. | |
| NHI-10 — Human Use of NHI | Browser-facing or user-shipped apps should not depend on secrets humans can inspect or reuse. | |
| Recommendation — Store OIDC client secrets in a managed secret store and prevent exposure in code, logs and client bundles. Replace static client secrets with short-lived or rotated credentials wherever the client model allows. Avoid putting OIDC client secrets in browser or user-distributed code; use PKCE for public clients. | ||
| NIST SP 800-53 Rev 5 | IA-5 — Authenticator Management | Client secrets are authenticators whose issuance, storage, rotation and revocation need lifecycle control. |
| IA-9 — Service Identification and Authentication | OIDC client secrets authenticate services and other non-human clients to an authorization server. | |
| IA-2 — Identification and Authentication (Organizational Users) | The same secret handling discipline supports authenticated access to production admin paths and related tooling. | |
| Recommendation — Manage OIDC client secrets through controlled issuance, rotation and revocation processes. Use service authentication controls that keep client credentials private to the runtime and protected in storage. Restrict secret access to authenticated operators and administrative processes only. | ||
| OWASP ASVS | V10 OAuth and OIDC — OAuth and OIDC | The question is specifically about secure OIDC client handling and public-client flow selection. |
| V13 Configuration — Configuration | Secret placement, build-time exposure and runtime injection are configuration issues for production apps. | |
| Recommendation — Apply OIDC client-type requirements so public apps use PKCE instead of a static secret. Keep client secrets out of configuration sources that can be shipped, logged or disclosed. | ||
Practitioner Guidance
What to verify: Confirm whether the app is truly a confidential client before approving a client secret. If the runtime is browser-facing, mobile, desktop, or otherwise user-distributed, treat static secret use as a design defect and move to PKCE or another client-appropriate method.
Decision rule: If the secret can reach source control, logs, support tooling, or a user-controlled runtime, assume it is already too exposed to keep unchanged. Rotate first, then fix the storage and delivery path.
What good looks like: The secret exists only in a managed store, is injected only at runtime, has tightly scoped read access, and can be rotated without editing application code.
Practitioner takeaway: The safe pattern is to keep OIDC client secrets server-side, short-lived in practice, and invisible to users, if the application cannot meet that bar, the correct fix is usually to remove the secret from the design, not to protect it harder.
Related resources from NHI Mgmt Group
- How should security teams implement Client ID Metadata Documents?
- How should security teams handle exposed secrets without breaking production?
- How should security teams handle AI client access to governed data without shared secrets?
- How should security teams handle workload authentication without relying on client secrets?
Deepen Your Knowledge
Free weekly newsletter
Subscribe to the NHI & AI Identity Journal
The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.
Bonus 33% off our NHI Course when you subscribe.
Reviewed and updated by the NHIMG editorial team on October 31, 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org