Credential model
How Backstop handles credentials — what it stores, what it never stores, and how database URLs flow through the system.
What Backstop stores
Backstop stores only what it needs to operate:
| Stored | Where | Retention |
|---|---|---|
| Bearer tokens (hashed) | In-process (token file at startup) | Until gateway restart |
| Audit events | S3 / local storage | Configurable (default: 90 days) |
| Parquet snapshots | S3 | Until explicitly deleted |
| Approval records | S3 / local storage | Configurable |
What Backstop never stores:
- Database credentials (connection strings are never written to disk or logs)
- Query results (only metadata and row counts appear in audit events)
- Bearer tokens in plaintext in logs
- Any data from the rows returned by SELECT queries
Database credentials
Database URLs are passed to the gateway at startup via environment variable:
BACKSTOP_DB_URL=postgresql://postgres:password@localhost:5432/mydbThe URL is held in process memory only. It is never written to disk, never included in audit events, and never returned through any API endpoint.
If an agent passes db_url in an execute_query request (to override the gateway default), that URL is also held in memory for the duration of the request only. It does not appear in logs or audit records.
Bearer token lifecycle
Tokens are defined in a JSON file and loaded at gateway startup:
BACKSTOP_TOKENS=/etc/backstop/tokens.json backstop-gatewayThe gateway reads the file once on startup. Changing the file requires a restart. Token values are never logged — only the token id field appears in audit events.
Token revocation
To revoke a token: remove it from tokens.json and restart the gateway. There is no hot-reload mechanism — the restart is required.
Token storage recommendations
- Store
tokens.jsonin a secrets manager (AWS Secrets Manager, HashiCorp Vault, Kubernetes Secrets) - Pass the file path via environment variable, not the tokens themselves
- Restrict filesystem read access to the gateway process only (
chmod 600 tokens.json) - Rotate tokens on a regular schedule — quarterly at minimum
S3 credentials
Backstop accesses S3 for snapshot storage. Credentials are passed via environment:
BACKSTOP_S3_ACCESS_KEY=...
BACKSTOP_S3_SECRET_KEY=...Or via instance role / workload identity (recommended for cloud deployments):
# AWS: no access key needed if running on an EC2 instance with an IAM role
BACKSTOP_STORAGE_URL=s3://prod-snapshotsBackstop uses the AWS SDK's standard credential chain — instance metadata, environment variables, ~/.aws/credentials — in that order.
What agents can observe
An agent calling execute_query receives:
- The query result (rows or command result)
safety_metadata— risk level, policy decision, table name, affected row estimatesapproval_idandsnapshot_idwhen relevant
An agent cannot observe:
- Other agents' queries or results
- The token file or any other token values
- Database credentials or connection strings
- The full audit log (that requires
metadata:readscope, which agents should not have)
Snapshot data security
Parquet snapshots stored in S3 contain real table data. Treat them with the same access controls as your database:
- Enable S3 bucket encryption (SSE-S3 or SSE-KMS)
- Restrict bucket access to the gateway and sidecar IAM roles only
- Enable S3 access logging on the snapshot bucket
- Set a lifecycle policy to expire old snapshots (default retention: 30 days)