REPLICATION and repo:org/*: Standing Grants You Can Enumerate Today
Neither finding needs a vendor to ship anything — a query and a grep close both, and the reported ten-hour intrusion clock tells you which week to do it in.
Who actually holds REPLICATION
Enumerate the accounts in a normal stack and the list runs long: Debezium or Kafka Connect source connectors, Airbyte and Fivetran ingestion users, pg_basebackup automation, Patroni or repmgr, every physical streaming replica, and the analytics vendor onboarded in 2023 and never offboarded. Those credentials are long-lived, committed into Helm values or connector JSON, and reachable from application subnets. They were provisioned against a threat model of can read the WAL.
Logical decoding is not a SQL-layer feature. The client opens a replication connection, the server forks a walsender backend, and that backend loads an output plugin, a shared library, to turn WAL records into a change stream. That work runs inside a privileged server process as the postgres OS user, outside the SQL sandbox. The Hacker News reports that a defect on that path yields the filesystem, the local socket, the instance metadata endpoint, and every credential the database process can read. Wider than database superuser.
Five service accounts nobody can name from memory hold REPLICATION, and REPLICATION now means shell access on the database host.
One gap the reporting leaves open: it truncated the CVE identifier. Pull the project advisory for the identifier and the affected minor versions, and map every cluster against that, not against a summary. On RDS, Aurora and Cloud SQL there is no patching, only scheduling, so get the patched minor version and the forced-maintenance date in writing.
The same shape on the build plane
CSO's account of the sub-ten-hour ransomware intrusion contains no exploit. An exposed credential, then a trust relationship spanning a development system and a cloud account, then privileged action in a different environment. In a modern stack that middle hop is one of four things: an OIDC trust policy whose subject condition reads repo:your-org/* rather than repo:your-org/your-repo:ref:refs/heads/main, a self-hosted runner whose instance profile every job inherits, a long-lived token with org-wide scope, or a deployment service principal holding standing owner-level IAM because scoping it was inconvenient two years ago.
| Standing grant | Provisioned for | What it now grants | The check |
|---|---|---|---|
| REPLICATION role | WAL streaming to replicas and CDC consumers | Code execution as the postgres OS user | SELECT rolname FROM pg_roles WHERE rolreplication OR rolsuper, plus every replication line in pg_hba.conf |
| Federated CI role, wildcard subject | Deploys without static cloud keys | Any workflow in any org repo can assume it | Grep trust policies for subject conditions missing repo and ref pinning |
| Shared registry, mutable tags | Dev pushes, prod pulls | Overwrite the tag prod resolves at deploy time | Tag immutability enabled; deployments pinned by digest |
The latency argument, and where the reports disagree
Rank the control loops against a ten-hour budget and most fall outside it: posture scanning nightly to weekly, access reviews quarterly, manual key rotation in days to months, alert-to-page-to-triage in 30 minutes to four hours. Only identity threat detection on AssumeRole anomalies runs in seconds to minutes. That arithmetic is also the argument against buying an AI-native detection product. The observed techniques were mundane, and what compressed was the attacker's recon-and-pivot loop. The symmetric move is removing the human from your containment loop.
The two accounts diverge on how far to take that. One pushes pre-authorized automated containment triggered without human approval: revoke IdP sessions, attach deny-all, quarantine CI runners. The other calls unscoped auto-revocation the most dangerous item on its own list, because a false positive that revokes a production service role is an outage you caused. The reconciliation is boring. Require two independent signals, build and test the rollback path before wiring the trigger, then prove it in a game day.
Rank the work by reachability × privilege gained and the database wins. Its precondition is a credential already handed to five systems.
What to do
Run SELECT rolname FROM pg_roles WHERE rolreplication OR rolsuper against every cluster today, grep every pg_hba.conf for replication lines, and revoke with ALTER ROLE ... NOREPLICATION anything not tied to a documented replica or CDC consumer.
Obtain the patched minor version and forced-maintenance date in writing from your RDS, Aurora or Cloud SQL support channel this week, then scope pg_hba and security groups so the app tier cannot open replication connections at all.
Grep every federated IAM trust policy, Azure federated credential and GCP workload identity binding this sprint for subject conditions missing repo and ref pinning, and pin deployments to image digests instead of mutable tags.