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
dsnhas the formpostgresql://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
idorupdated_at, tracks progress, and each new or changed row is one event. - You choose the columns. The
columnsfield 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 exampletenant_idor 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
- 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. - 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.
- 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 }- Use the same shape for your own table. Set
tableto the table your job writes to,cursor_columnto its growing column, and aprimarylabel to the column that names the job or tenant. - If the job reports through a JSON API, use an
http_pollsource and put the credential incredentialandcredential_header, not in the URL:
config:
url: https://api.example.com/v1/readings
credential: abc123 # an API key
credential_header: X-API-Key- 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
pollunder 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. Thecredentialfield carries a single header value.
Related
- Postgres table
- How do I keep the credentials for JSON API endpoints safe when an AI SRE looks into error spikes?
- How do I keep the credentials for JSON API endpoints safe when an AI SRE looks into high latency?
- How do I keep the credentials for JSON API endpoints safe when an AI SRE looks into failed deploys?
Still stuck? Get help