Skip to main content
Platform
Platform Overview How It Works
Solutions
AppSec Teams Platform Engineering Pricing Blog
Sign In Request Early Access
Secret exposure paths across a microservice architecture graph
Back to blog

Secret Exposure in Microservice Architectures: The Graph Problem

Secret scanning tools have gotten genuinely good at finding secrets in the places secrets shouldn't be: committed to repositories, embedded in build logs, hardcoded in configuration files checked into version control. If you are running a mature secrets management program, you are probably rotating on detection, using a secrets store like Vault or AWS Secrets Manager, and enforcing policies that prevent plaintext secrets from reaching production configuration at all.

None of that eliminates the question of what happens at runtime. A secret that is stored correctly, rotated regularly, and never committed to source control is still accessed at runtime by the services that need it. And in a microservice architecture, understanding the blast radius of a secret exposure is a graph traversal problem that secrets management tooling does not model.

The two distinct secret exposure questions

There are two separate questions that often get conflated in secret exposure discussions. The first is: where is this secret stored, and can an attacker read it at rest? That is the question secrets management tools are designed to answer. The second is: if a secret is read at runtime by a service, which execution paths from attacker-accessible entry points can cause that service to use the secret in a way that benefits the attacker?

The second question is a reachability question. It requires a model of the call graph from entry points to the code that reads the secret and uses it, and a model of what the secret provides access to downstream. A database credential that is read from Vault and used to authenticate a connection allows an attacker who can influence queries through a vulnerable handler to execute arbitrary queries against that database, even if the credential itself was never exposed in plaintext. The secret was managed correctly; the exposure path runs through the application's code, not through the secrets store.

How blast radius becomes a graph problem

In a monolithic application, the blast radius of a secret exposure is bounded by what that secret provides access to. A database credential grants access to the database. An API token grants access to the third-party API. The scope is relatively clear.

In a microservice architecture, secrets are frequently shared across services in ways that expand the blast radius significantly. A service account credential used by multiple services as their identity for inter-service authentication creates a shared exposure surface: any service that holds this credential, if compromised, can impersonate any other service in the set that trusts it. A database connection string for a shared database that multiple services connect to means a credential exposure affecting any one of those services potentially grants access to the database's full data set, not just the portion that the compromised service itself accessed.

The graph problem is: given your specific service topology and the credential-sharing patterns that exist in it, what is the actual blast radius of an exposure affecting service X? That question requires traversing the credential-sharing graph alongside the service call graph. Which services share this credential? Which data stores or downstream services does this credential unlock? If service A is compromised and holds a credential that also unlocks service B's admin interface, the blast radius of the service A compromise extends to service B's data regardless of whether service B itself is vulnerably.

The secret-access call graph within a single service

Before getting to inter-service blast radius, the intra-service question is worth examining carefully. When a service reads a secret at startup and holds it in memory for the duration of the process, every handler in that service has implicit access to the secret through the process's memory space. That is a very different exposure model than a service that reads a secret only within a specific code path, called only from a specific handler, in response to a specific request type.

Most services fall somewhere between these extremes. The database connection pool is initialized at startup and used by most handlers. A third-party API client initialized on first use might be accessed by a subset of handlers. The relevant reachability question for each secret is: which entry points, if sent a crafted request, could cause the secret to be used in a way the attacker can observe or influence?

For a database credential, the answer is likely "any entry point that triggers a database query on a table whose data the attacker wants." For an internal service-to-service credential, the answer depends on which handlers invoke the downstream service call that uses the credential. Constructing the call graph from entry points to secret-using code locations tells you which subset of the exposed API surface is relevant to the exposure risk for each secret.

What vault and secrets management do and do not solve

We are not arguing against secrets management tooling. The controls it provides, centralized storage, audit logging of secret access, automatic rotation, short-lived credentials, and access policies limiting which services can retrieve which secrets, are all correct security controls that reduce the impact of various failure modes. A short-lived credential that rotates every few hours limits the window of usefulness even if an attacker retrieves it. An access policy that restricts Vault access to specific service identities prevents a compromised service from retrieving credentials for services it has no legitimate reason to access.

The limitation is that those controls address the secrets storage and provisioning layer. They do not address the question of which code paths within a legitimate service consumer can be influenced by an external attacker to misuse the secret the service legitimately holds. A service that correctly retrieves a database credential from Vault and correctly uses it for its intended purpose still exposes that credential to misuse through any SQL injection vulnerability in a query it builds from user input.

Practical prioritization for secret exposure findings

Secret scanning findings that identify a potential exposure path warrant different prioritization based on the reachability structure. A finding where the secret-reading code is in a handler called only from an internal-only endpoint, accessible only from other services that have already been authenticated, is a lower-priority finding than a finding where the secret-reading code is in a handler on a public API endpoint with no authentication requirement.

The inter-service blast radius adds a second dimension. A finding in a service that holds a credential shared with a high-sensitivity downstream service warrants higher priority than a finding in a service whose credentials provide access only to its own low-sensitivity read replica database, even if the intra-service reachability looks similar.

Building this prioritization requires the service topology graph, the credential-sharing graph, and the per-service call graph. The intersection of those three models is where the genuinely high-priority secret exposure findings live.

See reachability analysis on your own code

Connect your repositories and apply a reachability filter to your existing scanner findings. No configuration changes to your current toolchain required.

Request early access