Every analytics tool that connects to your warehouse needs credentials. The question is how much permission those credentials carry. For tools that only need to read data, the answer should be: only read permission. In practice, a surprising number of analytics tools request or assume write access, either because their architecture uses temporary tables for intermediate computation or because no one questioned the default permissions during setup.
This post covers why read-only access is the correct security baseline for analytics tools, what a minimal-permission service account looks like on Snowflake, BigQuery, and Redshift, and where row-level security policies fit into the model.
Why Write Access Introduces Risk You Do Not Want
An analytics tool with write access can create tables, modify existing data, and in some cases drop objects. For a tool that is primarily aggregating and reading event data, none of these capabilities are necessary for its stated function. Granting them anyway creates several categories of risk.
The most obvious is accidental data modification. A tool that writes intermediate results to temporary tables and then fails mid-run may leave orphaned tables in a schema that production pipelines also write to. Cleanup logic that did not account for a failure mode runs a DROP TABLE on the wrong target. These failures are rare, but they happen, and the blast radius depends entirely on what permissions the tool had available when they occur.
Less obvious but more frequent: audit log noise. Most warehouse audit systems log all DDL and DML operations against your warehouse. A tool that creates and drops temporary tables on every query run generates dozens of write-operation log entries per session. That noise makes it harder to identify suspicious write activity in audit logs, which is precisely when you want clear signal. A tool that only reads data produces a clean audit trail of SELECT operations that is straightforward to monitor.
The third risk category is supply chain. When an analytics tool vendor updates their product, those updates could change what operations the tool performs against your warehouse. A read-only service account constrains what any future version of the tool can do, regardless of what the vendor decides to implement. This is not a theoretical concern; several data tool security incidents over the past few years involved tools that began using credentials for purposes beyond what users expected when they first connected them.
What a Minimal-Permission Service Account Looks Like
The structure varies by warehouse, but the principle is the same across all three major platforms.
On Snowflake, a read-only service account for an analytics tool should have USAGE on the database, USAGE on the schema, and SELECT on the specific tables or views the tool needs to query. The account should have no CREATE, INSERT, UPDATE, or DELETE privileges. Create a dedicated role for this purpose rather than assigning privileges directly to the user; this makes it easier to audit and modify later.
-- Snowflake: read-only role for analytics tool
CREATE ROLE analytics_readonly;
GRANT USAGE ON DATABASE analytics_db TO ROLE analytics_readonly;
GRANT USAGE ON SCHEMA analytics_db.events TO ROLE analytics_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA analytics_db.events TO ROLE analytics_readonly;
GRANT SELECT ON FUTURE TABLES IN SCHEMA analytics_db.events TO ROLE analytics_readonly;
CREATE USER goldenanalytics_svc
LOGIN_NAME = 'goldenanalytics_svc'
MUST_CHANGE_PASSWORD = FALSE;
GRANT ROLE analytics_readonly TO USER goldenanalytics_svc;
On BigQuery, assign the predefined roles/bigquery.dataViewer role on the specific dataset rather than the project. DataViewer grants bigquery.tables.getData and bigquery.tables.list without any write capabilities. If the tool only needs access to specific tables, a custom IAM role with only those permissions scoped to individual table resources is even more restrictive.
On Redshift, create a group with SELECT privileges on the relevant schemas and tables. No schema creation, no TEMP privileges (Redshift's TEMP permission allows creating temporary tables, which is write access that analytics tools sometimes request and often do not need).
-- Redshift: read-only group
CREATE GROUP analytics_readers;
GRANT USAGE ON SCHEMA events TO GROUP analytics_readers;
GRANT SELECT ON ALL TABLES IN SCHEMA events TO GROUP analytics_readers;
ALTER DEFAULT PRIVILEGES IN SCHEMA events
GRANT SELECT ON TABLES TO GROUP analytics_readers;
CREATE USER goldenanalytics_svc PASSWORD '...';
ALTER GROUP analytics_readers ADD USER goldenanalytics_svc;
Row-Level Security and When to Use It
Row-level security (RLS) adds a filter to every query from a specific role or user so that they can only see a subset of rows in a table. For analytics tools, RLS is appropriate in two situations: when the tool will be used by multiple users with different data access scopes, or when your table contains data that should not be accessible to analytics queries at all (for example, PII rows mixed into an event table that should only be read by a GDPR-compliant workflow).
On Snowflake, row access policies are defined as a function that returns a boolean and attached to a table. The policy runs at query time and filters rows based on the current role. An analytics tool service account can be mapped to a policy that excludes rows flagged as containing PII or rows belonging to regions the tool is not authorized to read.
On BigQuery, row-level security is implemented through row access policies on individual tables. The policy specifies which rows a given filter group can see. This is useful for multi-tenant analytics scenarios where different product managers should see attribution results only for their respective product areas, but all queries run through the same service account.
We are not saying you should implement RLS for every analytics tool integration. For a small team where all analysts have the same access scope and the event table contains no PII-tagged rows, the additional management overhead of RLS is not justified. The read-only service account alone addresses most of the risk. RLS becomes valuable when your user population has different access requirements or when your data model mixes sensitive and non-sensitive rows in the same table.
Credential Rotation and Monitoring
A read-only service account that uses the same credential indefinitely is less secure than one with regular rotation. For warehouse integrations with analytics tools, the practical approach is to use a secrets manager (AWS Secrets Manager, Google Secret Manager, or HashiCorp Vault) to store and rotate the service account credentials on a schedule, with the analytics tool pulling the current credential from the secrets manager rather than having a static credential in its configuration.
Most analytics platforms that support warehouse connections also support credential injection from a secrets manager. If your vendor requires a static credential in their configuration UI, that is worth noting as a security consideration during vendor selection.
Monitoring for the read-only account means watching for anomalous query patterns: unexpectedly high scan volumes, queries running at unusual times, or queries referencing schemas outside the expected scope. This monitoring is much simpler when the account only generates SELECT operations, because any DDL or DML entry in the audit log for that account is definitionally anomalous.
Vetting Vendors on Access Requirements
The right time to think about service account permissions is before an analytics tool is connected, not after. The questions to ask a vendor before setup:
- Does your product require write access to the customer warehouse, or does it operate entirely read-only?
- If you use temporary tables or caching layers within the warehouse, which schema do those land in, and how are they cleaned up?
- What is the minimum permission set required for full product functionality?
- Can the product run against a read-only service account without degraded functionality?
A vendor that cannot clearly answer these questions or that pushes back on read-only access as a constraint is a signal to examine the architecture more carefully before connecting your production warehouse. The data in your warehouse is not an appropriate cost of doing business for analytics tooling. Read-only access protects it without meaningfully limiting what analytics workflows can accomplish.