Security Best Practices for Using embabel-agent: A Developer’s Guide to Production Safety

TLDR: Secure embabel-agent by leveraging its Spring Boot security auto-configuration for JWT-based MCP server authentication, enforcing method-level authorization with @PreAuthorize, and extending the TrackedAspect observability layer for input validation and audit logging.

The embabel-agent framework provides a Spring Boot-based foundation for building AI agent applications with modular auto-configuration. Understanding the security best practices for using embabel-agent is critical to protecting both the Model Context Protocol (MCP) server endpoints and the tool execution pipelines in production environments.

Core Security Architecture

The embabel-agent security model operates on two distinct layers that developers must configure correctly to ensure comprehensive protection.

Infrastructure-Level Protection

The MCP server—the remote tool-execution endpoint—is secured by the AgentMcpServerAutoConfiguration class located in embabel-agent-autoconfigure/embabel-agent-mcpserver-security-autoconfigure/src/main/java/com/embabel/agent/autoconfigure/mcpserver/security/AgentMcpServerAutoConfiguration.java. This configuration imports SecureAgentToolConfiguration and SecureAgentSecurityConfiguration, which wire essential Spring Security components including a JwtAuthenticationConverter, a SecurityFilterChain, and a method-security expression handler. These beans enforce stateless authentication and coarse-grained access control at the transport layer.

Application-Level Controls

All agent-exposed services are wrapped by the Observed Aspect (TrackedAspect) found in embabel-agent-observability/src/main/java/com/embabel/agent/observability/tracing/TrackedAspect.java. Because this aspect executes before and after each public method invocation, it serves as an interception point for audit logging, rate-limiting, and pre-execution validation. The framework automatically enables method-level security annotations such as @PreAuthorize when the security auto-configuration classes are present on the classpath.

Critical Security Best Practices

Implementing robust security requires addressing credentials, transport, authorization, and runtime validation.

Never Hard-Code Secrets

Store API keys, JWT signing secrets, and database passwords in environment variables or dedicated secret managers. Hard-coded credentials in application.yml or source code frequently leak into version control and logs.


# application.yml (use environment variables for actual values)

spring.security.oauth2.resourceserver.jwt.issuer-uri=${JWT_ISSUER_URI}
spring.security.oauth2.resourceserver.jwt.audiences=${JWT_AUDIENCES}

Enforce HTTPS Everywhere

Deploy the embedded Tomcat server behind a TLS-terminating reverse proxy. For programmatic connector customization:

@Bean
public TomcatServletWebServerFactory servletContainer() {
    TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
    factory.addConnectorCustomizers(connector -> connector.setSecure(true));
    return factory;
}

Implement JWT and OAuth2 for MCP Endpoints

The auto-configured JwtAuthenticationConverter validates signed tokens and populates the Spring Security Authentication object. Explicitly configure the security filter chain to protect MCP routes:

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class AgentSecurityConfig {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authz -> authz
                .requestMatchers("/mcp/**").authenticated()
                .anyRequest().permitAll())
            .oauth2ResourceServer(oauth -> oauth.jwt());
        return http.build();
    }
}

Apply Method-Level Authorization

Annotate sensitive tool-invocation methods with @PreAuthorize to enforce least-privilege access. This complements the coarse-grained HTTP security with fine-grained function-level controls:

@PreAuthorize("hasAuthority('tool:run')")
public String executeTool(ToolRequest request) {
    // tool logic
    return "success";
}

Validate All Inbound Data

Extend the TrackedAspect to perform schema validation or sanitization before the agent core processes a request. The aspect’s interception mechanism provides a single chokepoint for rejecting malformed payloads:

@Around("@annotation(com.embabel.agent.observability.annotation.Tracked)")
public Object validateAndProceed(ProceedingJoinPoint pjp) throws Throwable {
    Object[] args = pjp.getArgs();
    // Inspect and validate args, throw SecurityException if invalid
    return pjp.proceed();
}

Configure CSRF Protection

Maintain Spring Security’s default CSRF filter enabled for state-changing endpoints. Disable CSRF protection only when exposing a pure REST API protected exclusively by JWT bearer tokens:

// Only disable for JWT-only REST APIs
http.csrf(csrf -> csrf.disable());

