惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
A
About on SuperTechFans
J
Java Code Geeks
G
Google Developers Blog
L
LangChain Blog
小众软件
小众软件
宝玉的分享
宝玉的分享
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
博客园 - 【当耐特】
IT之家
IT之家
F
Fortinet All Blogs
aimingoo的专栏
aimingoo的专栏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
博客园 - Franky
博客园_首页
雷峰网
雷峰网
Microsoft Security Blog
Microsoft Security Blog
Vercel News
Vercel News
B
Blog
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell

Cerbos - All Posts

Authentik vs Keycloak: Self-hosted IdP comparison Mapping business requirements to authorization policy for automotive Fine-grained authorization for AI gateways EIC 2026: Stop counting agents, protect what they can touch Agent skill for writing authorization policies in Claude Desktop Identity security in 2026 EIC 2026 takeaways: the identity stack built for humans will not hold up for AI agents Already have authentication? Here's the authorization layer you still need. Tokens are authorization decisions: a guide to policy-driven token issuance What is a Runtime Authorization Platform It's a dimmer switch, not a kill switch. How CISOs are rethinking AI agent governance From maps to bitmaps (and from bitmaps to bitmaps) AuthZEN, Shared Signals, SCIM Events, IPSIE: Notes from the OpenID Enterprise Panel How do you update authorization policies without redeploying your application? IIW42 recap: Where agent authorization got real Cerbos PDP v0.52.0/v0.53.0: Engine performance, security hardening, and CEL path functions Authorization Management Platforms: what they do, how they work, and where they fit PocketOS AI coding agent deleted a production database in 9 seconds Non-Human Identity management still has a blind spot Supabase alternative in 2026: Best open source auth options Benefits of on-premise authorization: Why enterprises are moving toward self-hosted Authorization policies: How to write, test, and validate them (faster with AI) Agent skill for writing authorization policies How much does it cost to build authorization in-house? Why centralized authorization governance reduces incident response time OPA alternative Why AI agents make authorization a right now problem Modernizing legacy application authorization: why it’s your biggest security blind spot How to add authorization to legacy applications without code changes 5 authorization blind spots auditors find, and how to fix them
How to add global authorization for Python microservices
Milap Neupane · 2022-12-15 · via Cerbos - All Posts

Microservices-oriented architecture has evolved from a buzzword to standard architecture practice for building large-scale applications. Applications are designed as blocks of independently deployable services and communicate with each other via lightweight mechanisms.

Microservices offer a lot of advantages, including flexible language selection, functionality-based scalability, independent deployment and independent product development teams. They can, however, bring challenges as well. One of those challenges is authentication and authorization of resources.

If an authorization mechanism is implemented as a global shared provider, it will help remove duplication, freeing the development team to focus on the business logic. In this tutorial, you will be building REST API endpoints in Python and adding resource access permissions to these endpoints using Cerbos.

If an authorization mechanism is implemented as a global shared provider, it will help remove duplication, freeing the development team to focus on the business logic.

In this tutorial, you will be building REST API endpoints in Python and adding resource access permissions to these endpoints using Cerbos.

Building a RESTful API

You will be building RESTful APIs on Python with permission management. To get started with this tutorial, make sure you have the following prerequisites:

In this tutorial, you will be creating REST APIs for the TODO service. The APIs will be built using Flask web framework.

Initialize the API by importing the Flask module into your application:

from flask import Flask
from flask_restful import Resource, Api, reqparse

app = Flask(__name__)
api = Api(app)

The API you’re building will have Create, Update, Read, and Delete REST API endpoints.

Now add the API endpoints for the TODO resource:

from flask import Flask
from flask_restful import Resource, Api, reqparse

app = Flask(__name__)
api = Api(app)

class TODO(Resource):
	pass

api.add_resource(TODO, '/todo')

Here you’ve added a TODO class that will contain all the necessary methods to handle the request to the provided routes. The line api.add_resource(TODO, '/todo') is to define the routes from which the API will be accessed.

Once you have the resource, add the methods to handle the GET, POST, PUT, EDIT requests:

class TODO(Resource):
    def get(self):
        return {'data': 'data'}, 200

api.add_resource(TODO, '/todo')

Before running the Python file, make sure to install the Flask and flask_restful dependencies:

