Please do not report security vulnerabilities in public issues, discussions or pull requests.
Report them privately through GitHub: Report a vulnerability (Security tab → Advisories → Report a vulnerability). Include:
- the affected version or commit;
- the component (source connection, catalog client, storage, HTTP listener, local state) and configuration involved, with credentials removed;
- steps to reproduce, and the impact you observed or expect.
We aim to acknowledge a report within three business days and to agree on a fix and disclosure timeline with you. We credit reporters in the advisory unless you prefer otherwise.
Flow is in beta. Security fixes are made on main and released in the next
patch release of the latest minor version. Older minor versions do not receive
fixes; see upgrading.
In scope: vulnerabilities in this repository's code, its Dockerfile and release artifacts, including credential exposure in logs or errors, TLS verification, unauthorized access through the optional HTTP listener, and state or data corruption an attacker can trigger.
Deployment choices are outside Flow's control but worth knowing:
- Secrets. The PostgreSQL URL comes from the environment variable named by
source.connection_env, and REST catalogtoken_env/credential_envname environment variables. Literal[catalog]properties, includingtoken,credentialand object-store keys such ass3.secret-access-key, are also accepted, so protectflow.tomllike any other secret when you use them. Without explicit keys, object-store access uses the default AWS credential chain (environment, shared profile files, web identity, container and instance metadata), so those sources are in scope for the process too. Protect the process environment, and keepflow.tomlout of version control. - Local state. The
state_dirholds replicated row data in the journal, spool and index. Flow runs with a0077umask on Unix, so every file and directory it creates is readable only by the user running Flow. This includes files written to afile://warehouse, which other users therefore cannot read. Flow removes group and other access from an existingstate_dirowned by that user, warns about one owned by root (such as a Kubernetes volume withfsGroup), and refuses to start when another non-root user owns it and group or other users can write to it. On shared volumes, pointstate_dirat a subdirectory Flow creates, such as/data/state, to avoid both. Readers ofmetrics.promorstatusmust run as the Flow user; otherwise use the HTTP listener. Backups ofstate_dircontain row data. - Container image. The image built from the Dockerfile runs as UID 10001 and its
/datais0700. Runtimes that assign an arbitrary UID (such as OpenShift) cannot use it; mount a volume writable by that UID and setstate_dirinside it. - PostgreSQL TLS. Connection settings follow libpq, whose default
sslmode=prefersilently falls back to plaintext. Across untrusted networks usesslmode=verify-full, which verifies the certificate chain and the server hostname, withsslrootcertnaming the server's CA bundle (without it the system trust store is used).sslmode=requireencrypts but does not authenticate the server unlesssslrootcertis set.sslmode=verify-cadoes not check the hostname, so any certificate issued by the configured CA is accepted; Flow requiressslrootcertfor it and it is appropriate only for a private CA.init,runandcheck --sourcewarn about unauthenticated settings for connections that leave the host. - Catalog and object store. Prefer
https://catalog and object-store endpoints across untrusted networks. Flow redacts catalog and storage credentials, including vended credentials, from its errors and from the debug output of catalog and storage configuration. - Logs. Keep
RUST_LOGatinfoin production. Flow drops debug and trace records from the AWS request signing crates (reqsign*) whateverRUST_LOGrequests, because they print credentials, but other dependencies' debug and trace output can include queries, object paths and request details. - HTTP listener. The optional
[http]listener is unauthenticated and serves status and metrics. Bind it to a private interface. It accepts up to 64 concurrent connections and closes clients that do not send a request within one second. - File descriptors. RocksDB keeps index files open and each HTTP connection
uses a descriptor, so raise the default 1024 soft limit, for example
LimitNOFILE=65536in a systemd unit.