BI Datasources
Connect your Odoo (PostgreSQL) database so Veya can answer analytics questions from your own books
Overview
Apps → Datasources is where you connect the databases Veya's analytics answers come from. The supported source today is PostgreSQL running Odoo (versions 13 through 18). Veya reads your posted invoices, vendor bills and general-ledger lines, syncs them into your private warehouse, and Ask Veya answers from that — never by querying your production database at question time.
Sync is read-only: Veya never writes to your database. Give it a role that can only SELECT.
What gets synced
| Layer | Odoo tables | Used for |
|---|---|---|
| Invoice lines | account_move (posted customer invoices) + account_move_line product lines | Revenue by customer, product, category, salesperson |
| Bill lines | account_move (posted vendor bills) + account_move_line | Spend by vendor and account, cost of revenue vs expenses, margin |
| GL lines | account_move_line on P&L accounts | Totals that tie to your Profit & Loss |
Amounts are taken in your company currency (the ledger's converted balance), so multi-currency invoices sum correctly.
Main company only (for now). An Odoo database often holds several legal entities. Veya syncs the main company — the one Odoo marks as base.main_company, which is the company your Profit & Loss reports on — so totals tie to your books. The test result names it (syncing main company "…"). Choosing additional companies per connection is coming soon.
The first sync is full: it reads your whole history. After that each sync is incremental — only rows changed since the last run. Turn on Daily to sync automatically overnight (in your organisation's timezone), or press Sync whenever you want it refreshed. Full re-sync (in the row's menu) rebuilds the warehouse from scratch if you ever need to repair it.
The connection form
The form has the same two security choices you may know from tools like Airbyte:
| Setting | Options | Meaning |
|---|---|---|
| SSL mode | verify-full (default), verify-ca, disable | TLS on the database connection itself. disable is only allowed together with an SSH tunnel. |
| SSH tunnel method | No tunnel, SSH key authentication, SSH password authentication | Whether Veya reaches the database directly, or through an SSH login on a server you control. |
Pick the combination that matches your server:
- Odoo on a VPS / your own server (the common case): SSH tunnel + SSL
disable. Nothing new is opened on your firewall — Veya logs in over SSH like an administrator would, and reaches Postgres on127.0.0.1from there. The SSH session encrypts the link. - Managed Postgres with its own public hostname and certificate (cloud database services): No tunnel + SSL
verify-full(orverify-caif the provider uses a private CA).
Veya always verifies the server certificate when TLS is on; unverified TLS modes (require, prefer) are deliberately not offered, because they accept any certificate and leave credentials exposed to interception.
Option A — SSH tunnel (recommended for a VPS)
Veya opens an SSH session to your server and, inside it, a TCP forward to the database. You need: an SSH login for Veya, TCP forwarding allowed for that login, and the database reachable from the server itself.
1. Create a read-only database role
As the postgres superuser, replacing the database name and choosing a strong password:
CREATE ROLE veya_readonly LOGIN PASSWORD '<strong-password>';
GRANT CONNECT ON DATABASE odoo TO veya_readonly;
\c odoo
GRANT USAGE ON SCHEMA public TO veya_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO veya_readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO veya_readonly;Postgres only needs to listen on localhost — the default. If pg_hba.conf restricts local TCP connections, make sure this line (or an equivalent) is present:
host odoo veya_readonly 127.0.0.1/32 scram-sha-2562. Create an SSH login for Veya
A dedicated system user with no shell is enough — it only ever forwards a port:
sudo useradd -m -s /usr/sbin/nologin veyaKey authentication (recommended). Generate a key pair on your own machine, put the public half on the server, and paste or upload the private half in Veya:
ssh-keygen -t ed25519 -f veya_tunnel_key -C "veya-bi"
# copy veya_tunnel_key.pub to the server:
sudo mkdir -p /home/veya/.ssh
sudo cp veya_tunnel_key.pub /home/veya/.ssh/authorized_keys
sudo chown -R veya:veya /home/veya/.ssh
sudo chmod 700 /home/veya/.ssh && sudo chmod 600 /home/veya/.ssh/authorized_keysVeya stores the private key encrypted and never shows it again.
Password authentication. Set a password on the veya user (sudo passwd veya) and make sure PasswordAuthentication yes is set in sshd_config — at least for that user.
3. Allow TCP forwarding for that login
In /etc/ssh/sshd_config (or a file under sshd_config.d/), restrict the veya user to forwarding only:
Match User veya
AllowTcpForwarding yes
PermitOpen 127.0.0.1:5432
X11Forwarding no
AllowAgentForwarding no
PermitTTY no
ForceCommand /bin/falseThen reload SSH: sudo systemctl reload ssh (or sshd).
PermitOpen pins the login to the one address it needs; ForceCommand /bin/false means the account can open a tunnel but never run a command.
4. Fill in the form
- Host
127.0.0.1, Port5432— the database's address as seen from your server, not from the internet. - Database, User
veya_readonly, Password. - SSL mode
disable. - SSH tunnel method
SSH key authentication(or password). - SSH jump server host your server's public hostname or IP, SSH port
22(or your custom port), SSH login usernameveya, and the private key (paste or Upload file) or password.
Press Test connection. A successful test reports the Odoo version it detected (for example Connected — Odoo 16.0 detected) and confirms every table and column the sync reads is present — so green means the sync will run.
Option B — Direct connection with TLS
Use this when the database has a public hostname and a certificate for that hostname. Veya connects straight to it; nothing else sits in between.
-
Create the read-only role exactly as in Option A, step 1.
-
Turn on TLS in
postgresql.conf:listen_addresses = '*' # or the interface Veya will reach ssl = on ssl_cert_file = '/etc/letsencrypt/live/db.example.com/fullchain.pem' ssl_key_file = '/etc/letsencrypt/live/db.example.com/privkey.pem'The certificate must be for the hostname you enter in Veya. The key file must be readable by the
postgresuser only. For a private CA, choose verify-ca in the form and paste the CA's PEM. -
Allow the role over TLS only, from Veya's addresses, in
pg_hba.conf(before any broaderhostrules):hostssl odoo veya_readonly <veya-ip-1>/32 scram-sha-256 hostssl odoo veya_readonly <veya-ip-2>/32 scram-sha-256hostssl(nothost) matches TLS connections only. We share the current list of Veya outbound addresses when you set up the connection. -
Open the Postgres port in your firewall / security group for those addresses only, then
sudo systemctl reload postgresql. -
In the form: host, port, database, role, password; SSL mode
verify-full(orverify-ca+ CA); SSH tunnel methodNo tunnel. Test.
If the test reports that a verified TLS connection could not be established, re-check step 2 (certificate matches the hostname) or use verify-ca with your CA — or switch to Option A, which needs no database-side TLS at all.
Odoo version
Odoo's accounting tables changed shape between major versions (13, 14–15, 16–18). You don't declare a version: Veya reads it from the database at test and sync time, adapts the extraction to the schema it actually finds, and shows the detected version on the datasources list. If the schema can't be read as a supported Odoo layout, the test says which tables or columns are missing.
Security notes
- All secrets (database password, SSH password, SSH private key, CA certificate) are stored encrypted and never returned by the API or shown in the UI. Leaving a secret field blank when editing keeps the stored value.
- Whichever host Veya dials from its own network — the database host without a tunnel, the SSH server with one — must resolve to a public address; Veya refuses private and loopback targets there. Behind a tunnel, the database address is resolved on your server, so
127.0.0.1is expected. - With a tunnel, TLS may be disabled only because the SSH session already encrypts and authenticates the link; without one, TLS is mandatory and certificate-verified.
- Every connection is scoped to your organisation; a connection can only ever load data into your own warehouse.