TL;DR - Support engineers need to look up customer data to resolve tickets, but most teams either give them too much access or no access at all — both create problems. - The fix is read-only MySQL users scoped to specific tables. A support agent who can
SELECTfromusersandordersbut cannotUPDATE,DELETE, or accessbilling_tokensis exactly right. - Browser-based database tools eliminate the need for SSH keys, VPN clients, or local database software on support laptops — reducing your attack surface and onboarding time. - Audit logging on support queries is not optional if you handle customer PII. SOC 2, GDPR, and HIPAA all require you to prove who accessed personal data and when. - The goal is fast ticket resolution without the security risk of overprivileged access. Read-only, table-restricted, time-limited, and logged.
Table of Contents
- Giving Support Teams Safe, Read-Only Database Access
- The Problem: Support Needs Data but Should Not Touch Production
- Creating Read-Only MySQL Users for Support
- Restricting Access to Specific Tables
- Browser-Based Access: No SSH, No VPN, No Workbench
- Audit Trails for Compliance
- Session Timeouts and Access Controls
- Common Patterns That Go Wrong
- FAQ
- Conclusion
Giving Support Teams Safe, Read-Only Database Access
Every support team eventually hits the same wall. A customer writes in saying their order is missing, their account shows the wrong plan, or their data did not sync. The support agent opens the admin panel, but the admin panel does not surface the detail they need. The only way to answer the question is to look at the database directly.
This is where support team database access becomes a real problem. Most companies handle it one of three ways: they give support engineers production credentials with far too many privileges, they force support to ask a developer to run queries (adding hours to resolution), or they build an internal tool that is always six months behind what support actually needs.
None of these are good. The first is a security incident waiting to happen. The second destroys support efficiency — Zendesk's 2025 CX Trends Report found that 72% of customers expect a response within one hour for urgent issues, and waiting on a developer makes that impossible. The third is an engineering time sink that never stays current.
There is a better path: give support teams direct, read-only database access scoped to the tables they need, with no local tooling and full audit logging. This guide shows you how.
The Problem: Support Needs Data but Should Not Touch Production
Support agents are the people most frequently looking up individual customer records. According to a Salesforce 2025 State of Service Report, 65% of support agents say they need to access multiple systems to resolve a single ticket. For technical products — SaaS platforms, e-commerce, fintech — "multiple systems" often means the database.
But support teams are also high-turnover. The Bureau of Labor Statistics reports that customer support roles have an average annual turnover rate of 30-40%. Credentials are constantly being issued to new hires and (hopefully) revoked for departures. Every active credential is an attack surface.
A 2024 Verizon DBIR analysis found that 68% of breaches involved a human element — overprivileged accounts accessed by non-engineering staff were specifically called out as a growing vector. When a support agent has DELETE and DROP privileges they do not need, a single mistake or compromised account can cause damage that read-only access would have prevented entirely.
The right model: support gets read access, limited to the tables they need, through a tool that does not require engineering overhead.
Creating Read-Only MySQL Users for Support
MySQL's privilege system is granular enough to create exactly the access profile support teams need. The key is creating dedicated users with SELECT-only grants — no INSERT, UPDATE, DELETE, ALTER, DROP, or GRANT privileges.
Here is the pattern:
-- Create a dedicated support user
CREATE USER 'support_readonly'@'%' IDENTIFIED BY 'strong-random-password-here';
-- Grant SELECT only on the production database
GRANT SELECT ON your_app_production.* TO 'support_readonly'@'%';
-- Require SSL for the connection
ALTER USER 'support_readonly'@'%' REQUIRE SSL;
-- Apply changes
FLUSH PRIVILEGES;
This gives the support user the ability to read every table but modify nothing. They can run SELECT queries with JOIN, WHERE, and GROUP BY — but INSERT, UPDATE, DELETE, and all DDL statements will be rejected.
For PostgreSQL, the equivalent uses roles:
-- Create a read-only role
CREATE ROLE support_readonly;
GRANT CONNECT ON DATABASE your_app_production TO support_readonly;
GRANT USAGE ON SCHEMA public TO support_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO support_readonly;
-- Make it apply to future tables too
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO support_readonly;
-- Create the support user and assign the role
CREATE USER support_agent WITH PASSWORD 'strong-random-password-here';
GRANT support_readonly TO support_agent;
One user per agent or one shared user? For teams of 1-5, individual users provide better audit granularity. For larger teams, a shared support_readonly user combined with application-level logging is more practical. The database privileges are identical either way.
Restricting Access to Specific Tables
Full-database read access is often more than support needs. A support agent looking up order statuses does not need to see the password_hashes table, the api_keys table, or the payment_tokens table. Table-level and even column-level grants let you restrict access to exactly what support requires.
-- Instead of granting SELECT on the entire database...
-- Grant SELECT only on specific tables
GRANT SELECT ON your_app_production.users TO 'support_readonly'@'%';
GRANT SELECT ON your_app_production.orders TO 'support_readonly'@'%';
GRANT SELECT ON your_app_production.subscriptions TO 'support_readonly'@'%';
GRANT SELECT ON your_app_production.support_tickets TO 'support_readonly'@'%';
-- Exclude sensitive tables entirely — no grant means no access
-- payment_tokens, api_keys, password_hashes are never granted
You can go further with column-level restrictions if certain columns within allowed tables contain sensitive data:
-- Allow support to see user info but not the hashed password or SSN
GRANT SELECT (id, email, name, created_at, plan, status)
ON your_app_production.users
TO 'support_readonly'@'%';
Column-level grants are more maintenance overhead — every schema change may require updating the grant — but for tables that mix customer-facing data with sensitive fields, they are the right trade-off.
What tables should support typically access? It varies by product, but a reasonable starting list: users/accounts (excluding password hashes), orders/transactions (excluding payment tokens), subscriptions/billing status, and support tickets for cross-referencing. The rule of thumb: if a support agent needs the data to answer a customer question, grant it. If they would never legitimately need it, do not.
Browser-Based Access: No SSH, No VPN, No Workbench
The traditional approach to giving support agents database access involves installing MySQL Workbench or DBeaver on their laptop, configuring an SSH tunnel or VPN, and providing connection credentials. This creates three problems:
IT overhead. Every support laptop needs database client software installed and maintained. When SSH keys rotate or the VPN configuration changes, IT has to touch every machine.
Security surface. SSH keys on support laptops are credentials that can be extracted if the machine is compromised. VPN clients give the support laptop a network path to production infrastructure. A browser-based tool eliminates both — the agent's laptop never has direct network access to the database.
Onboarding friction. A new support hire should be resolving tickets on day one. According to SHRM research, the average onboarding period for customer support roles is 1-2 weeks, and every tool that requires local configuration adds to that timeline.
Browser-based database access solves all three. The support agent opens a URL, authenticates, and runs queries — the database connection is made from the server, not from their laptop. No SSH keys, no VPN client, no local software.
DBEverywhere provides hosted phpMyAdmin and Adminer as a service — connect to your database from any browser without managing infrastructure. The free tier gives you 5 sessions per month, enough for a small support team doing occasional lookups. The paid tier at $5/month removes the session cap and adds 8-hour session timeouts.
The key security benefit: your database only needs to whitelist one IP address (DBEverywhere's static IP), rather than the home IP of every support agent. When someone leaves, you revoke their account — no SSH keys to rotate, no VPN certificates to revoke.
Audit Trails for Compliance
If your support team queries databases containing customer PII, you need an audit trail. This is not a nice-to-have — it is a compliance requirement under every major framework.
SOC 2 (CC6.1) requires logging and monitoring of access to information assets. If an auditor asks "who on your support team accessed customer records in the last 90 days?" you need a concrete answer. GDPR (Article 15) gives data subjects the right to know who accessed their data. HIPAA (45 CFR 164.312(b)) requires audit controls for systems containing protected health information.
The practical implementation has two layers:
Database-level logging. MySQL's general log captures every query, but generates enormous volume on busy servers. A better option is the MariaDB Audit Plugin or Percona Audit Log Plugin, which let you filter logging to specific users — log everything support_readonly does while skipping application queries. See our guide on database access audit trails for configuration details.
Application-level logging. If multiple agents share a database user, the database log only shows support_readonly — not which agent ran the query. Application-level logging maps sessions to individual users. DBEverywhere's session tracking records which authenticated user initiated each session, providing individual-level attribution that database logs alone cannot.
Session Timeouts and Access Controls
An open database session on a support agent's browser tab is an unattended access point. If the agent walks away from their desk, anyone who sits down has read access to customer data.
Session timeouts should match the risk profile. A 20-minute idle timeout is reasonable for support — long enough that an agent is not re-authenticating mid-investigation, short enough that an abandoned session closes before someone else can use it. For longer investigations, an 8-hour timeout lets agents work through complex cases while still enforcing an upper bound.
Access hours can be restricted. If your support team works 9-5, there is no reason for the support_readonly user to authenticate at 2 AM. The simplest approach is monitoring — alert on support database connections outside business hours and investigate.
Session caps prevent abuse. A support agent who runs 500 queries in an hour is either doing something unusual or has automation running against a read-only user. Baseline your team's normal usage and flag anomalies.
Common Patterns That Go Wrong
Here are the patterns teams commonly fall into — and why each creates risk.
Pattern 1: "Just use the app's database user." The app user has INSERT, UPDATE, and DELETE privileges because the application needs them. Giving those credentials to support means a mistyped query can modify production data. A Ponemon Institute 2024 study found that 55% of insider-related data incidents were negligent rather than malicious — read-only access prevents accidents, not just attacks.
Pattern 2: "Support asks engineering to run queries." This works at small scale but collapses as ticket volume grows. If your support team handles 50 tickets per day and 20% need a database lookup, that is 10 interruptions per day to an engineer — roughly $150-300/day in lost engineering productivity for a task that should be self-service.
Pattern 3: "We built an internal admin tool." Admin tools are great until they are not. They only expose the views someone thought to build. The first time support needs a specific join or date range filter the admin tool does not cover, they are back to asking engineering. Admin tools complement database access; they do not replace it.
Pattern 4: "Everyone uses the same read-only credentials." Shared credentials provide no individual accountability. When an audit shows that support_readonly queried the users table 847 times last month, you cannot tell which agent did it without application-level logging. Individual accounts or application-level session tracking are essential.
FAQ
What MySQL privileges should a support read-only user have?
SELECT only, scoped to the specific tables support needs. Do not grant INSERT, UPDATE, DELETE, ALTER, DROP, CREATE, INDEX, GRANT, or FILE. If support needs to see data in a table that also contains sensitive columns (like password hashes or payment tokens), use column-level grants to expose only the columns they need. Always require SSL with ALTER USER ... REQUIRE SSL so credentials are never transmitted in plaintext.
Can support accidentally break something with read-only access?
Not in terms of data — MySQL rejects any write operation from a SELECT-only user. The one concern is resource usage: a query without a WHERE clause on a large table could cause performance issues. Mitigate this with MAX_QUERIES_PER_HOUR and MAX_USER_CONNECTIONS limits on the MySQL user, and train support on basic query patterns (always filter by a primary key or indexed column).
How do we handle support accessing databases with sensitive data like payment info or health records?
Restrict at the table and column level. Grant access only to the tables support legitimately needs and use column-level grants for tables that mix sensitive and non-sensitive data. For highly regulated data (PCI cardholder data, HIPAA PHI), consider a dedicated read replica with sensitive columns masked or excluded entirely — a clean separation that does not rely solely on MySQL privilege enforcement.
Is browser-based database access less secure than a desktop client?
It is more secure in most configurations. A desktop client requires the support laptop to have direct network access to the database, meaning credentials and SSH keys are stored locally. A browser-based tool like DBEverywhere proxies the connection server-side — the agent's laptop never has direct database access and never caches credentials locally. The trade-off is that the proxy becomes a trust point, so choose one that enforces SSL, scopes sessions, and provides audit logs.
How many support agents can share a single read-only database user?
There is no technical limit — MySQL does not cap simultaneous connections per user by default (though you can set one with MAX_USER_CONNECTIONS). The real limit is auditability. If you need to know which agent ran a query, shared database users only work if your access tool provides session logging that maps each session to an individual. For teams of 5 or fewer, individual MySQL users are worth the granularity. For larger teams, a shared database user with application-level attribution is more practical.
Conclusion
Support team database access does not have to be a security liability. The pattern is straightforward: create read-only MySQL users, restrict them to the tables support needs, provide access through a browser-based tool, enforce session timeouts, and log everything.
The alternative — making support wait on engineering for every data lookup — is expensive. A Harvard Business Review study found that reducing customer effort is the strongest driver of loyalty, and nothing increases effort like telling a customer "let me check with engineering and get back to you tomorrow."
If you want browser-based, read-only database access without managing phpMyAdmin servers or distributing SSH keys, DBEverywhere hosts phpMyAdmin and Adminer as a service. Connect to your MySQL, PostgreSQL, or MariaDB database from any browser through a single whitelistable IP. The free tier covers 5 sessions per month. The paid tier is $5/month for unlimited sessions and longer timeouts.
Read-only access, scoped to the right tables, through a browser, with an audit trail — that is the model.
Try DBEverywhere Free
Access your database from any browser. No installation, no Docker, no SSH tunnels.
Get Started