Skip to Content

How do I keep the credentials for Postgres tables safe when an AI SRE looks into a cron job that stopped?

Tares stores the Postgres connection string as a secret on the source and polls the table itself, so the investigation of a stopped cron job works from events. You enter the connection URL once, when you add the source. The dsn is redacted in the API and omitted from catalog exports. For the AI SRE workflow, the cron job’s rows become events in the timeline.

How it works

The connection details live on the source, not in a prompt, a script or a ticket. Tares does the polling on the source’s schedule.

  • The connection string is a secret. The dsn has the form postgresql://user:pass@host:port/dbname. The API redacts it and catalog exports leave it out.
  • Rows become events. The Postgres connector reads a table incrementally. A cursor column that only ever grows, such as an id or updated_at, tracks progress, and each new or changed row is one event.
  • You choose the columns. The columns field lists what to pull. Empty means every column. The cursor, key and time columns are always included, so leave out the columns you do not need.
  • An entity key groups the events. A label marked primary (for example tenant_id or a job name column) becomes the key.

If the cron job exposes its status through a JSON endpoint instead of a table, the HTTP API connector fits. Its credential field holds one whole header value, such as a bearer token or an API key, and Tares stores it as a secret. The API never returns it and exports never include it. Headers that are not secret go in headers.

Set it up

  1. Pick the table that records your cron job’s runs, for example a table the job writes to on every run. Choose a cursor column that only grows, such as updated_at.
  2. Add the source. In the console go to Sources → Add source → Postgres, enter the Connection URL and press Discover. Tares lists the tables it can see, and you pick one. It proposes the cursor, entity key and labels from the columns. You can also ask a connected agent to ingest the table, and it runs discovery, a dry-run test and then creates the source.
  3. Choose which columns to pull, 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. Use the same shape for your own table. Set table to the table your job writes to, cursor_column to its growing column, and a primary label to the column that names the job or tenant.
  2. If the job reports through a JSON API, use an http_poll source and put the credential in credential and credential_header, not in the URL:
config: url: https://api.example.com/v1/readings credential: abc123 # an API key credential_header: X-API-Key
  1. Verify. Open the source. Recent events shows rows on the next poll, and Fields reports each column’s coverage, so you can confirm the key column is reliably present.

The host that runs Tares must be able to reach the Postgres server. The driver ships with Tares, so there is nothing extra to install.

What you get

  • One place for the secret. The connection string sits on the source, stored as a secret, and not in the questions you ask or the notes you write about an incident.
  • The cron job’s history in the timeline. Each new or changed row is an event with its own time, so you can see when the last run landed and what its status was.
  • Less data pulled. Column selection keeps fields you do not need out of the events.
  • Safe sharing of the setup. Catalog exports omit the dsn, and the HTTP API connector’s credential is never exported either, so you can share a source definition without sharing the secret.
  • Backoff on polled APIs. The HTTP API connector refuses a poll under 10 seconds. On a 429 or any 5xx it backs off, and it reports a rate limit or a config error in the source’s health.

When something else fits

  • If the system that runs the cron job can call Tares, such as a scheduler posting its own run results, the webhook connector is the better fit, because Tares receives the events instead of polling.
  • If the job’s state is in a table you cannot reach from the Tares host, or the job only writes logs, a log or metrics connector gives you the signal instead.
  • If the API you poll needs more than one credential header, put the extra non-secret headers in headers. The credential field carries a single header value.

Still stuck? Get help

Last updated on