Where credentials live, and what the proxy can actually see
AccessFlow is a full proxy, not a gateway. It terminates the user's session, holds the database and API credentials itself, and is the only thing that ever opens the real connection — under whatever policy you configure, from a multi-stage approval chain down to an audited break-glass path. That decision settles the three things a security reviewer asks about first: where the secrets are stored, what the proxy is able to read while a query runs, and what evidence survives afterwards. This page answers all three, and links to the operator chapters that configure them.
Database proxy security architecture — one component holds the credentials
Nobody gets the database password or the API credentials — not even your own team. AccessFlow sits in the middle and is the only thing that ever connects to the real database or upstream API, and only after a request is approved. Users sign in to AccessFlow, never to the target; behind the scenes the proxy holds the real database connection pools and the connectors' encrypted credentials, and reaches out on their behalf.
That single choke point is what makes everything below it possible: the component that decides whether a query may run is also the one that parses it, checks the schema allow-list against the parsed statement rather than against a string, applies masking and row-level security at execution time, and writes the audit record.
Where the credentials actually live
A datasource password is encrypted with AES-256-GCM before it is stored, under a key that lives only in the deployment's environment — never in the database beside the ciphertext it protects. The encrypted column is excluded from serialization on the entity itself rather than filtered per endpoint, so a future API route cannot leak it by accident — there is no response shape in which it appears.
If you would rather AccessFlow never store the secret, a datasource can hold a secret reference instead of a value and resolve it on demand from HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault. Rotating the secret upstream rotates it here, with no redeploy and no copy left behind.
Either way the plaintext has a deliberately short life. It is decrypted once, handed to the connection pool at initialisation, and not retained in application memory beyond that point; the query path works against a warm pool, never against a password.
Three other keys matter operationally, and they are deliberately not all sourced the
same way. The RSA-2048 JWT signing key comes from the environment. The
audit HMAC key can too, but it is optional — left unset it is derived
from the encryption key via HKDF-SHA256, and startup fails if neither is available. The
SAML SP signing keypair is hybrid: supply the key and certificate as
environment values and AccessFlow uses them verbatim and never persists them; leave
them unset and it generates a self-signed RSA-2048 pair on first use, encrypts the
private key with the same AES-256-GCM service, and stores it on the
saml_config row so it survives restarts. If your policy is that no signing
key may rest in the application database, supply that pair explicitly.
None of these is logged or returned by an endpoint. One exception is worth knowing
before you grep and find it: the zero-config docker compose up demo stack
ships throwaway keys inline so a fresh clone runs with no setup. They are committed on
purpose, and every production install path generates or demands its own.
Datasource docs →
Who can sign in, and who takes them out
Because nobody holds a production credential, the identity check moves entirely to AccessFlow's front door. So it has to be the front door your company already runs — and offboarding has to reach it without anyone remembering to click anything.
Workforce-ready auth
Sign in with the accounts your company already uses — SAML 2.0 SSO and OAuth 2.0 / OIDC, with built-in templates for Google, GitHub, Microsoft, GitLab, and a generic provider for any other IdP (Keycloak, Auth0, Okta, …). Roles and group memberships sync automatically from your identity provider on every login, with optional TOTP two-factor. With SCIM 2.0 provisioning, the IdP drives the whole user lifecycle: joiners are created, movers re-grouped, and leavers deactivated automatically — sessions and standing access grants revoked the moment someone is offboarded in Okta or Entra ID. One deployment hosts multiple fully-isolated organizations, and a super-admin manages tenants across the cluster — with per-org quotas and a kill-switch that disables an org instantly. Auth & SSO docs → Users & roles docs →
JWT · SAML · OAuth · SCIM provisioning · IdP group sync · TOTP · Multi-tenant orgs · Per-org quotasWhat the audit log proves
The proxy is the only thing that talks to the database, so its log is the complete
record — and a complete record is only worth something if it can be shown to be
complete. A separate, dedicated writer role owns the table and appends the rows, while
UPDATE, DELETE and TRUNCATE are revoked from the
general application role, which keeps SELECT for the admin read endpoint.
That privilege split raises the bar; the hash chain is what makes the log
tamper-evident rather than merely tamper-resistant, so an edit made around the
split still surfaces as a broken chain.
/admin/audit-log — every action, its actor and its resource, with a chain-verification pass and a CSV export.Tamper-evident audit & compliance reports
Every decision is recorded in a log that can't be quietly edited after the fact — append-only, cryptographically chained, and searchable, with CSV export and no row data ever stored. Pre-built compliance reports — classified-data access (PII/PCI/PHI/GDPR) and a DDL/DELETE trail with approver names — export as digitally signed PDF/CSV that verify offline, surfaced to a dedicated read-only Auditor role. And once a permitted query returns, result-export governance decides what may leave: per-datasource policies allow, watermark, row-cap, or deny downloads of classified results — the watermark (who, when, which query) is baked into the signed bytes, every export is audited, and "who downloaded this data" always has an answer. Need it in your SIEM? External audit sinks stream every audit event to Splunk HEC, syslog/CEF (TCP/TLS), or an HMAC-signed HTTPS endpoint, and archive digitally-signed segments to S3 Object Lock for WORM retention — at-least-once off a durable per-sink cursor, a dead sink never blocks the log, and every exported event carries its chain links so the external copy verifies on its own. Audit log docs →
HMAC-SHA256 chain · signed exports · SIEM streaming · WORM archivalWhat AccessFlow keeps, and what it never touches
The last question is the simplest: sitting in the middle of every query, how much of the data does the proxy keep? None of it. Results stream through; what is written down is the request and the decision.
Does AccessFlow store or copy my data?
No. AccessFlow proxies queries and streams results back without persisting them. Its own database stores the query text, the approval decisions, and audit metadata — row counts and timings, not rows. Datasource credentials are AES-256-GCM encrypted, or held in Vault, AWS Secrets Manager, or Azure Key Vault.
Agents are held to the same line: a query arriving over the built-in MCP server takes the same parse, risk analysis, approval and audit path as one a person submitted, and masking and row-level security apply to the samples it reads. Governed access for AI agents → Install AccessFlow →