How MySQL Handles Permissions for Views vs Base Tables
MySQL provides granular access control when working with Views. Permissions behave differently depending on whether queries run under the definer's privileges or the invoker's privileges.
Views in MySQL operate under two security modes: SQL SECURITY DEFINER (default) and SQL SECURITY INVOKER.
Under DEFINER mode, the user's permissions are not directly checked against the base tables — rather, the view runs with the privileges of the view creator.
Under INVOKER mode, the querying user must have individual privileges on both the view and the underlying base tables.
To access a view, a user must be granted at least SELECT (or INSERT/UPDATE/DELETE if applicable) on the view itself.
If the view is defined with SQL SECURITY DEFINER, the user does NOT need permissions on the base tables — only the view owner does.
If SQL SECURITY INVOKER is used, the user must have permissions on both the view and its underlying tables.
Views can hide sensitive columns by exposing only selected fields.
A user may be granted SELECT on a view without gaining SELECT on the base table.
This enables column-level and row-level security.
Example: A view that hides salary information in an employees table.
If a user attempts INSERT/UPDATE/DELETE through a view, MySQL checks whether the view is updatable and whether privileges exist.
Under DEFINER mode, the DEFINER must have table privileges for the operations to succeed.
Views cannot be used to bypass base table restrictions if the DEFINER lacks permissions.
In summary, granting privileges on a view does not automatically grant access to its underlying tables. MySQL’s SQL SECURITY modes define whose permissions apply, making views a powerful mechanism for secure, controlled data access.
If a user can SELECT from a view but gets 'access denied' when querying the underlying table directly, what’s the most likely reason?
You create a view with SQL SECURITY DEFINER and grant SELECT to a junior analyst — they can query the view but can't SELECT from the base table. Is this expected? Why?
A reporting feature broke after a DBA changed the view’s definer account — users now get permission errors even though their roles haven’t changed. What would you check first?
Your team built a view to expose customer data to a third-party app, but security flagged it as a risk. Why might granting access to the view instead of the table be dangerous if not configured properly?
You’re designing a multi-tenant analytics layer using views — how do you ensure tenants can’t access each other’s data via view definer privileges, and what edge cases might slip through?
A legacy view uses DEFINER with a service account that has broad privileges. You want to migrate to least-privilege access without breaking existing apps. What’s your migration strategy?
Your company is consolidating 20+ microservices that all query the same database via views — how do you design a permission model that scales securely across teams without creating a maintenance nightmare?
You’re migrating from a monolith to a service-oriented architecture, and legacy views with DEFINER privileges are tightly coupled to service accounts. How do you decouple this without introducing security gaps or downtime?