The technology world has always relied heavily upon applications with some form of state, especially during the previous era of monolithic applications. Yet, stateless applications have been around for a long time too, especially for certain scenarios like offline processing (batch).
With the growth of mobile applications, IoT, and cloud-native applications, the stateless design pattern has become much more prevalent, and the state pattern is now more likely to be maintained by the client (like an iOS or web app) rather than the underpinning micro services.
What are Stateless Applications
Many modern application development patterns are based upon the concept of stateless applications. Since stateless applications do not maintain session or transaction information between service calls made by clients, each and every request processed has all of the information it needs to start and complete requests. They can still have resources like databases and message queues connected to them, which might make them seem stateful, but that is not the case. To illustrate the difference, let’s look at a particular scenario: if a request for all “LEGO” products with “Ninjago” in the name is received by a stateless product lookup service, it would return a data set and could even cache these requests to increase speed, but the service would theoretically have no idea if the client was a first-time caller or its biggest customer. In contrast, stateful applications would go through multiple steps to gather data, including one for the requested brand (“LEGO”) and another for the requested name (“Ninjago”) before responding; if there was a failure at the second step, the application would have to decide whether to redo the step or restart the transaction.
Secrets and Stateless Applications Considerations
By their nature, stateless applications are a great fit for modern cloud infrastructures, including containerization and deployment on (and management by) platforms like Kubernetes. As there is no state to maintain between instances, stateless applications are easily and often set to automatically scale up and down based on demand, which improves their cost profile during slow times and delivers a better customer experience during busy times.
In addition to their ability to easily scale up and down for web and mobile applications, stateless applications are often used to receive data transmissions coming from IoT devices. Depending on the scenario, this could consist of hundreds of devices that report every interaction, or millions of devices from around the globe that report only at 2 A.M. local time.
Returning the data from all of these requests requires accessing other services or pulling data from a data store of some kind. It also requires accessing multiple environment-specific configuration items and secrets which, in many cases, are only available to the specific application instances that need to know them. These types of secrets include API keys, usernames, passwords, SSH certificates, and connection URLs.
While these can be hardcoded into the application, that would mean that the application would need to be changed every time it was deployed. For many applications, secrets can be moved into external configuration files, and for containerized applications, they can be moved directly into the application’s environment context (since the environment context cannot be seen by anything else). When creating and pushing configuration files, this will add an additional step between the application and environment configuration, which can increase the complexity. However, it only takes a little extra effort to include the required secrets when creating the application environment.
Ideally, the secrets will only be referenced in the environment-specific configuration and pulled from a centralized repository so that they are only maintained once and can leverage role-based access control (RBAC) to manage credentials as well as report on who has accessed — and even who has attempted to access — specific credentials.
Stateless applications are here to stay, and they rely on secrets just as much as applications do. Since stateless applications tend to be used more often in scenarios where the application needs to scale up and down in short order (such as when batch processing or searching queries), the best approach is to have a single, centralized secrets management solution that fully integrates with the application platform and can scale along with it. There are a wide range of choices, from narrowly-focused options like Kubernetes Secrets to more robust, cross-platform options like Conjur.