Featured resource
Tech Upskilling Playbook 2025
Tech Upskilling Playbook

Build future-ready tech teams and hit key business milestones with seven proven plays from industry leaders.

Learn more
  • Labs icon Lab
  • Core Tech
Labs

Guided: Security Best Practices in Microservices Integration

Microservices often need to exchange sensitive data internally. In some cases, using OAuth or external identity providers is not feasible due to infrastructure constraints. This hands-on lab walks you through a secure integration between two microservices using internal mechanisms such as API keys, request signing with HMAC, and message encryption. By the end of this lab, you will have practical experience securing services without relying on external authentication systems.

Labs

Path Info

Level
Clock icon Intermediate
Duration
Clock icon 54m
Last updated
Clock icon Aug 22, 2025

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Table of Contents

  1. Challenge

    Introduction

    In this lab, you will secure the internal communication between two Spring Boot microservices , an order-service and an inventory-service. Initially, these services communicate over HTTP with no security, which poses significant risks. You will incrementally add security measures (API keys, HMAC signatures, and payload encryption) to protect their interactions. By the end, you’ll understand how to enforce authentication and integrity for internal API calls and ensure confidentiality of data even if TLS is compromised.

    Learning Objectives

    • Recognize the risks of unsecured internal microservice communication (e.g. unauthorized access and data interception).
    • Implement API key authentication to restrict access to trusted services.
    • Apply HMAC signatures to ensure message integrity and authenticity.
    • Encrypt sensitive data using AES to maintain confidentiality in transit. >If you get stuck on a task, you can view the solution in the solution folder in your Filetree, or click the Task Solution link at the bottom of each task after you've attempted it.
  2. Challenge

    Assessing Risks in Unsecured Microservice Communication

    You are a developer responsible for securing an Order Management system built with two microservices:

    • order-service: Handles incoming order requests (product ID and quantity) and delegates stock updates to inventory-service
    • inventory-service: Processes inventory updates and returns the remaining stock for the specified product

    Observe Unsecured Communication

    At this stage, the system allows any service to call the inventory API without authentication, and order data is transmitted in plain JSON format. In this lab, you will begin by examining this unsecured interaction and then progressively enhance its security.

    • order-service runs on port 8081.
    • inventory-service runs on port 8082.

    To begin, start the order-service and inventory-service in the first and second Terminal tabs respectively.

    In first Terminal start order-service:

    cd order-service
    mvn spring-boot:run
    

    In second Terminal start inventory-service:

    cd inventory-service
    mvn spring-boot:run
    

    Now trigger an order by sending a request to the order-service. It will internally forward the request to the inventory-service at http://localhost:8082/api/inventory/. You should receive the following response:

    Inventory updated for product P123. New stock: 98
    

    You can also observe the logs in the other Terminals:

    Order Service:

    Sending Order to Inventory Service {"productId":"P123","quantity":2}
    

    Inventory Service:

    Received Order In Inventory Service - {"productId":"P123","quantity":2}
    

    Notice that the call succeeds without any authentication, and the JSON data (product ID and quantity) is transmitted in plaintext.


    Risks of Unsecure Communication

    1. Unauthorized Access

    Without authentication mechanisms like API keys, any service or external client can call sensitive internal APIs. This opens the door to abuse, such as unauthorized inventory updates or data leaks.

    2. Data Tampering

    If requests are not signed or verified, an attacker could intercept and modify the payload (e.g., changing product quantity or ID) during transit, leading to incorrect updates or malicious actions in the system.

    3. Lack of Confidentiality

    Transmitting plain JSON over the network exposes sensitive business data (like inventory levels or pricing) to on-path attackers. Anyone snooping the traffic can read and misuse this information.


    These are serious vulnerabilities that you will address in the coming steps.

  3. Challenge

    Securing Access with API Keys

    Addressing Unauthorized Access

    In this step, you will implement a simple API key mechanism to ensure that only the order-service can access the inventory-service API.

    An API key is a unique token that the client (order-service) sends with each request to identify itself. The inventory-service will check for this key and reject requests that don’t have it or have the wrong value. This is a basic form of authentication suitable for service-to-service communication when a full OAuth flow is undesired.

    info> Note: Why API keys? Using a static API key in internal calls provides a lightweight authentication layer. It’s essentially a shared secret that identifies trusted callers. While not as robust as user-based authentication, it helps ensure only authorized services (with the key) can invoke the API. Now, you will update the order service to send an API key header (X-API-KEY) in all outgoing requests. --- Next, in the inventory service, receive the incoming API key. Now, validate the API key by matching it with the expected API key stored in the inventory service. To test the APIs, restart both the order and inventory services using the first and second Terminals.

    You can stop a running service by pressing Control+C in its Terminal tab.

    Then, use the command mvn spring-boot:run in each service directory to start them again. To test how the system handles invalid API keys, modify the application.properties file in order-service with an incorrect key. After saving the change, restart the service and send a request. The inventory-service will respond with a 401 Unauthorized error.


    In this step, you have added a basic authentication layer: only order-service (knowing the key) can talk to inventory-service. However, the data in transit is still unprotected and an attacker could intercept or alter it. You will address that next step.

  4. Challenge

    Adding HMAC-based Signature Validation

    Preventing Data Tampering

    While an API key restricts access to trusted services, it doesn't protect the contents of the request from being altered in transit. To address this, you will implement Hash-Based Message Authentication Code (HMAC) to detect any tampering.

    An HMAC is a secure hash generated from the request payload and a shared secret key. The sender (order-service) generates this hash and includes it in a custom header. The receiver (inventory-service) recalculates the HMAC using the received data and the same shared key. If the two signatures differ, the request is considered modified or untrusted and is rejected.

    This mechanism ensures that:

    • The request was not altered during transit (data integrity)
    • It was sent by a trusted source that knows the shared secret (authenticity) You will start by updating the OrderService to enable generation of HMAC signature in the header. --- Now, you will update the InventoryController to receive and validate the HMAC signature. > Note: Make sure you restart the order and inventory services in order for changes to be applicable. With this implementation, the inventory-service verifies the HMAC signature to ensure the message hasn’t been tampered with. Even a small change in the JSON causes a mismatch, and the request is rejected as "Unauthorized: Invalid HMAC signature". This confirms both integrity and authenticity of the request.

    At this point, you have authentication (API key) and integrity protection (HMAC). But the data itself, however, is still in plaintext JSON.

    If the traffic is not encrypted at the transport layer (or an attacker somehow breaks TLS), sensitive information could be exposed. In the next step, you will encrypt the request payload for confidentiality.

  5. Challenge

    Encrypting Request Bodies

    Addressing Lack of Confidentiality

    The final security enhancement is to encrypt the data exchanged between services. You will use Advanced Encryption Standard (AES), a symmetric-key cipher, to encrypt the JSON payload in the order-service and decrypt it in the inventory-service.

    AES uses the same secret key for both encryption and decryption. By encrypting the request body, even if an attacker intercepts the HTTP call, the content will be unintelligible without the AES key. This adds a strong confidentiality layer on top of our existing integrity checks.

    In practice, before sending the request, the order service will transform the JSON (e.g. {"productId":"P123","quantity":5}) into an encrypted string using a secret key. The inventory service will decrypt it back to JSON after receiving the request.

    info> Note: You will use a shared AES key known to both services. For simplicity, you’ll use a static key. In real systems, keys should be securely generated and rotated.


    Now, you will update the order service to initialize a cipher and send encrypted order to inventory service. --- Since EncryptedOrder is now being sent from the order service, the inventory service must receive and process EncryptedOrder instead of Order. Now, you will test the endpoint.

    Note: Please make sure to restart the order and inventory services. With encryption enabled, the order service now sends an encrypted payload and the inventory service decrypts it transparently. The HMAC signature implemented in Step 4 continues to work on the encrypted data (signature is generated after encryption in the order service). This means the integrity check is now protecting the ciphertext. The inventory service verifies the HMAC on the ciphertext, then decrypt to get the plaintext JSON for processing. info> Note: In a real-world implementation, you would use a more secure mode than ECB for AES (e.g., CBC with an IV, or GCM mode which also ensures integrity). Also, secrets like API keys and HMAC/AES keys should be stored securely (not hard-coded) and rotated periodically.

    At this stage, the two services trust each other (via API key), any tampering is detectable (via HMAC), and the data is confidential (via AES encryption) all achieved without an OAuth server or user identity, suitable for internal microservice-to-microservice protection.

  6. Challenge

    Conclusion and Next Steps

    Congratulations!

    You have successfully implemented layered security across microservices using:

    • API keys to restrict access to trusted callers
    • HMAC signatures to ensure message integrity
    • AES encryption to protect sensitive data during transmission

    Together, these mechanisms help ensure that:

    • Only authorized services can communicate
    • Payloads are protected from tampering
    • Data remains confidential throughout its journey

    What to Explore Next

    To strengthen your setup further, consider the following enhancements:

    • Rate Limiting and Monitoring - Protect services from abuse and detect anomalies by monitoring API usage and enforcing request limits.

    • Key Rotation - Regularly update API keys and encryption secrets to minimize risks from accidental leaks or misuse.

    • Mutual TLS (mTLS) - Add two-way certificate authentication to validate both the client and the server at the transport layer.

    This lab demonstrated how internal service-to-service communication can be secured without relying on OAuth or external identity providers. By layering simple yet effective techniques, you have built a solid foundation for secure microservice integration.

    Continue to evolve this model by combining these patterns with transport-level protections and service mesh capabilities. Security is most effective when applied in layers, each reinforcing the other to keep your systems resilient and trustworthy.

Amar Sonwani is a software architect with more than twelve years of experience. He has worked extensively in the financial industry and has expertise in building scalable applications.

What's a lab?

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Provided environment for hands-on practice

We will provide the credentials and environment necessary for you to practice right within your browser.

Guided walkthrough

Follow along with the author’s guided walkthrough and build something new in your provided environment!

Did you know?

On average, you retain 75% more of your learning if you get time for practice.