The Authorization Landscape Has Changed

Five years ago, if you needed authorization for your application, you had two choices: build it yourself with Open Policy Agent (OPA), or pay enterprise prices for solutions like Axiomatics.

Today, the market has exploded with options. From Google Zanzibar-inspired databases to full-stack authorization platforms, developers have more choices than ever.

But how do you compare them? What actually matters?

I built Metis after years of frustration with existing solutions. This article shares what I learned comparing authorization platforms — not as marketing, but as engineering reality.


What We’re Comparing

I’ll focus on five dimensions that actually matter:

  1. Pricing Model — What you actually pay
  2. Performance — Real latency numbers where available
  3. Attribute Handling — How you get data into authorization decisions
  4. Policy Authoring — How you write and maintain rules
  5. Deployment Model — Where it runs and how you operate it

I’ll compare:

  • Permit.io — Full-stack authorization with excellent UI
  • AuthZed/SpiceDB — Zanzibar-inspired, ReBAC-focused
  • Cerbos — Open-core, YAML-based policies
  • Oso Cloud — Embedded authorization with Polar language
  • Axiomatics — Enterprise XACML solution
  • Metis — My solution (yes, biased, but I’ll stick to facts)

Disclaimer: All pricing and features are from public sources as of January 2025. I’m citing official websites and documentation. If anything is inaccurate, please let me know.


Pricing Comparison

Let’s start with what everything costs. This is based on publicly available pricing pages.

Entry-Level Pricing (Small Team: ~1,000 users)

+------------+-----------------------+-------------------------------+---------------------+ 
| Solution   | Free Tier             | Entry Paid Tier               | Source              | 
+------------+-----------------------+-------------------------------+---------------------+ 
| Permit.io  | Up to 1K MAU          | $150/month (Startup, 10K MAU) | permit.io/pricing   | 
| Cerbos     | Free OSS              | £25/month (100+ principals)   | cerbos.dev/pricing  | 
| Oso Cloud  | Free (deprecated OSS) | $149/month (Pro tier)         | Various sources     | 
| AuthZed    | Free OSS (SpiceDB)    | Cloud plans available         | authzed.com/pricing | 
| Metis      | 14-day trial          | $149/month (5M requests)      | policy.hermesc.gr   | 
| Axiomatics | No free tier          | Not publicly listed           | Not disclosed       | 
+------------+-----------------------+-------------------------------+---------------------+

Key Observations:

  1. Pricing models vary widely: Some charge per user (MAU/principals), others per request
  2. Open source options exist: Cerbos, SpiceDB are fully open source
  3. Entry prices cluster around $150/month for managed services
  4. Axiomatics doesn’t list pricing — typically $50K+ annually based on industry knowledge

Mid-Tier Pricing (Growing Company: 10K-50K users)

+-----------+------------------------+-----------------------------------------+--------------------+ 
| Solution  | Mid-Tier Price         | What's Included                         | Source             | 
+-----------+------------------------+-----------------------------------------+--------------------+ 
| Permit.io | Scales with MAU        | Based on monthly active users           | permit.io/pricing  | 
| Cerbos    | Scales with principals | Based on monthly active principals      | cerbos.dev/pricing | 
| Metis     | $399/month             | 25M requests, 15 engines, 25 connectors | policy.hermesc.gr  | 
| AuthZed   | Custom                 | Dedicated infrastructure pricing        | authzed.com        | 
+-----------+------------------------+-----------------------------------------+--------------------+

Why This Matters:

The pricing model determines predictability. User-based pricing scales with your user count. Request-based pricing scales with API volume. Choose based on your usage pattern.


Performance: What’s Actually Fast?

Performance claims are everywhere. Here’s what’s actually documented:

Documented Performance Numbers

