The fastest way to over-privilege an AI agent on MySQL is to give it the credentials your application already uses. That account can read and write half the schema, and now so can the agent, for tasks that only ever needed to read three tables. Least-privilege access for AI agents on MySQL is the discipline of granting the smallest scope a task needs and nothing more, then proving the agent cannot exceed it.
Least privilege is not one setting. It is the combination of which connection the agent can reach, which statements it can run, and which rows and columns come back. The goal is a grant so tight that even a compromised or confused agent can only do the small thing its task required.
What least privilege means for a MySQL agent
Scope an agent along three axes:
- Surface. Which database and which tables the agent can touch at all.
- Verbs. Whether it can only
SELECT, or also INSERT, UPDATE, DELETE, or DDL. - Data. Which columns return real values and which come back redacted.
MySQL grants cover the first two through user privileges, but managing a separate database user per agent gets unwieldy fast, and grants alone do not cover the third axis at all. You need a control point that scopes the connection, not just the account.
hoop.dev proxies the MySQL wire protocol and authorizes each session before it opens. That makes the gateway the place to enforce least privilege across all three axes at once: the policy decides which connection the agent's identity may reach, sensitive operations route for approval, and the masking plugin redacts columns the task should not see. The architectural point is that the smallest grant has to be enforced where the agent cannot widen it. A privilege the agent can edit is not a limit.
- Register the MySQL connection in hoop.dev with
HOST, PORT, USER, PASS, and DB, using a database user already scoped to the task's tables. - Give the agent a distinct identity and bind a policy that allows only the connections its task needs.
- Route write or destructive operations to a human for approval so the default grant is read-only.
- Turn on masking for sensitive columns so least privilege extends to the data, not just the verbs.
- Point the agent at the gateway endpoint and confirm a query outside its scope is denied or routed for approval.
Verify the boundary holds
Test the negative case. Have the agent attempt a statement against a table it should not reach, and confirm the gateway refuses it. A least-privilege configuration you have only tested on the happy path is an assumption, not a control.
Run the same negative test across all three axes. Try a forbidden table to check the surface. Try a write where only reads are allowed to check the verbs. Run a query that touches a sensitive column and confirm the value comes back redacted to check the data axis. A grant that passes all three negative tests is one you can actually reason about, because you have watched it refuse the things it should refuse rather than only watched it permit the things it should permit.
Pitfalls
- Re-using the app's database account. It is almost always broader than any single agent task.
- Granting write "just in case." Default to read-only and require approval for anything that mutates data.
- Ignoring the data axis. An agent scoped to read-only can still pull a column of PII. Mask it.
FAQ
Do I still need MySQL grants if the gateway enforces policy?
Yes, defense in depth helps. Scope the connection's database user tightly, then let the gateway add per-identity policy, approvals, and masking on top.
How is least privilege different from just-in-time access?
Just-in-time access controls when the agent has access. Least-privilege access controls how much. You want both: access that is small and temporary.
Does this work on RDS MySQL?
Yes. RDS connections can use per-user IAM auth on the web-app path, so the scoped identity maps to an IAM token rather than a shared user.
Pair this with just-in-time access so the small grant is also temporary and the wider model for agent access. Stand it up against a test MySQL database: hoop.dev on GitHub.