Zero-Trust for microservices, a practical blueprint

Published by Alex Olivier on October 17, 2025
Zero-Trust for microservices, a practical blueprint

Modern application development has embraced distributed systems. Microservices, serverless functions, and now, increasingly, AI agents, all communicate with each other to deliver powerful user experiences. However, this complexity creates a challenge: how do you control what these services and agents are allowed to do?

Traditional authorization has focused on the user. But in a distributed world, we need to answer a more complex question: "Is Service A allowed to access Resource X on behalf of User Y?"

This is where a decoupled authorization system becomes essential. Let's explore how to move from a vulnerable, perimeter-based security model to a granular, zero-trust architecture using Cerbos.

 

The problem: The wild west of workload identity

In many architectures, once a request is inside the network perimeter, it's trusted. An orders service can freely call a payments service, which can call a users service. This "Wild West" approach is a significant security risk. If a single service is compromised, an attacker can move laterally across your entire system.

The first step to securing this is establishing workload identity. Just like users, every service, bot, or automated process needs a unique, verifiable identity. An Identity Provider (IdP) can issue credentials, often in the form of JSON Web Tokens (JWTs), for each workload.

With identities in place, we can now enforce authorization. This is where Cerbos, a decoupled authorization layer, comes in.

Example: A basic workload policy

With Cerbos, you can write a simple, human-readable policy to control which services can communicate. This policy ensures only the employee-service can read review resources, creating workload isolation.

# Filename: policies/review.yml
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "default"
  resource: "review"
  rules:
    - actions: ["read"]
      effect: EFFECT_ALLOW
      # This policy only applies to principals with the "employee-service" role
      roles:
        - "employee-service"

 

On-behalf-of authorization: Merging identities

True zero-trust requires verifying access at every step. We need to check the permissions of both the service making the call and the end-user who initiated the request.

This is the "on-behalf-of" authorization model. The calling service presents two credentials:

  1. Its own workload JWT.
  2. The original user's JWT.

Cerbos can then make a fine-grained decision based on the combined identity context. For example, a policy can state:

  • ALLOW a request if:
    • The principal is the employee-service (verified via its workload JWT).
    • AND the request is on behalf of a user with the hr role (verified via the user's JWT).

This ensures that even a valid service can't perform actions outside the scope of the user it's representing. This logic is encapsulated in a simple, human-readable Cerbos policy, completely separate from your application code.

Example: An on-behalf-of policy

In this scenario, a manager should only see reviews of employees in their own department. The employee-service passes the user's details inside its own principal attributes. Cerbos can inspect this nested context to make a granular decision.

# Filename: policies/review.yml
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "default"
  resource: "review"
  rules:
    # Rule for managers to read reviews within their department
    - actions: ["read"]
      effect: EFFECT_ALLOW
      derivedRoles:
        - manager_in_department
      condition:
        match:
          # Check the department of the user in the "act" attribute against the review's department
          expr: "request.principal.attr.act.user.attr.department == request.resource.attr.department"

    # Rule for HR to read any review
    - actions: ["read"]
      effect: EFFECT_ALLOW
      derivedRoles:
        - hr_user

 

The next frontier: Governing AI agents

AI agents are the next evolution of workloads. They are autonomous, powerful, and need to be treated as untrusted actors. Granting an AI agent broad permissions to your APIs and data is a recipe for disaster.

The solution is to apply the same zero-trust framework. An AI agent is just another identity to be managed and authorized.

  1. Identity: The AI Agent gets its own unique workload identity from the IdP, just like any other service. Its token might contain specific attributes, like principal.type: "AI_AGENT".
  2. Policy: We write a highly restrictive Cerbos policy for the AI, enforcing the Principle of Least Privilege.

Example: A policy for an AI agent

For an AI agent that generates HR reports, the policy can be highly restrictive. This example allows the agent to perform only a single, custom action (read:aggregate) and explicitly denies everything else, preventing it from reading raw records or performing any other action.

# Filename: policies/hr_report.yml
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "default"
  resource: "hr_report"
  rules:
    - actions: ["read:aggregate"]
      effect: EFFECT_ALLOW
      # This policy only applies to the specific AI agent roles
      roles:
        - "ai-reporting-agent"

 

Visibility and observability

A major challenge in microservices is understanding access flows. When a request fails, is it a bug, a network issue, or an authorization failure?

Cerbos provides clear visibility through two key mechanisms:

Centralized policy & audit. Cerbos offers a single source of truth for all authorization logic. The detailed audit logs capture every decision, showing who (or what) was granted or denied access, to what resource, and which policy was responsible. This is crucial for compliance and security investigations.

Centralized policy & audit.png

Observability with OpenTelemetry. Cerbos has native support for OpenTelemetry. This means authorization checks appear as spans in your distributed traces. In tools like Jaeger or Datadog, you can see the exact Cerbos policy evaluation as part of the overall request lifecycle, making it easy for operations and development teams to understand access flows and debug issues.

Observability with OpenTelemetry.png

By moving authorization logic into a dedicated, decoupled service like Cerbos, you can implement a true zero-trust model that scales with your architecture. This enables you to focus on building features, secure in the knowledge that you have granular, context-aware control over every user, service, and AI agent in your system.

If you’re transitioning from a monolithic architecture to microservices, feel free to check out our ebook “Monolith to microservices migration: 10 critical challenges to consider” to guide your migration.

 

TL;DR:

Zero Trust for microservices is a security framework that assumes no user, service, or workload is inherently trustworthy. Every request must be verified and authorized, regardless of its origin. In a microservices architecture, this means applying fine-grained, context-aware controls between every service interaction. Instead of relying on a network perimeter, each call between services, APIs, or AI agents is explicitly authenticated and authorized in real time. With Cerbos, this principle becomes practical: identity and authorization are decoupled from application code, enabling consistent, auditable policy enforcement across a distributed system.

FAQ

What is the fastest way to add Zero-Trust authorization to Kubernetes microservices?

Which authorization engines work well for Zero-Trust in microservices?

How can I secure service-to-service communication in a microservices architecture without adding high latency?

Can a Zero-Trust policy engine such as Cerbos support 10M+ requests per day and 10k+ microservices while keeping p95 latency under 50 ms?

How should AI agents be governed when they call microservice APIs?

How do I implement on-behalf-of authorization for user-initiated requests crossing multiple services?

What components make up a Zero-Trust microservices stack?

How can I avoid vendor lock-in for microservices authorization?

Book a free Policy Workshop to discuss your requirements and get your first policy written by the Cerbos team