+------------+---------------------+----------------------------------------------------------------------+ 
| Solution   | Claimed Performance | Source/Notes                                                         | 
+------------+---------------------+----------------------------------------------------------------------+ 
| SpiceDB    | 5ms p95             | GitHub - "5ms p95 when scaled to millions of queries/s"              | 
| Metis      | 6.69ms average      | Our production metrics, 99.08% cache hit rate                        | 
| Cerbos     | Sub-millisecond     | Cerbos website - "sub-millisecond policy evaluation" (embedded mode) | 
| Permit.io  | "Zero-latency"      | Marketing claim, actual numbers not disclosed                        | 
| OPA        | 1-5ms               | Local evaluation, but you build everything around it                 | 
| Axiomatics | 50-200ms typical    | Based on implementation experience, not official claims              | 
+------------+---------------------+----------------------------------------------------------------------+

Reality Check:

  • Network latency matters: Local/embedded will always be faster than service calls
  • Cache vs uncached: Most systems rely heavily on caching
  • What’s measured: Is it just policy eval, or end-to-end with data fetching?

At Metis, our 6.69ms includes fetching attributes from external systems in real-time. Most competitors require you to pre-load this data.


The Attribute Problem: How Do You Get Data In?

This is where solutions diverge significantly.

How Each Solution Handles Attributes

Traditional Approach (Most Solutions):

You manually sync attribute data to the authorization system.

Example with Permit.io:

javascript

// You write code to sync user data 
await permit.api.users.sync({ 
  key: "user123", 
  email: "[email protected]", 
  attributes: { 
    department: "engineering", 
    role: "senior", 
    clearance: "secret" 
  } 
});

// Then check permissions
const allowed = await permit.check("user123", "read", "document");

Challenges:

  • Data gets stale (synced hourly? daily?)
  • You write sync logic for every data source
  • Need to handle updates, deletes, cache invalidation

Cerbos Approach:

You pass attributes in each request:

yaml

# Your policy 
apiVersion: api.cerbos.dev/v1 
resourcePolicy: 
  resource: "document" 
  rules: 
    - actions: ['read'] 
      effect: EFFECT_ALLOW 
      condition: 
        match: 
          expr: R.attr.classification == P.attr.clearance

javascript

// You fetch and pass attributes 
const user = await getUserFromDB(userId); 
const doc = await getDocFromDB(docId); 
 
const allowed = await cerbos.check({ 
  principal: { 
    id: userId, 
    attributes: { 
      clearance: user.clearance  // You fetch this 
    } 
  }, 
  resource: { 
    id: docId, 
    attributes: { 
      classification: doc.classification  // You fetch this 
    } 
  } 
});

Challenges:

  • You fetch attributes yourself
  • Every authorization check requires prep work
  • Code couples authorization to your data layer

Metis Approach (Our Differentiator):

You configure connectors once, we fetch automatically:

javascript

// One-time configuration 
await metis.connectors.add({ 
  name: "company_ldap", 
  type: "ldap", 
  url: "ldap://company.com", 
  attributes: ["clearance", "department"] 
});
await metis.connectors.add({ 
  name: "document_db", 
  type: "postgresql", 
  connection: "postgres://...", 
  table: "documents", 
  attributes: ["classification", "owner"] 
});

// Then just check permissions - we fetch attributes in real-time
const allowed = await metis.check({
 user: "[email protected]",
 action: "read",
 resource: "doc-123"
});
// Metis automatically fetches clearance from LDAP and classification from DB

Trade-off:

  • Adds latency (we still hit 6.69ms average with caching)
  • Requires connector configuration
  • But: Zero sync code, always current data

Who Does Real-Time Attribute Fetching?

As far as I can tell from public documentation:

  • ✅ Metis — Built-in, core feature
  • ⚠️ Axiomatics — Policy Information Points (PIPs) can do this, but complex to configure
  • ❌ Most others — Require manual sync or attribute passing

This is our main differentiator.


Policy Authoring: How You Write Rules

Policy Languages Compared

XACML (Axiomatics):

xml

