Use casesSecurity and platformPlatform teams12 / 12
How it fits together

Changed through a pull request, with no password to keep

The whole setup is one file in git with no secret in it. CI shows the diff on the pull request and applies it on merge, all or nothing, and prod refuses changes made by hand. Database users come from Vault for the length of a lease, so there is no password to rotate or leak.

0passwords in the file or the store
1file, applied all or nothing
80 %of a lease, then a new user
Your repo and people
Your CI
Your cluster · Helm chart
Your data and the record
VaultStable↗
database engine · role bound to host
AWSExp↗
Secrets Manager · RDS IAM
↗ queryapigate.yaml connections: - name: warehouse credentials: source: vault-database role: reporting-ro no secret in the file✓
↗ configAsCode: enabled: true locked: true or let the chart apply it: the first new pod applies the file, once.

Someone edits prod by hand

Console → roles → partner
↗ On the pull requestconfig diff
--server prod
shows every change; changes nothing
On mergeconfig apply
--server prod
all or nothing
QAG_API_KEY from the CI's secrets, never an argument
namespace queryapigate helm chartStable↗
The governed corepod-1pod-2pod-3↗

01 · Apply

One transaction, under the store's write lock. Audited once: who, and the file's SHA-256.

invalid_config · rolled back

02 · Lock

What the file manages changes only through a file.

409 config_managed

03 · Credentials

A database user from Vault for each lease, renewed at 80 %. Connections retire before it ends.

503 secret_unavailable
PodDisruptionBudget NetworkPolicy ServiceMonitor events · mcp data planeExp
↗

PostgreSQL

warehouse.internal user v-reporting-ro-q7mz a user Vault made for this lease; none is stored
↗

The store and the record

Store: connections, queries, roles and keys, as the file says Audit: config_applied · sha256 9c1e…4b07
· ci-deployer
each change via: config
What CI showsexit 2: changes to review
$ queryapigate config diff --server https://prod.example.com queryapigate.yaml + queries[best_month] ~ roles[partner] rate_limit: "60/minute" -> "120/minute" 1 to create, 1 to change.
Stablecompatibility promise Expmay change in a minor release Not in the file: server settings, administrators, run history and the audit log.
Your repoOne YAML file, no secret in itConnections, roles, queries, keys' grants and exports. A password is a reference; a database user can come from Vault.
Your CIconfig diff on the pull request, config apply on mergeOr the Helm chart applies the file as its first new pod starts.
The governed core, in your clusterApply → lock → credentialsAll or nothing, audited with the file's SHA-256. A change made by hand on prod is refused with 409 config_managed.
AsksVault (AWS experimental)A database user for each lease, renewed at 80 %, from a role bound to its host.
Your databaseReached as a user that lives as long as its lease
The recordOne config_applied entry per fileWho applied it, the file's hash, and every change via: config.

The same governed core as the full architecture.

For platform teams

Run it like the rest of your platform

The platform team wants it installed with Helm, changed through a pull request, and holding no database password of its own. Each of those is a setting, not a project.

✓The whole setup as one YAML file with no secret in it. config diff on every pull request, config apply on merge, all or nothing.
✓QUERYAPIGATE_CONFIG_LOCKED keeps what the file manages to the file; a change made by hand on prod is refused, not drifted.
✓A Helm chart for one pod or several: non-root, read-only root filesystem, and with the chart's config option a merge is the deploy.
✓No password at rest: short-lived credentials from Vault per lease or RDS IAM tokens, or ${vault:…} and ${aws-sm:…} references. AWS experimental.
Platform teams
# in CI, on the pull request
$ queryapigate config diff --server https://prod.example.com queryapigate.yaml
+ queries[best_month]
    connection_name: "sales"
~ roles[partner]
    rate_limit: "60/minute" -> "120/minute"

1 to create, 1 to change.

# a connection with no password: Vault makes one per lease
{"name": "warehouse", "db": "postgres", "host": "warehouse.internal",
 "port": 5432, "database": "postgres",
 "credentials": {"source": "vault-database", "role": "reporting-ro"}}
More use casesAll twelve →

Not sure which fits?

The example APIs ship with a generated database and one scoped key per scenario, so you can try each of these in a few minutes without connecting anything of your own.

Run the examplesCompare alternatives