> pip3 install Flask
> pip3 install flask_restful

Now you can start the Flask server by running the main.py file:

> python3 main.go

This will start the Flask app in the default port 5000. To check the GET /todo API, use the curl command:

> curl http://127.0.0.1:5000/todo
#=> {"data": "data"}

Now that you have the server up and running, add the remaining endpoints create, update, delete including authentication.

Authentication

class TODO(Resource):
    @app.route("/todo/<string:id>")
    def get(id):
        if not TODO.__authenticate(request.headers["token"]):
            return {'message': 'API key invalid'}, 401

        return {'data': id}, 200

    def post(self):
        if not TODO.__authenticate(request.headers['TOKEN']):
            return {'message': 'API key invalid'}, 401

        return {'message': 'success'}, 201

    @app.route("/todo/<string:id>", methods = ['PUT'])
    def put(id):
        if not TODO.__authenticate(request.headers['TOKEN']):
            return {'message': 'API key invalid'}, 401

        return {'data': id}, 200

    @app.route("/todo/<string:id>", methods = ['DELETE'])
    def delete(self):
        if not TODO.__authenticate(request.headers['TOKEN']):
            return {'message': 'API key invalid'}, 401

        return {'message': id}, 200
    
    def __authenticate(token):
        if token in Tokens:
            return True
        else:
            return False

api.add_resource(TODO, '/todo')

The API key for the users is managed in a dict. Create a new file resources.py with the API tokens. This file is imported by the main file to check if the token is valid.

# format => { "token": "userid" }
Tokens = {
	"user1SecretToken": "1",
	"user2SecretToken": "2",
	"user3SecretToken": "3"
}

Here you can see that an authentication mechanism is added to check if the API key provided by the user is valid. If the token is invalid, the user will receive the message “API key invalid.”

The next step is to add an authorization mechanism in the API. You will need to set up the following authorization policies.

Authorization

GET

  • User with admin role can get their todo or any other user’s todo
  • User with user role can get only their todo and cannot get other users’ todo

CREATE

  • User with user or admin role can create a todo for self

UPDATE

  • User with admin role can update their todo or any other user’s todo
  • User with user role can update only their todo and cannot update other users’ todo

DELETE

  • User with admin role can delete any todo
  • User with user role cannot delete any todo

I will be using Cerbos for authorization of the user requests. Cerbos helps you to authorize by defining context-aware access control policies for your application resources.

There are three steps to add managing your permissions using Cerbos:

  1. Deploy and run Cerbos
  2. Define your policies
  3. Check permissions

Run Cerbos

Create a policies directory where all the policies will be stored:

mkdir -p cerbos-bin/policies

Start the Cerbos server using the container image.

docker run --rm --name cerbos -d -v $(pwd)/cerbos-bin/policies:/policies -p 3592:3592 ghcr.io/cerbos/cerbos:0.4.0

This will start the Cerbos server in port 3592. Navigate to the port, where you can see documentation about the Cerbos API. You can also try out the API from the web page.

Define Your Policies

The policies will be defined in a user-friendly YAML format. Not only developers, but any non-technical person can go through the YAML file and understand the defined policies, which are found in a central place and easy to manage.

Create a file derived_roles.yml inside the cerbos-bin/policies directory:

---
apiVersion: "api.cerbos.dev/v1"
derived_roles:
  name: todo_derived_roles
  definitions:
    - name: admin
      parentRoles: ["admin"]

    - name: user_that_owns_the_record
      parentRoles: ["user"]
      condition:
        match:
          expr: request.resource.attr.user == request.principal.id

    - name: any_user
      parentRoles: ["user"]

There are three derived roles created to which the policies will be attached. Create a file resource_policy.yml to store the resource policies:

---
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "default"

  importDerivedRoles:
  - todo_derived_roles

  resource: todo
  rules:
  - actions: ["*"]
    effect: EFFECT_ALLOW
    roles:
    - admin

  - actions: ["create", "view", "update"]
    derivedRoles:
    - user_that_owns_the_record
    effect: EFFECT_ALLOW

  - actions: ["view"]
    derivedRoles:
    - any_user
    effect: EFFECT_ALLOW
    condition:
      match:
        expr: request.resource.attr.public == "true"

Check Permissions