<Policy PolicyId="DocumentAccess"> 
  <Target> 
    <Resources> 
      <Resource> 
        <ResourceMatch MatchId="string-equal"> 
          <AttributeValue>document</AttributeValue> 
          <ResourceAttributeDesignator AttributeId="resource-type"/> 
        </ResourceMatch> 
      </Resource> 
    </Resources> 
  </Target> 
  <Rule RuleId="AllowSameDepartment" Effect="Permit"> 
    <!-- Complex XML continues... --> 
  </Rule> 
</Policy>

Complexity: Very high. Requires XACML expertise.

OPA Rego (Open Policy Agent):

rego

package auth; 
 
allow { 
    input.user.role == "manager" 
    input.user.department == input.document.department 
    input.document.classification != "top-secret" 
}

Complexity: Medium. Logical, but unique syntax.

Cerbos YAML:

yaml

apiVersion: api.cerbos.dev/v1 
resourcePolicy: 
  resource: document 
  rules: 
    - actions: ['read'] 
      effect: EFFECT_ALLOW 
      roles: ['user'] 
      condition: 
        match: 
          expr: R.attr.department == P.attr.department

Complexity: Low-medium. Human-readable, but still requires structure.

Permit.io:

UI-based policy editor — check boxes and forms.

Complexity: Very low for simple cases. UI doesn’t scale to complex policies.

Metis (AI-Assisted):

You describe in natural language, AI generates OPA Rego:

Human: "Managers in the same department can approve expenses under €10,000  
during business hours on weekdays."

