APIs: Concepts, Design, Requests, Responses, and Integration
Spring Boot Actuator Env Endpoint
Learn how Spring Boot Actuator's env endpoint exposes property sources, resolves precedence, masks secrets, and can be secured safely in production.
The Spring Boot Actuator env endpoint reports configuration values available through Spring's Environment abstraction. It is useful when you need to understand which configuration sources are loaded, which profiles are active, and why one property value takes precedence over another.
The endpoint is operationally sensitive. It can reveal credentials, tokens, internal service addresses, deployment details, and feature flags. Treat it as an administrative interface, not as a general application API.
What the env endpoint does
Spring Environment is Spring's abstraction for resolving properties and profiles from ordered property sources. A property source is a named origin of configuration, such as an application file, an environment variable, a Java system property, or a command-line argument.
The Actuator env endpoint presents those property sources and their property entries. It can also perform a targeted lookup for one property name. This makes it useful for:
- Verifying that the expected application configuration was loaded.
- Checking which profiles are active or available.
- Finding the source that supplied an effective setting.
- Diagnosing precedence problems between files, environment variables, and command-line arguments.
- Comparing local, staging, container, and production configuration behavior.
Endpoint enablement and HTTP exposure
Two separate decisions control whether an Actuator endpoint can be reached:
- Enablement determines whether the endpoint exists within the application.
- Exposure determines whether an enabled endpoint is reachable over a transport such as HTTP or JMX.
| Endpoint enabled | Exposed over HTTP | Security access granted | Expected outcome |
|---|---|---|---|
| No | No | Irrelevant | The endpoint is unavailable, commonly producing 404. |
| Yes | No | Yes | It may be available through another enabled transport, but not through the web route. |
| Yes | Yes | No | The route exists, but authentication or authorization can produce 401 or 403. |
| Yes | Yes | Yes | The authorized request can retrieve the endpoint response. |
Spring Boot versions differ in their default web exposure behavior. Some versions expose only a small set of endpoints, while others expose a different default set. Do not rely on defaults for production. Use an explicit allowlist and check the documentation for the Spring Boot version running in the deployment.
Dependency and basic exposure configuration
The application needs the Spring Boot Actuator dependency. For Maven, the dependency normally has this form:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
For Gradle:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
}
An explicit web exposure allowlist can be placed in application.properties:
management.endpoints.web.exposure.include=health,info
This production-oriented example deliberately does not expose env. If a controlled administrative environment genuinely needs it, add env only after applying network and authorization controls:
management.endpoints.web.exposure.include=health,info,env
Management paths, ports, and interfaces
By default, web Actuator endpoints are commonly served below an application management prefix such as /actuator. The exact route depends on the management base path and the Spring Boot version.
You can customize the prefix:
management.endpoints.web.base-path=/manage
With that setting, the collection route is conceptually /manage/env rather than /actuator/env. A request must use the configured management path, not an assumed path from another environment.
A separate management server port can reduce accidental exposure through the main application listener:
management.server.port=9091
In suitable deployments, bind the management listener to a restricted interface or place it behind a private load balancer. Network separation is not a replacement for authentication, but it reduces the number of clients that can reach the route.
Request structure
The collection request retrieves the available property sources through the configured management base path:
curl --fail --user "$ACTUATOR_USER:$ACTUATOR_PASSWORD" \
"$MANAGEMENT_BASE/env"
For a targeted lookup, append the property name as the endpoint's property-name path parameter:
curl --fail --user "$ACTUATOR_USER:$ACTUATOR_PASSWORD" \
"$MANAGEMENT_BASE/env/application.name"
A targeted lookup is preferable when investigating one setting. It reduces unnecessary disclosure compared with retrieving the complete environment.
URL encoding property names
A property name in a URL path is not just ordinary text. Dots are usually safe in a path segment, but brackets, slashes, spaces, question marks, hash characters, semicolons, and percent signs have routing or URL semantics. Encode the path value using a URL encoder rather than manually replacing characters.
property_name='app.datasource[0].url'
encoded_name=$(python -c 'import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1], safe=""))' "$property_name")
curl --fail "$MANAGEMENT_BASE/env/$encoded_name"
Whether a slash remains part of the property name or becomes another path segment depends on the router and its encoded-slash policy. Semicolons can be interpreted as path parameters and may be stripped or normalized by a framework, gateway, WAF, or reverse proxy. Trailing-slash behavior also varies. A request ending in /env/ might be redirected, accepted, or rejected depending on the application and proxy configuration.
Understanding the response model
A collection response generally contains a list or map of property sources. Each source has a name identifying its origin and a set of property entries. An entry commonly includes a property key and a value, although response fields and detail levels can vary by Spring Boot version.
- Property source name: identifies an origin such as a configuration file, system properties, or environment variables.
- Property key: the name used to look up a setting.
- Property value: the resolved or supplied value, potentially replaced by a sanitization marker.
- Origin details: some versions or configurations provide additional location information, but clients should not assume those fields always exist.
The same key can appear in several sources. For example, server.port might be present in a YAML file and also in a container environment variable. The source order and Spring's precedence rules determine which value becomes effective.
Sanitization can replace a sensitive value with a marker such as ******. A masked response does not prove that the original secret is absent; it proves only that the endpoint chose not to return it.
Common property sources and precedence
Property precedence is the ordering rule used when more than one source defines the same key. The precise order is version- and context-dependent, so consult the documentation for the running Spring Boot version. The following sources are common examples rather than a universal complete ranking.
| Property source | Typical deployment use | Relative precedence considerations | How to verify |
|---|---|---|---|
| Command-line arguments | Temporary startup overrides and deployment flags | Often deliberately high precedence | Inspect the command that launched the JVM and the env response. |
| Java system properties | -Dname=value settings from a launcher or platform | Often overrides file-based configuration | Inspect JVM arguments and the relevant property source. |
| OS environment variables | Containers, Kubernetes manifests, and platform settings | Usually overrides ordinary application-file values | Check the process environment and relaxed name conversion. |
| Profile-specific files | Environment-specific settings such as staging or production | Applied conditionally when the profile is active | Check active profiles and loaded source names. |
| Application configuration files | Defaults in application.properties or YAML | Common baseline; external files may override packaged files | Inspect source names and deployment mounts. |
| External configuration | Mounted files, configuration trees, remote or platform-provided configuration | Position depends on the import mechanism and version | Verify mounts, imports, startup logs, and source names. |
| Test properties | Test-specific overrides and test context setup | Can override normal application configuration in tests | Inspect test annotations, test files, and the test context. |
The env endpoint helps identify the origin of a resolved setting. For example, if a database host differs between staging and production, look for duplicate definitions, check whether the intended profile is active, and determine whether an injected environment variable outranks the profile-specific file.
Profiles and imported configuration
An active profile is a selected Spring profile that controls which beans and configuration documents apply. A default profile is used when no explicit active profile is selected.
spring.profiles.active=staging
spring.profiles.default=default
Profile-specific files commonly follow names such as application-staging.properties or application-staging.yml. Conditional configuration can also use profile annotations or profile-specific configuration documents. A source can therefore exist on disk without affecting the application if its profile is inactive.
Configuration can also be imported from outside the packaged application. Examples include mounted configuration trees, a platform's injected files, and remote configuration systems where supported. Confirm that the import location is available, that the import is enabled, and that the source appears in startup diagnostics or the env response.
Spring Boot supports relaxed binding, meaning several naming styles can represent the same logical property. For example, a property such as my.service.timeout is commonly supplied through an environment variable like:
MY_SERVICE_TIMEOUT=2500
Numeric indexes and unusual punctuation require extra care. Confirm the exact binding rules for the property and verify the resulting key rather than assuming that every spelling maps identically.
Security risks
Environment data can disclose:
- Database credentials, API keys, passwords, and access tokens.
- Internal hostnames, ports, URLs, network topology, and cloud resource names.
- Deployment structure, mounted paths, container metadata, and platform configuration.
- Feature flags, licensing settings, debugging options, and security-related switches.
Default sanitization usually recognizes common secret-like key names, but it cannot identify every organization-specific secret. A custom credential key may be returned unless it matches a configured sanitization pattern. Conversely, a broad pattern can mask harmless values and make diagnosis harder.
Never expose the env endpoint publicly merely because values appear masked. Key names, source names, configuration structure, unrecognized secrets, and version-specific response behavior can still disclose sensitive information. Public management endpoints also create a target for automated enumeration and configuration reconnaissance.
Sanitization
Sanitization masks values before they are serialized in the response. Configure additional patterns for application-specific keys according to the Spring Boot version in use. A representative configuration is:
management.endpoint.env.keys-to-sanitize= password,secret,token,apiKey,privateKey,credential
Some Spring Boot versions use different property names or support different pattern configuration mechanisms. Verify the exact setting for your release and test it with representative keys.
After changing the setting, perform a controlled lookup and confirm that the value is masked. Test both a known secret and a normal diagnostic property to detect patterns that are too narrow or too broad.
Safe production configuration
A safe deployment usually exposes only the endpoints needed by monitoring and operations:
management.endpoints.web.exposure.include=health,info
management.endpoints.web.base-path=/manage
management.server.port=9091
Keep env off the public allowlist. If an incident-response or platform workflow requires it, expose it only on a restricted management listener or private route, require authentication, and authorize a narrowly defined administrative role.
With Spring Security, protect sensitive Actuator routes explicitly. The exact matcher and configuration style differ between Spring Security versions, but the policy should express the following intent:
@Bean
SecurityFilterChain actuatorSecurity(HttpSecurity http) throws Exception {
http
.securityMatcher("/manage/**")
.authorizeHttpRequests(auth -> auth
.requestMatchers("/manage/health").permitAll()
.requestMatchers("/manage/env").hasRole("ACTUATOR_ADMIN")
.anyRequest().authenticated())
.httpBasic(Customizer.withDefaults());
return http.build();
}
Adapt the route to the configured management base path and use your approved authentication mechanism. Authorization at Spring Security should be combined with:
| Control | Threat addressed | Example implementation area | Operational notes |
|---|---|---|---|
| Least-privilege roles | Unnecessary administrative access | Spring Security roles or authorities | Separate read-only monitoring from configuration diagnostics. |
| Network restriction | Internet-wide discovery and access | Private subnet, firewall, security group, or service mesh | Allow only approved operators and monitoring systems. |
| Authentication | Anonymous requests | Spring Security, gateway identity, or mutual TLS | Use managed identities and rotate credentials. |
| Reverse-proxy controls | Unintended route forwarding | Ingress, API gateway, or proxy route policy | Do not publish the management listener through a general API route. |
| Auditing | Undetected sensitive reads | Application, gateway, and identity-provider logs | Record identity and outcome without logging secret response bodies. |
Review firewall rules, ingress paths, proxy rewrites, service-to-service permissions, and management listener bindings together. A secure application route can still be exposed accidentally by an ingress rule that forwards every path.
Practical investigations
Verify the effective application name
Use a targeted property lookup through the configured management base path:
curl --fail --user "$ACTUATOR_USER:$ACTUATOR_PASSWORD" \
"$MANAGEMENT_BASE/env/application.name"
Compare the reported source with the expected file, environment variable, or command-line argument. Avoid requesting the full environment when one property answers the question.
Find why a database host differs
- Check the active profile and confirm that the expected profile-specific file is loaded.
- Search the env response for duplicate definitions of the database host.
- Check container or Kubernetes environment variables and mounted configuration trees.
- Compare the source ordering with the expected precedence for the running Spring Boot version.
- Verify that the higher-precedence source contains the intended value.
Expose only health and info
Use an explicit allowlist such as health,info, keep the management listener private, and do not include env in the public route. Monitoring should use the smallest endpoint set that satisfies its checks.
Mask an application-specific credential
Add a key pattern that matches the credential name, restart or reload configuration as required by the deployment, then test a targeted lookup. Confirm that the value is masked and that the pattern does not hide unrelated diagnostic properties. Preserve role and network restrictions even after successful masking.
Troubleshooting
| Symptom | Likely cause | Verification step | Resolution |
|---|---|---|---|
| 404 Not Found | Missing Actuator dependency, disabled endpoint, non-exposure, incorrect path or port, or proxy route omission | Check dependencies, enablement, exposure, management settings, listener, and proxy logs. | Install Actuator, enable and expose only as intended, use the correct base path and port, and fix route forwarding. |
| 401 Unauthorized | Authentication is required but credentials or identity are missing or invalid | Inspect the authentication challenge and identity-provider or gateway logs. | Use an approved administrative identity and valid authentication method. |
| 403 Forbidden | The principal lacks the required role, or a gateway or ingress denies access | Review Spring Security authorities and perimeter policy. | Align the narrowly scoped actuator role with the approved access policy. |
| Missing or unexpected value | Higher-precedence source, inactive profile, incorrect environment-variable mapping, or unloaded external configuration | Inspect sources, active profiles, deployment variables, mounts, imports, and startup diagnostics. | Correct the winning source or activate and load the intended configuration. |
| Secret visible | Sanitization pattern does not match, or behavior differs by version | Test the key name and review sanitization configuration for the running release. | Add an appropriate pattern and keep strict endpoint access controls. |
| Ordinary value masked | Sanitization pattern is overly broad | Test representative keys against each configured pattern. | Narrow the pattern while retaining coverage for all secret names. |
| Punctuation lookup fails | Property name was not encoded, semicolon handling changed, or a proxy normalized the path | Inspect the encoded request and each routing layer's received path. | Encode the path value, avoid unsafe route construction, and adjust proxy handling. |
Version and deployment differences
Endpoint defaults, response fields, sanitization properties, security integration, and configuration property names can differ among Spring Boot releases. Test against the exact dependency version used in each environment. Do not assume that a local response or configuration example applies unchanged to production.
- Local development: developers may run the application on one port with permissive access. This is convenient but can hide missing production network controls.
- Containers: environment variables and command-line arguments frequently override packaged files. Inspect the actual container specification and process arguments.
- Kubernetes-style deployments: ConfigMaps, Secrets, environment-variable injection, projected files, and configuration trees can create several competing sources.
- Managed platforms: platform variables, startup wrappers, sidecars, gateways, and private management interfaces can alter both precedence and routing.
When moving between deployment types, verify the management host, port, base path, ingress policy, active profiles, imported configuration, and effective property source rather than comparing only application files.
Exam-relevant notes
- The env endpoint reads from Spring's Environment; it is not a general runtime configuration editor.
- An endpoint can be enabled but not exposed over HTTP.
- Repeated keys across property sources are expected; precedence determines the effective value.
- Active profiles affect which configuration documents and conditional beans apply.
- Relaxed binding maps common naming styles, but unusual punctuation and indexed properties need verification.
- Sanitization reduces disclosure but does not make public exposure safe.
- 404 usually indicates dependency, enablement, exposure, routing, or path problems; 401 and 403 usually indicate authentication or authorization policy.
For related configuration and environment material, see Env and Config. The endpoint route associated with this lesson is the configured env management path; preserve its exact path when integrating with routing and proxy tests.