The final step is to check the permissions in the API endpoint to validate if the user is authorized to access the TODO resource.

Create a generic Python file that will handle the permission check. To check the permission, make an API call to the Cerbos server with data about the user, their attributes, and the role of the user in a JSON format. Modify the get method to include the permissions check using Cerbos:

  from flask import Flask, request
  from flask_restful import Resource, Api, reqparse
  from resources import Tokens, TodoItems, Users

  import cerbos
  import uuid

  def get(id):
    if not TODO.__authenticate(request.headers["token"]):
      return {'message': 'API key invalid'}, 401
    # Initialize cerbos client
    client = cerbos.Client(host=CERBOS_URL)
    # initialize the resource instance which is being accessed
    todo_request = cerbos.ResourceInstance(
        attr=TodoItems[id]
    )
    # Initialize the principal
    userId = Tokens[request.headers["token"]]
    user = Users[userId]
    principal = cerbos.Principal(
        id=userId,
        roles=[user["role"]],
        attr=user,
    )
    # Check the user is permitted to access the resource
    if not TODO.check(client, principal, "view", todo_request):
      return { 'data': 'Not authorized' }, 401
    
    return {'data': id}, 200

  def check(
        client: cerbos.Client,
        principal: cerbos.Principal,
        action: str,
        resource: cerbos.ResourceInstance,
    ):
        # Build the Cerbos request
        request = cerbos.CheckResourceSetRequest(
            request_id=str(uuid.uuid4()),
            actions=[action],
            principal=principal,
            resource=cerbos.ResourceSet(
                kind="todo", instances={resource.attr["id"]: resource}
            ),
        )
        try:
            # Make a Cerbos request
            response = client.check_resource_set(request)

            # Check whether the Cerbos response indicates that this action is allowed
            return response.is_allowed(resource.attr["id"], action)
        except cerbos.ClientException as e:
            print(f"Request failed: {e.msg}")

Note: The generic implementation for Cerbos check and calls can be found in the GitHub repo.

In the resource.py file, add the Users resource and the TodoItems resource.

TodoItems = {
	"1": {
    	"id": "1",
    	"user": "1",
    	"title": "learn python",
    	"status": "completed",
    	"public": "false"
	},
	"2": {
    	"id": "2",
    	"user": "1",
    	"title": "learn flask",
    	"status": "in_progress",
    	"public": "false"
	},
	"3": {
    	"id": "3",
    	"user": "1",
    	"title": "learn cerbos",
    	"status": "in_progress",
    	"public": "false"
	},
	"4": {
    	"id": "4",
    	"user": "2",
    	"title": "learn cerbos",
    	"status": "in_progress",
    	"public": "false"
	},
	"5": {
    	"id": "5",
    	"user": "1",
    	"title": "learn cerbos",
    	"status": "in_progress",
    	"public": "true"
	}
}

Users = {
	"1": {
    	'role': 'user',
	},
	"2": {
    	'role': 'user',
	},
	"3": {
    	'role': 'admin',
	}
}

These resources would ideally be in a database, but for simplicity I am adding them to a file.

Now try to access the TODO resource with the token of a user. I am using Postman to make the requests.

When User 2 Tries to Access Resource 4

Resource 4 belongs to user 2, so the user should be able to access the resource:ok

When User 2 Tries to Access Resource 5

Resource 5 belongs to user 1 but is a public resource. In the policy file, I have defined the policy to “view” public resources to everyone, so the user will be able to access it:public_resource

When User 2 Tries to Access Resource 3

Resource 3 belongs to user 1 and is not a public resource, so the user will not be able to access it:public_resource

Similarly, you can add the check to all the remaining endpoints and validate the authorization of the resources. The complete code can be found in the GitHub repo. You can play around by changing the policies and see how it changes the resource access permission.

Conclusion

While designing your API, permission management is a key functionality to keep in mind for the security of the resources. If any permission checks are missing, you will be compromising the data of your platform. It is important to have a proper permission check for each resource, but you also do not want to spend a lot of time thinking about permissions while developing each API. The permission check should be easy to implement and easy to test.

Using an external provider like Cerbos is a smart choice because it helps to centralize permission management in an easy-to-understand format. This solves the access permissions problem for developers and non-technical users alike.