Skip to Content
Tares

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 dsn is redacted when the API returns the source.
  • The dsn is left out of catalog exports.
  • The columns field 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

  1. Decide which table or API holds the latency signal. For example, an orders table with an updated_at column, or an internal JSON endpoint that reports request timings.

  2. 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.

  3. 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 }
  1. 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.

  2. If the latency data comes from a JSON API that needs a key, add an http_poll source and put the key in credential, with the header name in credential_header:

config: url: https://api.example.com/v1/readings credential: abc123 # an API key credential_header: X-API-Key
  1. 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_poll event 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_poll shows 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_poll connector 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.

Still stuck? Get help

Last updated on