# Datlas Connector — setup instructions for agents

You are setting up the **Datlas Connector** inside a company network so that Datlas Enterprise can
reach databases that are not exposed to the internet. Follow these steps exactly and report the
checklist at the end.

## What the connector is

- A small container (`ghcr.io/cendyandreoli/datlas-connector`) that runs next to the databases.
- It makes **only outbound** connections: one TLS WebSocket to `https://app.datlasdb.com` (port 443).
  Nothing listens for inbound traffic. Do **not** open ports or allow-list IPs for Datlas.
- It authenticates with its own Ed25519 key (created at first start, kept in `/data`), runs only
  commands signed by the Datlas server, and answers with signed results.
- Queries run in read-only transactions. Data changes happen only where the organization enabled them
  (Datlas Console → Fontes → "Liberar alterações governadas"), for people whose role allows it, in an explicit
  transaction (COMMIT/ROLLBACK, confirmation in production, at most 1 000 rows, audited). To forbid changes through
  this connector regardless of the console, set `DATLAS_READ_ONLY=true`.
- Database passwords stay on the connector (environment variables or its volume). They are never sent
  to Datlas in plain text.

## Inputs you need before starting

Ask the person who asked you for anything missing. Do not guess.

1. `DATLAS_ENROLL_TOKEN` — one-time registration token from Datlas Console → Conectores. Valid for
   24 hours, single use. Treat it as a secret.
2. The **source names** Datlas expects from this connector (for example `qa` and `prod`). They are
   shown in Datlas Console → Fontes, column "Conexão" ("conector X · fonte `qa`").
3. For each source: host, port, database name, a database user and its password, and the SSL mode.
   Use the database user the person tells you to use. **Do not decide the user's privileges yourself**:
   ask if it is not stated. The database user is the upper limit of what Datlas can do; the console decides
   who can do what within it.
4. A machine that can reach those databases on the network and has Docker. If the databases are only
   reachable through a VPN or private network, the connector must
   run on a machine inside that network.

## Step 1 — Check the machine can reach everything

Run on the machine that will host the connector:

```sh
# database reachability (repeat for each source)
nc -vz <db-host> <db-port>
# outbound HTTPS to Datlas (must print 200 or 302/303)
curl -s -o /dev/null -w '%{http_code}\n' https://app.datlasdb.com/console/login
```

If the database host only resolves or routes inside a VPN or private network, make sure the command
above works **on this machine**, and run the container with
`--network host` so it uses the same DNS and routes.

## Step 2 — Database user

Use the user the person asked for. If they asked for a new user and did not say which privileges, ask
before creating it. Examples, only if asked:

PostgreSQL, read-only user:

```sql
CREATE ROLE datlas_reader LOGIN PASSWORD '<strong password>';
GRANT CONNECT ON DATABASE <database> TO datlas_reader;
GRANT USAGE ON SCHEMA public TO datlas_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO datlas_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO datlas_reader;
```

MySQL / MariaDB, read-only user:

```sql
CREATE USER 'datlas_reader'@'%' IDENTIFIED BY '<strong password>';
GRANT SELECT, SHOW VIEW ON <database>.* TO 'datlas_reader'@'%';
```

What each person can see and do in Datlas is decided by the Datlas permissions (per project and source),
within what this user allows. If the company wants no changes through Datlas at all, add `DATLAS_READ_ONLY=true`.

## Step 3 — Write the environment file

Create `datlas-connector.env` with permission 600 (`chmod 600 datlas-connector.env`). Never commit it.

```sh
DATLAS_ENROLL_TOKEN=<token from the console>
# one pair of lines per source; NAME in the variable becomes the source name (lowercase, _ becomes -)
DATLAS_SOURCE_QA=postgresql://<user>@<qa-host>:5432/<database>?sslmode=require
DATLAS_SOURCE_QA_PASSWORD=<password>
DATLAS_SOURCE_PROD=postgresql://<user>@<prod-host>:5432/<database>?sslmode=require
DATLAS_SOURCE_PROD_PASSWORD=<password>
# optional: only these hosts/networks may be reached through the connector
# DATLAS_ALLOW_HOSTS=<qa-host>,<prod-host>
# optional: refuse data changes through this connector, whatever the console says
# DATLAS_READ_ONLY=true
```

