In Odoo 19, APIs are primarily built using controllers, which act as a bridge between external systems and Odoo’s backend. These controllers define how HTTP requests are handled and allow developers to expose endpoints for integrations such as mobile apps, eCommerce platforms, or third-party services.
While creating APIs is straightforward, securing them is critical. Improperly secured endpoints can expose sensitive data, allow unauthorized access, and compromise the entire system.
In this blog, we will explore how to properly secure API endpoints in Odoo 19 by following best practices and implementing secure controller configurations.
Understanding API Controllers in Odoo 19
In Odoo, API endpoints are created using the @http.route decorator inside a controller class. These controllers handle incoming requests and return responses in JSON or HTTP format.
A basic example:
from odoo import http
from odoo.http import request
class DemoController(http.Controller):
@http.route('/api/data', type='json', auth='public', methods=['POST'])
def get_data(self):
return {"message": "Hello World"}
Controllers define:
- Route (URL path)
- Request type (http, json, jsonrpc)
- Authentication (public, user, none, bearer)
- Allowed HTTP methods
However, using auth='public' without restrictions makes this endpoint insecure.
1. Using Proper Authentication
Authentication is the first layer of security for any API.
Auth Types in Odoo
- auth='public' > Accessible by anyone
- auth='user' > Requires login
- auth='bearer' > Uses API token
- auth='none' > No session handling
Secure Example
@http.route('/api/orders', type='json', auth='user', methods=['POST'])
def get_orders(self):
return {"status": "success"}This ensures only authenticated users can access the endpoint.
2. Implementing Token-Based Authentication
For external integrations, token-based authentication is recommended.
Step 1: Add API Key
from odoo import models, fields
class ResUsers(models.Model):
_inherit = 'res.users'
api_key = fields.Char("API Key")
Step 2: Validate Token
def validate_api_key():
api_key = request.httprequest.headers.get('X-API-KEY')
user = request.env['res.users'].sudo().search([('api_key', '=', api_key)], limit=1)
if not user:
return False
request.update_env(user=user)
return True
Step 3: Secure Route
@http.route('/api/secure-data', type='json', auth='none', methods=['POST'])
def secure_data(self):
if not validate_api_key():
return {"error": "Unauthorized"}
return {"data": "Secure Data"}This ensures only authorized systems can access the API.
3. Avoid Unrestricted Public Controllers
Public controllers are useful for:
- Website pages
- Webhooks
- Public APIs
But they must be used carefully.
Best practice:
- Always validate requests
- Never expose sensitive data
- Limit write operations
Odoo itself warns that public routes should be used cautiously when dealing with data exposure.
4. Restrict HTTP Methods
REST APIs support multiple methods like GET, POST, PUT, and DELETE.
Only enable what is necessary:
@http.route('/api/data', type='json', auth='user', methods=['POST'])This reduces the attack surface.
5. Enforce Access Control (ACLs and Record Rules)
Even if authentication is implemented, access control must still be enforced.
ACL (Access Control List)
Defines:
- Read
- Write
- Create
- Delete permissions
Record Rules
Restrict data visibility per user:
<record id="rule_user_records" model="ir.rule">
<field name="name">User Records</field>
<field name="model_id" ref="model_sale_order"/>
<field name="domain_force">[('user_id', '=', user.id)]</field>
</record>
This ensures users only access permitted data.
6. Avoid Overusing sudo()
Using sudo() bypasses all security rules.
request.env['res.partner'].sudo().search([])
- Use only when necessary
- Combine with validations
7. Input Validation and Data Sanitization
Always validate incoming data before processing.
data = request.jsonrequest
if not data.get('name'):
return {"error": "Name is required"}
Best practices:
- Validate required fields
- Check data types
- Avoid direct SQL queries
8. CSRF Protection
Odoo includes CSRF protection to prevent malicious requests.
- Enabled by default for most controllers
- Can be disabled for external APIs if needed
Example:
@http.route('/api/form', type='http', auth='user', csrf=True)For JSON APIs:
- Use token-based authentication instead
9. Use HTTPS for Secure Communication
Always deploy APIs over HTTPS:
- Prevents data interception
- Secures credentials and tokens
Never expose APIs over HTTP in production.
10. Rate Limiting and Monitoring
Odoo does not provide built-in rate limiting, so external tools should be used:
- Nginx
- API Gateway
- Cloudflare
Also, enable logging:
import logging
_logger = logging.getLogger(__name__)
_logger.info("API accessed by user %s", request.env.user.id)
Monitoring helps detect suspicious activity early.
11. API Versioning for Better Security
Versioning helps maintain compatibility and control API changes:
@http.route('/api/v1/data', type='json', auth='user')
def api_v1(self):
return {"version": "v1"}Versioning allows safer upgrades without breaking existing integrations.
Securing API endpoints in Odoo 19 requires a combination of proper authentication, access control, validation, and infrastructure-level protections. Controllers make it easy to expose APIs, but they must be configured carefully to avoid security risks.
By following best practices such as using token-based authentication, enforcing ACLs, validating inputs, and limiting access, developers can build secure and reliable APIs in Odoo.
A well-secured API not only protects your system but also ensures safe and scalable integrations.
By applying these strategies, you can confidently build secure API endpoints in Odoo 19 while maintaining flexibility and performance.
To read more about How to Configure Odoo REST API Module in Odoo 18, refer to our blog How to Configure Odoo REST API Module in Odoo 18.