Integrations
An integration is a saved connection to something outside Waiso — a database, a bucket, an AI account, an API. You set it up once on the project’s Integrations page; after that, scripts, flow steps, the SQL workbench and the AI features use it by name, and nobody types a password into code again.
- Know the kinds of connection and what each one is for
- Add a connection and confirm the secret variables it creates
- Reach a database on a private network through an SSH or Tailscale tunnel
- Test a connection and read what a failure means
What a connection holds
A connection has two halves. The settings — host, port, database, bucket, region, base address — stay on the connection and anyone with access to the page can read them. The credentials — a password, an access key, an API key — are not kept on the connection at all: saving turns each one into a secret variable of the project, and the connection reads it from there every time it is used.
Connections belong to one project. The page lists them as cards you can search and filter by Databases, Storage and Services; a card’s Open takes a database to its SQL workbench, Browse Files takes a bucket to its file browser, and the ⋯ menu holds Test connection, Edit and Delete.
The kinds of connection
| Kind | Group | Used by | Secret variables |
|---|---|---|---|
| PostgreSQL | Databases | SQL scripts, flow SQL steps, the workbench | PG_<NAME>_PASSWORD |
| MySQL | Databases | SQL scripts, flow SQL steps, the workbench | MYSQL_<NAME>_PASSWORD |
| Amazon S3 | Storage | The SDK’s s3 functions, the file browser | S3_<NAME>_ACCESS_KEY_ID, …_SECRET_ACCESS_KEY |
| AI provider | Services | The assistants, the AI step, the AI Scraper | AI_<NAME>_API_KEY |
| API (HTTP) | Services | The flow’s HTTP Request step | Depends on the sign-in |
| Services | The flow’s Email step, the Email page | One per provider credential |
The AI provider and API (HTTP) kinds have their own pages: Connect an AI provider and API (HTTP) connections. Email is a service you switch on here and configure on its own page — see Email.
Add a connection
- Open the dialog
On Integrations, click Add integration (or right-click an empty area of the page). The dialog Connect a data source lists every kind on the left, grouped and searchable with Search integrations…; About on the right says what each one is for.
- Name it and fill the settings
The Name matters twice: it is how scripts and steps pick the connection, and it names its variables. A database asks for Host, Port (5432 or 3306 filled in), User, Database, Password and SSL mode; or switch to the Connection string tab, paste
postgresql://user:password@host:5432/dbnameand press Apply to fill them. - Choose how to reach a database
Under How to reach the database, keep Direct when it has a public address, or pick SSH tunnel or Tailscale (next section).
- Confirm the variables
Save connection first opens Variables this connection creates, listing the exact names. Click Confirm and save. A name that is already taken is marked already exists — change the connection name, and the save waits until you rename the connection.
Credentials are secret variables
The variable names are derived from the connection’s name, never typed: the kind’s prefix, then the name in capitals with every other character turned into _, then the field. A PostgreSQL connection named Main DB stores its password as PG_MAIN_DB_PASSWORD; an S3 connection named S3 Data gives S3_DATA_ACCESS_KEY_ID and S3_DATA_SECRET_ACCESS_KEY (the prefix is not repeated). Only credentials become variables — host, user and bucket stay settings.
- Editing the connection shows each credential as a chip with the variable’s name — Stored as the secret variable … Click to edit its value. — instead of a password box. Changing the value there or on the Variables page is the same thing: it re-keys the connection.
- Renaming the connection renames its variables; the confirmation lists the names that go away. The values are kept.
- Renaming the variable yourself does not break anything: the connection finds its credential by what it is, not by its name.
- Deleting the variable leaves the connection without a credential. Its card says Credential missing: … — open the connection and enter it again., runs that use it fail with
credential_missing, and typing the value in the connection creates the variable again. - Deleting the connection deletes the variables it made. A connection that scripts still use cannot be deleted: the dialog lists them (Used by …).
Secret values are encrypted at rest with AES-256-GCM and never come back in any list or answer. Like every variable, they also reach your scripts as environment variables — see Variables and secrets.
Databases on a private network
Runs can only reach public addresses. A host on a private network — 10.x, 192.168.x, 172.16–31.x, localhost, link-local or CGNAT ranges — is refused, and the test says so: This host is on a private network (an internal address). Runs cannot reach it — use the database public address. To reach it anyway, pick a tunnel:
| Route | When | What you fill |
|---|---|---|
| Direct | The database has a public address | Nothing more |
| SSH tunnel | Through a bastion host you already have | Bastion host, Port, User, a Private key (with its passphrase) or a Password |
| Tailscale | The database is in your tailnet | An Auth key and, optionally, a Device name |
With a tunnel, Host is the database address as seen from inside the private network. The first test of an SSH tunnel shows the bastion’s fingerprint — Confirm the bastion’s identity, check it with whoever runs the server, and press Trust and test. If that identity changes later, connections stop until you trust the new key. Tunnel secrets are stored as secret variables like every other credential.
Test a connection
Test connection does the real thing: a database test opens a connection and runs a query, an S3 test checks the bucket with your keys, an AI test sends one tiny request. The card then shows Connected or Failed with the time, and a failure gives a reason in plain words — the tunnel could not open, the database refused the credentials, the host did not answer. Databases and buckets are re-tested by themselves when you open the page and their last test is more than five minutes old; AI providers are tested only when you press the button, because a test spends your own quota.
Codes you may meet
credential_missing— the connection’s secret variable was deleted. Open the connection and enter the value again.host_not_allowed— an outbound address the worker refused because it is private: a custom SMTP host, a file uploaded from an internal URL.variable_name_taken— a variable with one of the derived names already exists. Rename the connection.
Limits and rules
- A connection’s kind cannot change after it is created (Integration type cannot be changed after creation).
- One S3 connection per project: the SDK’s uploads always go to the project’s bucket.
- On the cloud, SQL and S3 connections are counted per plan — Free 1, Pro 3, Team 10, Business unlimited. The dialog says how many you use before you try.
- Your script code never opens a socket: user code runs with no network. Queries and file transfers are done by the worker on the script’s behalf, through the connection.