How do I keep the credentials for Postgres tables safe when an AI SRE looks into high latency?
Tares stores the Postgres connection string as a secret on the source, so an AI SRE investigating high latency works from the events the source produces. The dsn is redacted in the API and omitted from catalog exports. For JSON APIs, the http_poll connector keeps its credential as a secret in the same way.
How it works
The Postgres connector polls a table incrementally and turns each new or changed row into one event. You give it a connection URL once, in the dsn field of the source config, in the form postgresql://user:pass@host:port/dbname. Tares stores that field as a secret.
What an investigation sees are the events from the table, not the connection URL:
- The
dsnis redacted when the API returns the source. - The
dsnis left out of catalog exports. - The
columnsfield limits which columns Tares pulls. Leave it empty and every column comes in, so list the columns you need for the latency question.
The AI SRE guide covers how an agent investigates from the events Tares holds. The Postgres connector page covers the table side, including the cursor column that tracks new and changed rows.
The JSON API connector follows the same rule. It sends one credential in one header. The credential field holds the whole value and is stored as a secret, never returned by the API and never exported. The credential_header field names the header, and it defaults to Authorization. Other headers go in headers, which is not secret, so keep credentials out of that map. The HTTP API (poll) connector page has the details.
Set it up
-
Decide which table or API holds the latency signal. For example, an
orderstable with anupdated_atcolumn, or an internal JSON endpoint that reports request timings. -
Add the Postgres source. In the app, go to Sources → Add source → Postgres, enter the Connection URL (
dsn) and press Discover. Tares lists the tables it can see and proposes the cursor, entity key and labels from the columns. Or ask a connected agent to ingest the table. In that case you pass the connection URL in your request, so use the form if you would rather type it yourself. -
Choose the columns to pull. The cursor, key and time columns are always included. Then save. The source looks like this:
- name: orders
connector: postgres
poll: 10s
config:
dsn: postgresql://user:pass@host:5432/appdb
table: orders
cursor_column: updated_at
columns: id,tenant_id,status,amount,updated_at # empty = every column
labels:
- { name: tenant_id, field: tenant_id, primary: true }
- { name: status, field: status }-
Open the source and check Recent events, which shows rows on the next poll. Fields reports each column’s coverage, so you can confirm the key column is reliably present.
-
If the latency data comes from a JSON API that needs a key, add an
http_pollsource and put the key incredential, with the header name incredential_header:
config:
url: https://api.example.com/v1/readings
credential: abc123 # an API key
credential_header: X-API-Key- Press Discover on the HTTP API source. Tares calls the API once, shows the reply and fills in what becomes an event. Pick the entity key and create the source. You can also send the same object with
POST /api/sources.
What you get
- The Postgres connection string is stored as a secret on the source, not in the investigation.
- Each poll becomes events in the timeline, so the agent investigating high latency reads rows and readings.
- You choose the columns, so only the fields you list, plus the cursor, key and time columns, reach Tares.
- For JSON APIs, the credential is stored as a secret, never returned by the API and never exported.
- The payload of an
http_pollevent is stored as received, so labels you declare later can still reach every field without a second call to the API. - If an API rejects a request with a 4xx status,
http_pollshows it as a config error on the source’s health, with the status and a slice of the reply.
When something else fits
- If the system you want to watch calls Tares instead of being polled, the webhook connector fits better, because Tares then holds no connection to that system.
- If the data is not a table, the
http_pollconnector covers any JSON endpoint, as long as one header carries the credential. - If you only need to see metrics and not rows, a Prometheus source avoids a database connection altogether.