diff --git a/README.md b/README.md
index c5a7d87305..337cafdf24 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ Available addons
----------------
addon | version | maintainers | summary
--- | --- | --- | ---
-[auth_api_key](auth_api_key/) | 19.0.1.0.3 | | Authenticate http requests from an API key
+[auth_api_key](auth_api_key/) | 19.0.1.1.0 | | Authenticate http requests from an API key
[auth_api_key_group](auth_api_key_group/) | 19.0.1.0.0 | | Allow grouping API keys together. Grouping per se does nothing. This feature is supposed to be used by other modules to limit access to services or records based on groups of keys.
[auth_oauth_multi_token](auth_oauth_multi_token/) | 19.0.1.0.0 | | Allow multiple connection with the same OAuth account
[auth_oidc](auth_oidc/) | 19.0.1.0.0 | | Allow users to login through OpenID Connect Provider
diff --git a/auth_api_key/README.rst b/auth_api_key/README.rst
index 0b185c4574..cd03129c30 100644
--- a/auth_api_key/README.rst
+++ b/auth_api_key/README.rst
@@ -11,7 +11,7 @@ Auth Api Key
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !! source digest: sha256:13e40ab685d9417f6461852e3c3c37fec5967c3a7a956fdb54b3fcc5f1b42115
+ !! source digest: sha256:e7679893d3301998264999e637352ed54ac21f411be14f01b7f8b2ab102b3b50
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
@@ -70,6 +70,11 @@ The api key menu is available into Settings > Technical in debug mode.
By default, when you create an API key, the key is saved into the
database.
+When you create an API key, a random key is generated automatically. You
+can replace it manually, or use the Generate Random Token button if an
+existing record has no key. The key field is masked by default, and the
+password widget provides a button to reveal the value when needed.
+
When a database is neutralized, stored API key values are cleared.
If you want to manage them via serve environment settings use
diff --git a/auth_api_key/__manifest__.py b/auth_api_key/__manifest__.py
index 856447f9dc..9f480f74f5 100644
--- a/auth_api_key/__manifest__.py
+++ b/auth_api_key/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Auth Api Key",
"summary": """
Authenticate http requests from an API key""",
- "version": "19.0.1.0.3",
+ "version": "19.0.1.1.0",
"license": "LGPL-3",
"author": "ACSONE SA/NV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/server-auth",
diff --git a/auth_api_key/i18n/auth_api_key.pot b/auth_api_key/i18n/auth_api_key.pot
index 910901518c..00b53accdb 100644
--- a/auth_api_key/i18n/auth_api_key.pot
+++ b/auth_api_key/i18n/auth_api_key.pot
@@ -78,6 +78,11 @@ msgstr ""
msgid "Display Name"
msgstr ""
+#. module: auth_api_key
+#: model_terms:ir.ui.view,arch_db:auth_api_key.auth_api_key_form_view
+msgid "Generate Random Token"
+msgstr ""
+
#. module: auth_api_key
#: model:ir.model,name:auth_api_key.model_ir_http
msgid "HTTP Routing"
diff --git a/auth_api_key/i18n/it.po b/auth_api_key/i18n/it.po
index 4a8682150d..6786d9b125 100644
--- a/auth_api_key/i18n/it.po
+++ b/auth_api_key/i18n/it.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
-"PO-Revision-Date: 2026-07-20 08:46+0000\n"
+"PO-Revision-Date: 2026-07-27 11:46+0000\n"
"Last-Translator: mymage \n"
"Language-Team: none\n"
"Language: it\n"
@@ -81,6 +81,11 @@ msgstr "Disabilita la chiave API quando si archivia un utente"
msgid "Display Name"
msgstr "Nome visualizzato"
+#. module: auth_api_key
+#: model_terms:ir.ui.view,arch_db:auth_api_key.auth_api_key_form_view
+msgid "Generate Random Token"
+msgstr "Genera token casuale"
+
#. module: auth_api_key
#: model:ir.model,name:auth_api_key.model_ir_http
msgid "HTTP Routing"
diff --git a/auth_api_key/i18n/ja.po b/auth_api_key/i18n/ja.po
index baf16ead11..2f6c91489f 100644
--- a/auth_api_key/i18n/ja.po
+++ b/auth_api_key/i18n/ja.po
@@ -79,6 +79,11 @@ msgstr ""
msgid "Display Name"
msgstr ""
+#. module: auth_api_key
+#: model_terms:ir.ui.view,arch_db:auth_api_key.auth_api_key_form_view
+msgid "Generate Random Token"
+msgstr ""
+
#. module: auth_api_key
#: model:ir.model,name:auth_api_key.model_ir_http
msgid "HTTP Routing"
diff --git a/auth_api_key/i18n/zh_CN.po b/auth_api_key/i18n/zh_CN.po
index dd912a4421..e4f022d4ce 100644
--- a/auth_api_key/i18n/zh_CN.po
+++ b/auth_api_key/i18n/zh_CN.po
@@ -79,6 +79,11 @@ msgstr ""
msgid "Display Name"
msgstr ""
+#. module: auth_api_key
+#: model_terms:ir.ui.view,arch_db:auth_api_key.auth_api_key_form_view
+msgid "Generate Random Token"
+msgstr ""
+
#. module: auth_api_key
#: model:ir.model,name:auth_api_key.model_ir_http
msgid "HTTP Routing"
diff --git a/auth_api_key/models/auth_api_key.py b/auth_api_key/models/auth_api_key.py
index ee8564a6f1..63eef6b735 100644
--- a/auth_api_key/models/auth_api_key.py
+++ b/auth_api_key/models/auth_api_key.py
@@ -1,6 +1,8 @@
# Copyright 2018 ACSONE SA/NV
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
+import secrets
+
from odoo import api, fields, models, tools
from odoo.exceptions import AccessError, ValidationError
from odoo.tools import consteq
@@ -12,6 +14,7 @@ class AuthApiKey(models.Model):
name = fields.Char(required=True)
key = fields.Char(
+ default=lambda self: self._generate_random_key_value(),
help="""The API key. Enter a dummy value in this field if it is
obtained from the server environment configuration.""",
)
@@ -36,6 +39,28 @@ def _check_key_required(self):
if not api_key.key:
raise ValidationError(self.env._("The API key is required."))
+ @api.model
+ def _generate_random_key_value(self):
+ """Return a random API key value.
+
+ The token is generated by the Odoo server instance so XML data and the
+ UI button can create a secret without storing any default value in the
+ module sources.
+ """
+ return secrets.token_urlsafe(32)
+
+ def generate_random_key(self, api_key_ids=None):
+ """Generate a key for records that do not have one yet.
+
+ :param list api_key_ids: optional record IDs, mainly used by XML data
+ function calls where the method is invoked on the model.
+ :return: True when the operation completed.
+ """
+ api_keys = self.browse(api_key_ids) if api_key_ids else self
+ for api_key in api_keys.filtered(lambda record: not record.key):
+ api_key.key = api_key._generate_random_key_value()
+ return True
+
@api.model
def _retrieve_api_key(self, key):
return self.browse(self._retrieve_api_key_id(key))
diff --git a/auth_api_key/readme/CONFIGURE.md b/auth_api_key/readme/CONFIGURE.md
index d333318925..12f823bb97 100644
--- a/auth_api_key/readme/CONFIGURE.md
+++ b/auth_api_key/readme/CONFIGURE.md
@@ -2,6 +2,11 @@ The api key menu is available into Settings \> Technical in debug mode.
By default, when you create an API key, the key is saved into the
database.
+When you create an API key, a random key is generated automatically. You
+can replace it manually, or use the Generate Random Token button if an
+existing record has no key. The key field is masked by default, and the
+password widget provides a button to reveal the value when needed.
+
When a database is neutralized, stored API key values are cleared.
If you want to manage them via serve environment settings use
diff --git a/auth_api_key/static/description/index.html b/auth_api_key/static/description/index.html
index 0aec51591d..2eb3f9372f 100644
--- a/auth_api_key/static/description/index.html
+++ b/auth_api_key/static/description/index.html
@@ -372,7 +372,7 @@
Auth Api Key
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!! source digest: sha256:13e40ab685d9417f6461852e3c3c37fec5967c3a7a956fdb54b3fcc5f1b42115
+!! source digest: sha256:e7679893d3301998264999e637352ed54ac21f411be14f01b7f8b2ab102b3b50
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
The api key menu is available into Settings > Technical in debug mode.
By default, when you create an API key, the key is saved into the
database.
+
When you create an API key, a random key is generated automatically. You
+can replace it manually, or use the Generate Random Token button if an
+existing record has no key. The key field is masked by default, and the
+password widget provides a button to reveal the value when needed.
When a database is neutralized, stored API key values are cleared.
If you want to manage them via serve environment settings use
auth_api_key_server_env.