- URL schemes: `postgresql://`, `mysql://`, `mariadb://`.
- `sslmode`: `require` (encrypted), `verify-full` (encrypted + certificate check), `prefer`, `disable`.
  Use `disable` only inside a private network that already encrypts traffic (for example, an encrypted VPN).
- The source names **must** match the names Datlas expects (input 2).

## Step 4 — Run the connector

```sh
docker run -d --name datlas-connector --restart unless-stopped \
  --env-file datlas-connector.env \
  -v datlas-connector:/data \
  -e DATLAS_HEALTH_PORT=8081 \
  ghcr.io/cendyandreoli/datlas-connector:latest
```

Add `--network host` when the databases are reachable only through the host's VPN or private network.

The first start registers the connector (the token is consumed) and saves its identity in the
`datlas-connector` volume. Keep that volume: it *is* the connector's identity. After the first start
you may remove `DATLAS_ENROLL_TOKEN` from the env file.

## Step 5 — Verify

```sh
docker logs datlas-connector 2>&1 | tail -5
# expected: "Conectado ao Datlas (N fonte(s))." with N = number of sources you configured
docker exec datlas-connector python -c "import urllib.request;print(urllib.request.urlopen('http://127.0.0.1:8081/healthz').read().decode())"
# expected: {"ok": true, ..., "sources": ["prod", "qa"], ...}
docker exec datlas-connector python /app/datlas-connector.py check
# expected: one line per source, "<name>: ok, <n> tabela(s)"
```

Then ask the person to open Datlas Console → **Fontes**: each source should show **Conectada** in the
Status column within about a minute (the console also has "Testar conexão agora" in each source's menu).

## Troubleshooting

| Symptom | Cause and fix |
|---|---|
| `Registro recusado: o token é inválido, já foi usado ou expirou` | Ask for a new registration in Console → Conectores → "Gerar novo registro". Remove the `datlas-connector` volume only if you are reinstalling on purpose. |
| Logs repeat `Sem conexão com o Datlas (...)` | No outbound HTTPS/WebSocket to `app.datlasdb.com:443`. Check firewall/proxy egress rules. |
| Console Status "Conector offline" | The container is not running or not connected. Check `docker ps` and the logs. |
| Status "Erro: A fonte X não está configurada neste conector" | The source name in Datlas has no matching `DATLAS_SOURCE_<NAME>` variable. Fix the variable name and restart. |
| Status "Erro: o banco recusou usuário ou senha" | Wrong user/password in the env file. |
| Status "Erro: tempo esgotado ao falar com o banco" | The connector host can't reach the database. Re-run Step 1 from the host; use `--network host` for VPN or private networks. |
| App says "o conector ... ainda não aceita edição" | The connector image is older than 1.3.0. Pull `ghcr.io/cendyandreoli/datlas-connector:latest` (or `:1.3.0`) and restart it. |
| Edits refused with "modo somente leitura (DATLAS_READ_ONLY)" | The company set `DATLAS_READ_ONLY=true` on this connector. Remove it only if changes through Datlas are wanted. |
| `check` reports SSL errors | Adjust `sslmode` (`require` for managed databases; `disable` only on encrypted private networks). |

## Production with replicas (optional)

1. `docker run --rm -e DATLAS_ENROLL_TOKEN=<token> ghcr.io/cendyandreoli/datlas-connector:latest enroll --print-identity`
   prints the identity once. Store it in a secrets manager as `DATLAS_CONNECTOR_IDENTITY`.
2. Run two or more replicas with `DATLAS_CONNECTOR_IDENTITY`, the `DATLAS_SOURCE_*` variables and
   `DATLAS_HEALTH_PORT=8081`. Probes: `GET /healthz` (200 connected, 503 not). Metrics: `GET /metrics`.
3. Key rotation: `rotate` (with `DATLAS_CONNECTOR_IDENTITY` set, it prints the new identity to store).

## Report back (checklist)

- [ ] Machine and how it reaches the databases (network, VPN or private network, `--network host` or not)
- [ ] Sources configured (names only, never passwords) and SSL mode of each
- [ ] Output of `docker logs datlas-connector | tail -5`
- [ ] Output of `/healthz` and of `check`
- [ ] Anything that failed and what you changed

Never paste passwords or the enrollment token into reports, tickets or chat.
