Many assume that an MCP server can simply be given a permanent database password and start querying without oversight, but that approach ignores just-in-time access principles. In reality, static credentials expose the entire data set to any compromised service, and they provide no way to audit individual statements.
When a machine‑learning model or an autonomous process needs to read or write data, the organization still wants to enforce the principle of least privilege. The request should be granted only for the exact period it is needed, and the operation should be recorded so that auditors can later verify who asked for what data and when. Without a control point that sits between the MCP server and PostgreSQL, the service can issue any command it likes, and any accidental or malicious query becomes invisible to security teams.
To address this, the architecture must separate three concerns. First, the identity system (OIDC or SAML) decides which service identity is making the request and whether the request may start. This setup step is essential but does not enforce any policy on its own. Second, a dedicated gateway must sit on the data path, intercepting every wire‑protocol message between the MCP server and the database. Only in this position can the system examine, transform, or block traffic. Third, the gateway must produce enforcement outcomes: it should mask sensitive columns, block dangerous statements, require human approval for high‑risk actions, and record each query for replay and audit.
Why just-in-time access matters for PostgreSQL
Just-in-time access limits the window of exposure. An MCP server that needs to read a customer table for a short inference job should receive a scoped token that expires after the job completes. If the token is misused, the damage is confined to that brief interval. Moreover, PostgreSQL queries often return rows that contain personally identifiable information. Inline masking ensures that even a legitimate service sees only the fields it is authorized to view, reducing the risk of data leakage.
Audit logging at the command level is another critical outcome. Security teams need to know exactly which SELECT, INSERT, UPDATE, or DELETE statements were executed, by which service identity, and at what time. This granularity enables forensic analysis after a breach and supports compliance requirements that demand per‑query evidence.
How the gateway enforces just-in-time access
hoop.dev acts as the Layer 7 proxy that fulfills the data‑path role. When an MCP server initiates a PostgreSQL connection, it points its client to the gateway instead of the database host. The gateway authenticates the request against the organization’s identity provider, extracts the service’s groups, and checks the policy that defines which databases, schemas, and tables the service may touch.
Once the request is authorized, hoop.dev establishes a short‑lived session with the database using a credential that the gateway holds. The service never sees the database password or an IAM token. During the session, hoop.dev inspects every SQL statement. If a statement matches a guardrail rule, such as a DROP DATABASE or a massive DELETE, hoop.dev blocks the command before it reaches PostgreSQL. For queries that return rows containing sensitive columns, hoop.dev applies inline masking so that the MCP server receives redacted data.
Every statement, along with the identity that issued it and the outcome (allowed, blocked, or masked), is recorded by hoop.dev. The recorded session can be replayed later, providing a complete audit trail without requiring changes to the PostgreSQL server or the MCP application.
Integrating the gateway with an MCP server
The integration flow follows three steps. First, register the PostgreSQL instance with the gateway, providing the host, port, and the credential that the gateway will use. Second, configure the MCP server to connect to the gateway’s address instead of the database directly. Because the gateway presents the same wire‑protocol interface, the MCP server continues to use its standard PostgreSQL client library without code changes. Third, define a just-in-time access policy that grants the MCP service the minimum set of tables it needs, with a short expiration window. The policy also specifies which columns should be masked and which statements require manual approval.
All of these steps are described in the getting‑started guide and the detailed feature documentation. The guide walks through creating the connection, attaching an OIDC identity, and writing the policy in a declarative format. Because hoop.dev operates as a transparent proxy, existing monitoring and connection‑pooling tools continue to work unchanged.
Benefits at a glance
- Scoped, short‑lived credentials eliminate long‑standing passwords.
- Inline masking reduces exposure of PII while still allowing legitimate analysis.
- Command‑level audit logs provide forensic evidence for every query.
- Guardrails and approval workflows stop destructive statements before they execute.
- Session recording enables replay for debugging and compliance reviews.
FAQ
What is just-in-time access?
It is a model where a service receives permission to a resource only for the exact time it needs it, after which the permission automatically expires. This limits the attack surface and ensures that any misuse is time‑boxed.
How does hoop.dev enforce just-in-time access for MCP servers?
hoop.dev sits on the data path, authenticates the MCP service via the organization’s identity provider, checks a policy that defines time‑bound scopes, masks sensitive fields, blocks prohibited statements, and records every query for later review.
Do I need to change my MCP code to use the gateway?
No. The gateway presents the native PostgreSQL wire protocol, so the MCP server continues to use its existing client library and connection string, only pointing at the gateway address.
For the full implementation details, see the getting‑started guide and the feature documentation. Visit the GitHub repository to get the source code and contribution guidelines.