Leverage Observability for Security Monitoring

Integrate MicrometerAgentInstrumentation to emit metrics on authentication failures, rejected payloads, and unusual access patterns. Real-time dashboards enable rapid incident detection:

@Bean
public MicrometerAgentInstrumentation micrometerInstrumentation(MeterRegistry registry) {
    return new MicrometerAgentInstrumentation(registry);
}

Maintain Dependency Hygiene

Regularly audit the Spring Boot, Spring Security, Tomcat, and cryptographic libraries for CVEs. Use Maven’s versions plugin to identify outdated components:

mvn dependency:tree
mvn versions:use-latest-releases

Practical Implementation Examples

The following examples demonstrate common security configurations for production embabel-agent deployments.

Enabling JWT Protection for the MCP Server

Create a configuration class that customizes the SecurityFilterChain while retaining the auto-configured JWT converter provided by AgentMcpServerAutoConfiguration:

package com.example.agent;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableMethodSecurity // Activates @PreAuthorize annotations
public class AgentSecurityConfig {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // Require authentication for all "/mcp/**" endpoints
        http.authorizeHttpRequests(authz -> authz
                .requestMatchers("/mcp/**").authenticated()
                .anyRequest().permitAll())
            .oauth2ResourceServer(oauth -> oauth.jwt()); // Validates JWT tokens
        return http.build();
    }
}

The auto-configuration in AgentMcpServerAutoConfiguration imports the necessary security beans, so this class overrides defaults only when custom path restrictions are required.

Restricting Tool Execution to Privileged Users

Combine the @Tracked annotation with @PreAuthorize to ensure observable, authorized access to sensitive tools:

package com.example.agent.tools;

import org.springframework.security.access.prepost.PreAuthorize;
import com.embabel.agent.observability.annotation.Tracked;

@Component
public class SecureTool {

    @Tracked // Enables observability and validation hooks
    @PreAuthorize("hasAuthority('tool:run')")
    public String execute(String payload) {
        // Tool logic here
        return "Execution completed";
    }
}

The TrackedAspect logs the invocation metadata and can be extended to perform additional payload inspection before execute() runs.

Key Security Files and Components

Understanding the location and purpose of these source files is essential for auditing and customizing the security posture:

Summary

  • Leverage auto-configuration: Rely on AgentMcpServerAutoConfiguration to wire JWT and Spring Security infrastructure for MCP endpoints.
  • Enforce least privilege: Use @PreAuthorize annotations on tool methods to restrict execution to authorized principals.
  • Validate inputs: Extend TrackedAspect to inspect and sanitize payloads before they reach the agent core.
  • Protect secrets: Externalize all credentials to environment variables or secret management systems.
  • Monitor continuously: Use MicrometerAgentInstrumentation and the TrackedAspect audit trail to detect anomalous access patterns.

Frequently Asked Questions

How does embabel-agent handle authentication for MCP server endpoints?

The framework uses AgentMcpServerAutoConfiguration to import SecureAgentSecurityConfiguration, which configures a Spring Security SecurityFilterChain and a JwtAuthenticationConverter. This setup validates JWT tokens on incoming requests to /mcp/** paths and populates the security context with authentication details derived from the token claims.

Can I use method-level security annotations like @PreAuthorize with embabel-agent?

Yes. When the security auto-configuration is present, Spring Security’s method security is automatically enabled. You can annotate tool methods with @PreAuthorize("hasAuthority('tool:run')") to enforce fine-grained authorization decisions based on the authenticated user’s authorities.

What is the purpose of the TrackedAspect in security contexts?

TrackedAspect provides an AOP interception point around methods annotated with @Tracked. It records request and response metadata for audit trails and offers a configurable hook to perform input validation, rate limiting, or additional security checks before method execution proceeds, as implemented in embabel-agent-observability/src/main/java/com/embabel/agent/observability/tracing/TrackedAspect.java.

How should I manage JWT secrets in an embabel-agent application?

Never commit JWT signing keys or issuer URIs to version control. Configure these values via environment variables injected into application.yml (e.g., ${JWT_ISSUER_URI}), or use a dedicated secret manager like HashiCorp Vault or AWS Secrets Manager integration with Spring Cloud.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →