TIP: You can type at any time to perform a new search.
Vault
vault · OCA/server-auth
Security findings
- Repository
- OCA/server-auth · module folder · Try on Runboat
- Module version
- 1.0.10
- Category
- Vault
- Folder size
- 0.58 MB
- License
- AGPL-3
- Application
- Yes
- Auto-installable
- No
- Website
- https://github.com/OCA/server-auth
- Last tracking update
- 2026-10-03 23:57:03
- Authors
- Odoo Community Association (OCA), initOS GmbH
- Maintainers
- Odoo Community Association (OCA), initOS GmbH
- Committers
- Cyril VINH-TUNG, Carlos Roca, CarlosRoca13, Jan Suhr, Weblate, OCA-git-bot, oca-ci
- Odoo dependencies
- Python dependencies
- None
- System dependencies
- None
- Required by
- vault_share
- Description
This module implements a vault for secrets and files using end-to-end-encryption. The encryption and decryption happens in the browser using a vault specific shared master key. The master keys are encrypted using asymmetrically. For this the user has to enter a second password on the first login or if he needs to access data in a vault. The asymmetric keys are stored for a certain time in the browser storage. The server can never access the secrets with the information available. Only people registered in the vault can decrypt or encrypt values in a vault. The meta data isn't encrypted to be able to search/filter for entries more easily. This modules requires a secure context for the browser to work properly and therefore HTTPS support is required. The [vault-recovery](https://github.com/fkantelberg/vault-recovery) project focuses on disaster recovery in case of an incident to recover secrets from old database backups or old exports.
Code Analysis
Views touched (28)
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
inbox |
inbox | ir.ui.view | qweb | New |
res_config_settings_view_form |
res.config.settings.view.form | res.config.settings | form | Inherits base_setup.res_config_settings_view_form |
view_res_users_key_form |
res.users.key | form | New | |
view_res_users_key_tree |
res.users.key | list | New | |
view_right_form |
vault.right | form | New | |
view_right_tree |
vault.right | list | New | |
view_users_form_keys_modif |
res.users | form | New | |
view_vault_entry_form |
vault.entry | form | New | |
view_vault_entry_full_tree |
vault.entry | list | New | |
view_vault_entry_overview_form |
vault.entry | form | Inherits view_vault_entry_form | |
view_vault_entry_search |
vault.entry.search | vault.entry | search | New |
view_vault_entry_tree |
vault.entry | list | New | |
view_vault_export_wizard |
vault.export.wizard | form | New | |
view_vault_field_form |
vault.field | form | New | |
view_vault_field_tree |
vault.field | list | New | |
view_vault_file_form |
vault.file | form | New | |
view_vault_file_tree |
vault.file | list | New | |
view_vault_form |
vault | form | New | |
view_vault_import_wizard |
vault.import.wizard | form | New | |
view_vault_inbox_form |
vault.inbox | form | New | |
view_vault_inbox_tree |
vault.inbox | list | New | |
view_vault_log_tree |
vault.log | list | New | |
view_vault_right_overview_search |
vault.right.overview.search | vault.right | search | New |
view_vault_right_overview_tree |
vault.right | list | New | |
view_vault_search |
vault.search | vault | search | New |
view_vault_send_wizard |
vault.send.wizard | form | New | |
view_vault_store_wizard |
vault.store.wizard | form | New | |
view_vault_tree |
vault | list | New |
HTTP endpoints (9)
| Route(s) | Handler | Auth | Type | Methods | Flags |
|---|---|---|---|---|---|
/vault/inbox/get |
Controller.vault_get_inbox |
user | json | ALL | |
/vault/keys/get |
Controller.vault_get_keys |
user | json | ALL | |
/vault/rights/get |
Controller.vault_get_right_keys |
user | json | ALL | |
/vault/inbox/<string:token> |
Controller.vault_inbox |
public | http | ALL | sudo website |
/vault/public |
Controller.vault_public |
user | json | ALL | sudo |
/vault/replace |
Controller.vault_replace |
user | json | ALL | sudo |
/vault/inbox/store |
Controller.vault_store_inbox |
user | json | ALL | |
/vault/keys/store |
Controller.vault_store_keys |
user | json | ALL | |
/vault/rights/store |
Controller.vault_store_right_keys |
user | json | ALL | sudo |
Models touched (19)
New fields (3)
-
group_vault_exportBooleanimplied_group='vault.group_vault_export' args: 'Export Vaults' -
group_vault_importBooleanimplied_group='vault.group_vault_import' args: 'Import Vaults' -
module_vault_shareBoolean
No public methods.
New fields (7)
-
active_keyMany2one → res.users.keycompute='_compute_active_key'store=False args: 'res.users.key' -
inbox_enabledBooleandefault=True -
inbox_idsOne2many → vault.inboxargs: 'vault.inbox', 'user_id' -
inbox_linkCharcompute='_compute_inbox_link'readonly=Truestore=False -
inbox_tokenChardefault=<expr>readonly=True -
keysOne2many → res.users.keyreadonly=True args: 'res.users.key', 'user_id' -
vault_right_idsOne2many → vault.rightreadonly=True args: 'vault.right', 'user_id'
-
action_get_vault(self)@api.model -
action_invalidate_key(self)Disable the current key and remove all accesses to the vaults -
action_new_inbox_token(self) -
find_user_of_inbox(self, token)@api.model -
get_vault_keys(self)
New fields (10)
-
currentBooleandefault=Truereadonly=True -
fingerprintCharcompute='_compute_fingerprint'store=True -
iterationsIntegerreadonly=Truerequired=True -
ivCharreadonly=Truerequired=True -
privateCharreadonly=Truerequired=True -
publicCharreadonly=Truerequired=True -
saltCharreadonly=Truerequired=True -
user_idMany2one → res.usersrequired=True args: 'res.users' -
uuidChardefault=<expr>readonly=Truerequired=True -
versionIntegerreadonly=True
-
extract_public_key(self, user) -
store(self, iterations, iv, private, public, salt, version)
New fields (17)
-
allowed_createBooleancompute='_compute_access'store=False -
allowed_deleteBooleancompute='_compute_access'store=False -
allowed_readBooleancompute='_compute_access'store=False -
allowed_shareBooleancompute='_compute_access'store=False -
allowed_writeBooleancompute='_compute_access'store=False -
entry_idsOne2many → vault.entryargs: 'vault.entry', 'vault_id', 'Entries' -
field_idsOne2many → vault.fieldargs: 'vault.field', 'vault_id', 'Fields' -
file_idsOne2many → vault.fileargs: 'vault.file', 'vault_id', 'Files' -
log_idsOne2many → vault.logreadonly=True args: 'vault.log', 'vault_id', 'Log' -
master_keyCharcompute='_compute_master_key'inverse='_inverse_master_key'store=False -
nameCharrequired=True -
noteText -
perm_userMany2one → res.userscompute='_compute_access'store=False args: 'res.users' -
reencrypt_requiredBooleandefault=False -
right_idsOne2many → vault.rightdefault=<expr> args: 'vault.right', 'vault_id', 'Rights' -
user_idMany2one → res.usersdefault=<expr>readonly=Truerequired=True args: 'res.users', 'Owner' -
uuidChardefault=<expr>readonly=Truerequired=True
-
action_open_export_wizard(self) -
action_open_import_wizard(self) -
share_public_keys(self)
New fields (0)
No new fields.
Public methods (6)-
check_access(self, operation) -
log_entry(self, msg) -
log_error(self, msg) -
log_info(self, msg) -
log_warn(self, msg) -
raise_access_error(self)@api.model
New fields (12)
-
allowed_createBooleanrelated='vault_id.allowed_create'store=False -
allowed_deleteBooleanrelated='vault_id.allowed_delete'store=False -
allowed_readBooleanrelated='vault_id.allowed_read'store=False -
allowed_shareBooleanrelated='vault_id.allowed_share'store=False -
allowed_writeBooleanrelated='vault_id.allowed_write'store=False -
entry_idMany2one → vault.entryondelete='cascade'required=True args: 'vault.entry' -
entry_nameCharrelated='entry_id.complete_name' -
ivChar -
master_keyCharcompute='_compute_master_key'store=False -
nameCharrequired=True -
perm_userMany2onerelated='vault_id.perm_user'store=False -
vault_idMany2onerelated='entry_id.vault_id'
-
create(self, vals_list)@api.model_create_multi -
log_change(self, action) -
unlink(self) -
write(self, values)
New fields (21)
-
allowed_createBooleanrelated='vault_id.allowed_create'store=False -
allowed_deleteBooleanrelated='vault_id.allowed_delete'store=False -
allowed_readBooleanrelated='vault_id.allowed_read'store=False -
allowed_shareBooleanrelated='vault_id.allowed_share'store=False -
allowed_writeBooleanrelated='vault_id.allowed_write'store=False -
child_idsOne2many → vault.entryargs: 'vault.entry', 'parent_id', 'Child' -
complete_nameCharcompute='_compute_complete_name'readonly=Truerecursive=Truestore=True -
expire_dateDatetimedefault=False args: 'Expires on' -
expiredBooleancompute='_compute_expired'search='_search_expired'store=False -
field_idsOne2many → vault.fieldargs: 'vault.field', 'entry_id', 'Fields' -
file_idsOne2many → vault.fileargs: 'vault.file', 'entry_id', 'Files' -
log_idsOne2many → vault.logreadonly=True args: 'vault.log', 'entry_id', 'Log' -
nameCharrequired=True -
noteText -
parent_idMany2one → vault.entrydomain="[('vault_id', '=', vault_id)]"ondelete='cascade' args: 'vault.entry', 'Parent' -
perm_userMany2onerelated='vault_id.perm_user'store=False -
tagsMany2many → vault.tagargs: 'vault.tag' -
urlChar -
user_idMany2onerelated='vault_id.user_id' -
uuidCharcopy=Falsedefault=<expr>required=True -
vault_idMany2one → vaultondelete='cascade'required=True args: 'vault', 'Vault'
-
action_open_export_wizard(self) -
action_open_import_wizard(self) -
copy_data(self, default=None) -
create(self, vals_list)@api.model_create_multi -
log_change(self, action) -
search_panel_select_range(self, field_name, **kwargs)@api.modelWe add the following contexts related to searchpanel: - entry_short_name: Show just the name instead of full path. - from_search_panel: It will be used to overwrite domain. Remove the limit of records (default is 200). -
search_read(self, domain=None, fields=None, offset=0, limit=None, order=None)Changes related to searchpanel: - Add a domain to only show records with children. -
unlink(self)
New fields (6)
-
contentBinaryattachment=False args: 'Download' -
entry_idMany2one → vault.entrydomain="[('vault_id', '=', vault_id)]" args: 'vault.entry', 'Entries' -
include_childsBooleandefault=True -
master_keyCharrelated='vault_id.master_key' -
nameChardefault=<expr> -
vault_idMany2one → vaultargs: 'vault', 'Vault'
No public methods.
New fields (1)
-
valueCharrequired=True
No public methods.
New fields (1)
-
valueBinaryattachment=False
-
search_read(self, *args, **kwargs)@api.model
New fields (8)
-
contentBinaryattachment=False args: 'Database' -
crypted_contentChar -
master_keyCharrelated='vault_id.master_key' -
nameChar -
parent_idMany2one → vault.entrydomain="[('vault_id', '=', vault_id)]" args: 'vault.entry', 'Parent Entry' -
pathMany2one → vault.import.wizard.pathdefault=''domain="[('uuid', '=', uuid)]" args: 'vault.import.wizard.path', 'Path to import' -
uuidChardefault=<expr> -
vault_idMany2one → vaultargs: 'vault', 'Vault'
-
action_import(self)
New fields (2)
-
nameCharrequired=True -
uuidCharrequired=True
No public methods.
New fields (12)
-
accessesIntegerdefault=1help="If this is 0 the inbox can't be written using the link" args: 'Access counter' -
expirationDatetimedefault=<expr>help="If expired the inbox can't be written using the link" -
filenameChar -
inbox_linkCharcompute='_compute_inbox_link'help='Using this link you can write to the current inbox. If you want people to create new inboxes you should give them your inbox link from your key management.'readonly=True -
ivCharrequired=True -
keyCharrequired=True -
log_idsOne2many → vault.inbox.logreadonly=True args: 'vault.inbox.log', 'inbox_id', 'Log' -
nameCharrequired=True -
secretCharreadonly=True -
secret_fileBinaryattachment=Falsereadonly=True -
tokenCharcopy=Falsedefault=<expr>readonly=True -
user_idMany2one → res.usersrequired=True args: 'res.users', 'Vault'
-
find_inbox(self, token)@api.model -
read(self, *args, **kwargs) -
store_in_inbox(self, name, secret, secret_file, iv, key, user, filename, ip=None)
New fields (2)
-
inbox_idMany2one → vault.inboxondelete='cascade'readonly=Truerequired=True args: 'vault.inbox' -
nameCharreadonly=True
No public methods.
New fields (5)
-
entry_idMany2one → vault.entryondelete='cascade'readonly=True args: 'vault.entry', 'Entry' -
messageCharreadonly=Truerequired=True -
stateSelectionreadonly=True args: <expr> -
user_idMany2one → res.usersreadonly=Truerequired=True args: 'res.users', 'User' -
vault_idMany2one → vaultondelete='cascade'readonly=Truerequired=True args: 'vault', 'Vault'
-
create(self, vals_list)@api.model_create_multi
New fields (15)
-
allowed_createBooleanrelated='vault_id.allowed_create'store=False -
allowed_deleteBooleanrelated='vault_id.allowed_delete'store=False -
allowed_readBooleanrelated='vault_id.allowed_read'store=False -
allowed_shareBooleanrelated='vault_id.allowed_share'store=False -
allowed_writeBooleanrelated='vault_id.allowed_write'store=False -
keyChar -
master_keyCharreadonly=Truerelated='vault_id.master_key'store=False -
perm_createBooleandefault=<expr>help='Allow to create in the vault' args: 'Create' -
perm_deleteBooleandefault=<expr>help='Allow to delete a vault' args: 'Delete' -
perm_shareBooleandefault=<expr>help='Allow to share a vault with new users' args: 'Share' -
perm_userMany2onerelated='vault_id.perm_user'store=False -
perm_writeBooleandefault=<expr>help='Allow to write to the vault' args: 'Write' -
public_keyCharcompute='_compute_public_key'readonly=Truestore=False -
user_idMany2one → res.usersdomain=[('keys', '!=', False)]required=True args: 'res.users', 'User' -
vault_idMany2one → vaultondelete='cascade'readonly=Truerequired=True args: 'vault', 'Vault'
-
create(self, vals_list)@api.model_create_multi -
log_access(self) -
unlink(self) -
write(self, values)
New fields (9)
-
filenameChar -
ivCharrequired=True -
keyCharrequired=True -
key_userCharrequired=True -
nameCharrequired=True -
publicCharrelated='user_id.active_key.public' -
secretChar -
secret_fileChar -
user_idMany2one → res.usersdomain=[('keys', '!=', False), ('inbox_enabled', '=', True)]required=True args: 'res.users', 'User'
-
action_send(self)
New fields (9)
-
entry_idMany2one → vault.entrydomain="[('vault_id', '=', vault_id)]"required=True args: 'vault.entry', 'Entry' -
ivCharrequired=True -
keyCharrequired=True -
master_keyCharcompute='_compute_master_key'store=False -
modelCharrequired=True -
nameCharrequired=True -
secretCharrequired=True -
secret_temporaryCharrequired=True -
vault_idMany2one → vaultrequired=True args: 'vault', 'Vault'
-
action_store(self)
New fields (1)
-
nameCharrequired=True
No public methods.
Loading…
Loading…
Loading…
Loading…