Public vs. confidential clients and how to avoid common security pitfalls in identity
At the heart of any secure software system lies identity: the ability to know, manage, and control who or what is trying to access a resource, and whether they are authorized to do so. When architecting and deploying software, it’s important to consider identity and what role it serves in securing a system.
Identity is not only relevant for users, but also for devices, applications, and services that need to access or provide data and resources. Identifying and choosing the right authentication patterns and practices for networked systems can be a challenging task. In this blog post, I’ll explain the difference between public and confidential client types and the role they play in system security. I’ll also leave you with a few best practices that can help you avoid common security pitfalls.
Secrets and their importance in proving identity
A client is a software entity that has a unique identifier assigned by an identity provider. A client can be a web app, a mobile app, a service, or a daemon that requests access to protected resources from a server. For example, a web app that uses Microsoft Graph to access user data is a client. Clients acquire an identity through registration with an Identity Provider (IdP) such as Microsoft Entra ID or Active Directory Federation Services (AD FS). When examining the public or confidential nature of a given client, we are evaluating the ability of that client to “keep a secret”—to hold sensitive, identity proving information in such a way that it cannot be accessed or known to a user (or adversary) within the scope of its access and threat model.
Public clients cannot be trusted to safely keep application secrets. These are applications that can be downloaded and run on devices, such as desktop, wearable, mobile, or client-side browser apps. Any time the source or compiled bytecode of a given app is transmitted anywhere it can be read, disassembled, or otherwise inspected by untrusted parties, it is a public client.
Confidential clients can be trusted to keep secrets. These are apps that run on servers, such as backend-driven web apps, web APIs, or web services/daemons. The source code and compiled binaries for such clients are considered difficult to access by users or attackers and therefore we can trust that an application providing a client secret to assert its identity is presenting adequate proof of its identity.
Common types of public and confidential clients
|Public clients||Confidential clients|
|Desktop apps||Backend-driven web applications|
|Mobile apps||Web APIs|
|Wearable apps||Azure Functions|
|Single-page web applications||Web daemons and services|
|Headless and embedded apps (plugins, IoT**)|
|**With robust physical and hardware security, some IoT deployments could be classified as confidential clients.|
Common types of secrets
There are numerous types and ways that secrets can be employed to prove the identity of a client. Some common examples include:
Managed identities for Azure resources – For app-only authentication scenarios, application and service developers building on Azure have the option to offload secret management, rotation, and protection to the platform itself. With managed identities, identities are provided and deleted with Azure resources and no one, including the Global Administrator, can access the underlying credentials. The best way to prevent leaking secrets? Let managed identities handle it for you.
Client ID and secret – In this pattern, a pair of values is generated by the authorization server when registering a client. The client ID is a public value that identifies the application, while the client secret is a confidential value used to prove the identity of the application.
Proving possession of a certificate – Public Key Infrastructure (PKI), which includes standards such as X.509, is the fundamental technology that enables secure communication over the internet and forms the backbone of internet privacy. PKI is used to issue digital certificates that verify the identity of parties involved in online communication and is the underlying technology that powers protocols such as HTTPS, which is widely used to secure web traffic. Similarly, certificates can be used to secure service-to-service (S2S) communication in Azure by enabling mutual authentication between the services. This involves each service presenting a certificate to the other as a means of proving its identity.
Presentation of a signed assertion – Used in workload identity federation, signed assertions enable the exchange of a trusted 3rd party identity provider token with the Microsoft Entra ID platform to obtain access tokens to call Microsoft Entra ID protected resources. Workload identity federation can be used to enable a variety of federation scenarios, including Azure Kubernetes Service, Amazon Web Services EKS, GitHub Actions, and more.
When does proving client identity matter?
Proving client identity matters when there is a need to verify both the authenticity and authorization of a client application before granting access to sensitive data or resources. Some examples include:
Controlling API access – If you have an API that is metered (e.g., for billing), or exposes sensitive data or resources, you will want to verify the identity of the client before granting access. This can be especially important, for example, when ensuring that only authorized applications have access to the API, and that the proper customer is billed for their metered API usage.
Protecting users from app impersonation – If you have a service-deployed, user-facing application (e.g., a backend-driven web app) that accesses sensitive data or services, using client secrets to protect the resources used by that application may prevent bad actors from impersonating a legitimate client to phish users and exfiltrate data or abuse access.
Service-to-service communication – If you have multiple backend services (e.g., downstream APIs) that need to communicate with each other, you may want to verify the identity of each service to ensure they are authorized to access only necessary resources to perform their function.
In general, proving client identity matters when there is a need to authenticate and authorize a client independent of or in addition to a user.
Building your app or service on the Entra platform
Whether you’re building web services, mobile, web, or desktop applications, the Microsoft Entra platform can be used to help you build software your users and customers can sign in to using their Microsoft identities or social accounts. It authorizes access to your own APIs or Microsoft APIs like Microsoft Graph or Cognitive Services.
For developers, the Microsoft identity platform offers the ability to integrate modern innovations in the identity and security space, like passwordless authentication, step-up authentication, and Conditional Access. You don’t need to implement such functionality yourself; applications integrated with the Microsoft identity platform natively take advantage of such capabilities.
To help you get started, the Entra platform provides an array of quickstarts and how-to guides for varying app types. These resources guide you through the process of registering your first app or service all the way to acquiring your first token from Microsoft Entra ID using the Microsoft Authentication Library (MSAL).
- Web app that signs in users
- Web app that calls web APIs
- Protected web API
- Web API that calls web APIs
- Daemon app
Confidential clients: best practices for managing secrets
Use managed identities to simplify deployment and security – Managed identities provide an automatically managed identity in Microsoft Entra ID for applications to use when connecting to resources that support Microsoft Entra ID authentication. Applications can use managed identities to obtain Azure AD app-only tokens without having to manage any credentials. This can remove many of the headaches and complexities associated with secret management while increasing your security and resiliency. If you’re using managed identities, most, if not all of the best practices listed below are already taken care of for you.
Use secure storage – Store client secrets in a secure location, such as Key Vault or an encrypted configuration file. Avoid storing client secrets in plaintext or as checked-in files to version control systems.
Limit access – Limit access to client secrets to only authorized personnel. Use role-based access control (RBAC) to restrict access to client secrets to only those who need it to perform their operational duties.
Rotate client secrets – Rotation of client secrets, either on an as-needed or scheduled basis, can minimize the risk of a compromised secret being used to gain unauthorized access. When applied to cryptographic artifacts, the time span during which a key is suggested to remain in use, is called its ‘cryptoperiod’ and may be influenced by the strength of the cryptographic algorithm used and/or the adherence to standards or regulatory compliance practices.
Use long secrets and strong encryption – Closely related to the above, using strong encryption algorithms for data both in-transit (on the wire) and at-rest (on disk) helps ensure that high-entropy secrets remain unlikely to be brute-forced. Algorithms such as AES-128 (or higher) can help protect data at rest, while RSA-2048 (or higher) can help efficiently protect data in transit. Due to the ever-evolving nature of cybersecurity, it is always best practice to consult your security experts and periodically review your algorithm selection.
Avoid hardcoding secrets – Do not hardcode client secrets in source code. Avoiding secrets in source code can minimize the value of bad actors gaining access to your source code. It can also prevent such secrets from accidentally being pushed to insecure repositories or made available to project contributors who may have source access, but not secret access.
Monitor repositories for leaked secrets – It’s an unfortunate fact that bad check-ins happen when dealing with source code. That pesky secret that was never supposed to be in the source code somehow got checked into the repo. Git pre-commit hooks are a great way to prevent these kinds of accidental check-ins in the first place but is not a substitute for monitoring as well. Automated monitoring of repositories can catch leaked secrets and, with a plan in place to rotate compromised credentials, can help reduce the blast radius of such security incidents.
Monitor for suspicious activity – Monitor logs and audit trails for suspicious activity related to client secrets. Where possible use automated alerts and response processes to notify personnel and define contingencies for unusual activity related to client secrets.
Architect your applications with client secrecy in mind – Your security model is only as strong as the weakest link in the chain. Do not forward security credentials or tokens from confidential to public clients, as this may move client secret data to a public client, allowing impersonation of the confidential client.
Use up-to-date libraries and SDKs from trusted sources – The Microsoft identity platform provides a variety of client and server SDKs and middlewares designed to boost your productivity while keeping your applications secure. Libraries such as Microsoft.Identity.Web simplify adding authentication and authorization to web apps and APIs on the Microsoft identity platform. Keeping dependencies updated helps ensure your applications and services benefit from the latest security innovations and updates.
Safeguarding identity in public and confidential clients
We’ve learned that public and confidential clients have different security postures and use cases. Public clients are great for enabling user-delegated access to protected resources but are unable to prove their own application identity. Confidential clients, on the other hand, can perform both user and application authentication and authorization and must be built with security in mind to ensure that their secrets are not shared with public clients or other third parties.
In some cases, such as service-to-service communication, infrastructure like managed identities greatly helps to simplify the development and deployment of services and removes much of the complexity typically associated with secret management. When managed identities cannot be used, it’s important to have policies, preventive measures, and contingencies in place for securing secrets and responding with security incidents related to them.
Visit our docs to learn more about security best practices when registering an application in Microsoft Entra ID or to learn more about the Microsoft Authentication Library (MSAL).