Metis AI generates:
```rego
package metis.expense_approvaldefault allow := false

allow if { 
    input.action == "approve" 
    input.resource.type == "expense" 
     
    # Manager role 
    input.user.role == "manager" 
     
    # Same department 
    input.user.department == input.resource.department 
     
    # Amount check 
    input.resource.amount < 10000 
     
    # Business hours (9-17) 
    time.clock([hour, _, _]) 
    hour >= 9 
    hour < 17 
     
    # Weekday 
    time.weekday(time.now_ns()) in [1, 2, 3, 4, 5] 
}

Complexity: Low. Natural language → optimized policy. You can still hand-edit the generated Rego.


Deployment Models

Where Does It Run?

+------------+---------------+---------------+-------------------+----------------+ 
| Solution   | Open Source   | Self-Hosted   | Managed Cloud     | Embedded/Edge  | 
+------------+---------------+---------------+-------------------+----------------+ 
| Cerbos     | ✅ Full OSS   | ✅ Yes        | ✅ Cerbos Hub    | ✅ WASM        | 
| SpiceDB    | ✅ Full OSS   | ✅ Yes        | ✅ AuthZed Cloud | ❌ No          | 
| OPA        | ✅ Full OSS   | ✅ Yes        | ❌ DIY           | ✅ WASM        | 
| Permit.io  | ⚠️ OPAL only  | ⚠️ Limited    | ✅ Primary       | ❌ No          | 
| Metis      | ❌ No         | ✅ Enterprise | ✅ Primary       | ❌ No          | 
| Axiomatics | ❌ No         | ✅ Yes        | ✅ Yes           | ❌ No          | 
+------------+--------------+--------------+-----------------+--------------------+

What This Means:

  • Want full control? Cerbos or SpiceDB open source
  • Want zero ops? Permit.io, Metis, or AuthZed Cloud
  • Want embedded? Cerbos WASM or OPA
  • Enterprise on-prem? Most support this (for $$)

Feature Matrix


Use Case Fit

Choose Permit.io If:

  • You want beautiful UI for non-technical users
  • You need quick setup with UI-driven policies
  • Simple RBAC/ABAC is sufficient
  • You’re okay with manual attribute syncing

Best for: B2B SaaS, teams with non-technical stakeholders managing permissions

Choose SpiceDB/AuthZed If:

  • You’re building Google Docs-style sharing
  • Relationships are more important than attributes
  • You need proven Zanzibar architecture
  • You’re comfortable with operational complexity (if self-hosting)

Best for: Collaboration platforms, document sharing, social features

Choose Cerbos If:

  • You want open source with optional support
  • You like YAML for policies
  • You need embedded/edge deployment (WASM)
  • You want middle ground between DIY and full SaaS

Best for: Teams wanting flexibility, Kubernetes deployments, air-gapped environments

Choose Oso Cloud If:

  • You were using the old Oso OSS and want migration path
  • You like Polar language syntax
  • You need embedded authorization

Best for: Microservices, teams comfortable with policy languages

Choose Metis If:

  • You need real-time attribute freshness (compliance, security)
  • You want AI-assisted policy authoring
  • Your team lacks authorization experts
  • You need fast performance with complex attribute-based rules
  • You’re frustrated with manual data syncing

Best for: Regulated industries, complex ABAC requirements, teams replacing Axiomatics

Choose Axiomatics If:

  • You have $50K+ budget
  • You need battle-tested enterprise solution
  • You have dedicated security team for XACML
  • Compliance requires established vendor

Best for: Large enterprises, defense/gov, heavily regulated industries


The Real Differentiators

After building Metis and studying competitors, here’s what actually matters:

1. The Data Freshness Problem

Most solutions ignore this. They make YOU solve:

  • How do I sync user attributes?
  • How often do I sync?
  • What if data changes between syncs?
  • How do I handle deletions?

Only Axiomatics (PIPs) and Metis (connectors) tackle this directly.

Trade-off: Real-time fetching adds latency. We cache aggressively (99.08% hit rate) to maintain 6.69ms average.

2. Policy Authoring Expertise

XACML requires experts. Rego requires learning. YAML is better, but still technical.

UI builders (Permit.io) are great for simple cases but don’t scale to complex policies.

Our bet: AI can bridge this gap. Generate policies from natural language, then let experts tune.

3. Performance vs Features

Simple systems are fast. Feature-rich systems are slow. Pick your trade-off.

Our approach: AI-generate policies once (slow), compile them (one-time cost), execute them forever (fast).

Think once deeply. Execute swiftly always.

Pricing Reality Check

Let’s get specific about costs for a realistic scenario.

Scenario: Mid-size B2B SaaS company

  • 10,000 monthly active users
  • 50 million authorization checks per month
  • 15 different applications/microservices

Estimated Annual Costs:

Permit.io:

  • Likely need Pro tier: ~$500/month = $6,000/year
  • (Exact pricing depends on MAU count, not publicly detailed)

Cerbos Hub:

  • Based on Monthly Active Principals
  • 10,000 principals: pricing calculator shows **$4,800/year**

Metis:

  • 50M requests fits Business tier: $399/month = $4,788/year
  • Or Professional if requests lower: $149/month = $1,788/year

AuthZed Dedicated:

  • Custom pricing, estimated $24K-$60K/year based on resources

Axiomatics:

  • Estimated $100K-$250K/year based on industry knowledge

DIY with OPA:

  • Software: Free
  • Engineering time: 2–3 months initial build (~$40K)
  • Ongoing maintenance: 20 hours/month ($30K/year)
  • Total Year 1: ~$70K

Total Cost of Ownership (3 Years):

+--------------------+------------+--------------+--------------+ 
| Solution           | Year 1     | Years 2-3    | 3-Year Total | 
+--------------------+------------+--------------+--------------+ 
| Permit.io          | $6,000     | $12,000      | $18,000      | 
| Cerbos             | $4,800     | $9,600       | $14,400      | 
| Metis Business     | $4,788     | $9,576       | $14,364      | 
| Metis Professional | $1,788     | $3,576       | $5,364       | 
| SpiceDB OSS        | $40K (eng) | $60K (maint) | $100K        | 
| AuthZed Dedicated  | $40K       | $80K         | $120K        | 
| Axiomatics         | $100K      | $240K        | $340K        | 
+--------------------+------------+--------------+--------------+

Key Insight: Engineering time is expensive. Managed services save money unless you have dedicated authorization team.


What I Learned Building Metis

After evaluating every solution, here’s what I concluded:

1. There’s No Perfect Solution

  • Want beautiful UI? → Permit.io
  • Want pure ReBAC? → SpiceDB
  • Want full OSS? → Cerbos or OPA
  • Want real-time data? → Metis or Axiomatics
  • Have huge budget? → Axiomatics

2. The Attribute Problem Is Underserved

Most solutions say “just sync your data” and move on. In practice, this is 50–70% of the implementation effort.

Real-time attribute fetching is rare because it’s hard to build performantly. We spent months getting to 6.69ms with real-time fetches.

3. AI Changes The Game

Policy languages exist because computers need precision. But AI can bridge human language to computer language.

This feels like the early days of GitHub Copilot for code. AI-assisted policy authoring will become standard.

4. Performance Numbers Are Marketing

Everyone claims “fast” or “low latency.” Few publish actual numbers.

We publish ours (6.69ms average, 99.08% cache hit) because measurement matters. If a vendor won’t publish performance data, be skeptical.

How To Choose

Ask yourself these questions:

1. What’s your authorization model?

  • Mostly RBAC → Any solution works
  • Heavy ABAC → Metis, Cerbos, or Axiomatics
  • Relationship-focused → SpiceDB

2. How technical is your team?

  • Non-technical stakeholders manage policies → Permit.io
  • Developers only → Any solution
  • No authorization experts → Metis (AI-assisted) or Permit.io (UI)

3. How do you handle attributes?

  • Okay with syncing → Most solutions
  • Need real-time → Metis or build custom with Axiomatics

4. What’s your budget?

  • <$5K/year → Open source (Cerbos, SpiceDB) + engineering time
  • $5K-$20K/year → Managed SaaS (Permit.io, Metis, Oso)
  • $20K-$100K/year → Dedicated hosting (AuthZed) or enterprise
  • $100K+/year → Axiomatics or other enterprise solutions

5. Where does it run?

  • Cloud-native → Most solutions
  • On-premises required → Cerbos, Axiomatics, or enterprise tiers
  • Edge/embedded → Cerbos WASM or OPA

Final Thoughts

Authorization isn’t sexy. It’s not the feature that gets you customers.

But get it wrong, and it becomes a security incident. Get it slow, and it degrades every user interaction. Get it inflexible, and it blocks new features.

The market has matured significantly. In 2020, your options were “build it yourself” or “pay enterprise prices.” In 2025, there are excellent solutions at every price point and use case.

My recommendations:

For startups: Start with Permit.io or Cerbos for quick setup. You can migrate later if needed.

For scale-ups: If growing fast with complex rules, consider Metis or SpiceDB depending on ABAC vs ReBAC needs.

For enterprises: If replacing Axiomatics or building new, evaluate Metis (modern, affordable) or AuthZed Dedicated (proven scale). Keep Axiomatics if you’re already heavily invested.

For engineers: If you have time and expertise, SpiceDB or Cerbos OSS gives you full control. But factor in the engineering cost honestly.


Corrections Welcome

I’ve tried to be factual using only public information. If I’ve misrepresented any solution:

All pricing and features are as of January 2025 from public sources. Technologies evolve quickly — verify current information before making decisions.


About Metis

I built Metis after years of frustration with authorization solutions. The 6.69ms performance with real-time attribute fetching came from months of optimization. The AI policy generation was inspired by watching teams struggle with Rego and XACML.

We’re not trying to be everything to everyone. We’re solving two specific problems:

  1. Real-time attribute freshness without manual syncing
  2. AI-assisted policy authoring for teams without authorization experts

If those are your problems, evaluate us at policy.hermesc.gr.

If they’re not, one of the other solutions listed here is probably better for you.

Sources: