How do I keep JSON API credentials safe when an AI SRE looks into slow database queries?
Tares keeps credentials on the source, stored as secrets, and the agent works with the events the source produces, not the connection. The http_poll connector sends one credential in one header, and the Postgres connector takes a connection string as a secret. Neither is returned by the API or included in exports.
How it works
Each source holds its own connection details. When an AI SRE investigates slow database queries, it works from the events those sources have stored in the timeline.
JSON API endpoints (http_poll)
- Tares calls the endpoint itself on the source’s schedule and stores one event per item. No script runs on your side.
credentialholds the whole credential value and is stored as a secret. The API never returns it and exports never include it.credential_headernames the header that carries it. The default isAuthorization.- Other headers the API needs go in
headers. That map is not secret, so put only non-sensitive values there.
Postgres (postgres)
- The
dsnis the source’s connection URL, in the formpostgresql://user:pass@host:port/dbname. - The
dsnis stored as a secret. The API redacts it and catalog exports omit it. - Tares polls the table incrementally on a cursor column and stores one event per new or changed row.
columnslimits which columns are pulled. The cursor, key and time columns are always included.
The agent’s view is the event stream. For an http_poll source that is the summary line and the payload fields. For a Postgres source it is the rows you chose to pull.
See the HTTP API (poll) connector and the Postgres connector for every field.
Set it up
- Decide which endpoint reports on slow queries, and which table holds the data you want next to it.
- Add the JSON API source. Go to Sources → Add source → HTTP API (poll). Fill in the method and URL, and enter the credential as one header name and value. Press Discover. Tares calls the API once, shows the reply and fills in what becomes an event. Pick the entity key, then create the source.
- Or create the same source from YAML, or with
POST /api/sources. A bearer token goes in theAuthorizationheader:
config:
url: https://api.github.com/user
credential: Bearer ghp_xxx # a bearer token
credential_header: Authorization- An API key in a custom header looks like this:
config:
url: https://api.example.com/v1/readings
credential: abc123 # an API key
credential_header: X-API-Key- Add the Postgres source. Go to Sources → Add source → Postgres, enter the Connection URL and press Discover. It lists the tables it can see and proposes the cursor, entity key and labels. Choose your columns and save. The YAML form is:
- 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 }- You can also ask a connected agent to set a source up. For Postgres it calls
discover_source, thentest_sourcefor a dry run that fetches sample rows, thencreate_source. - Verify. Open each source. Recent events shows what each poll stored, and Fields lists every field seen with its coverage.
What you get
- Credentials live in one place, the source configuration, as secrets. The API returns neither the
credentialnor thedsnin clear text, and exports leave both out. - The agent investigates from events and labels, so it needs no copy of the connection string or the API header.
- Tares polls the API and the table itself, so no script holds the credential.
- The polling is gentle on the upstream API. Tares refuses a
pollunder 10 seconds. It backs off on a 429 or any 5xx, and the wait doubles from the poll interval up to an hour. A 429 withRetry-Afteruses that value. - Problems show up on the source. Any other 4xx appears as a config error on the source’s health, with the status and a slice of the reply. A rate limit appears as “rate limited by the API, next try at HH:MM”. The backoff clears on the next good poll.
- Payloads are stored as received, so labels you declare later can still reach every field.
When something else fits
- If an API needs more than one secret header, note that
http_pollsends one credential in one header, and theheadersmap is not secret. - If a system should push events to Tares instead of Tares polling it, the webhook connector fits better than
http_poll. - If the data you need is in a table, use the Postgres connector instead of an API. It needs a Postgres reachable from the Tares host and a column that only ever grows as its cursor.
Related
- Postgres table
- How do I keep the credentials for JSON API endpoints safe when an AI SRE looks into 5xx errors on an API?
- How do I keep the credentials for JSON API endpoints safe when an AI SRE looks into a cron job that stopped?
- How do I keep the credentials for Postgres tables safe when an AI SRE looks into high latency?
Still stuck? Get help