Labs4Change

Looker Permissions Done Right: Groups, Access Grants, and Row-Level Security

A practical guide to Looker permissions — groups-first access, row-level security, column-level grants, and the folder structure that keeps content governed.

Most Looker instances we audit have the same problem: permissions assigned to individual users, no consistent group structure, and sensitive fields visible to everyone. It works until someone asks "who can see revenue data?" and nobody knows the answer.

Here's how to fix it.

The Groups-First Rule

Never assign permissions to individual users. Every permission flows through groups.

This sounds obvious, but we see it violated constantly. Someone needs access "just for today," an admin grants it directly, and six months later you have 40 users with individually assigned permissions that nobody can audit.

The structure that works:

Department Groups:
├── Marketing
│   ├── Marketing Developers    # Development mode, deploy access
│   ├── Marketing Users         # Explore access, content creation
│   └── Marketing Viewers       # Dashboard-only access
├── Sales
│   ├── Sales Developers
│   ├── Sales Users
│   └── Sales Viewers
└── Finance
    ├── Finance Developers
    ├── Finance Users
    └── Finance Viewers

Three permission tiers per department. Developers can build. Users can explore. Viewers can see dashboards. That's it. When someone changes roles, you move them between groups — you don't touch individual permissions.

Model Sets and Permission Sets

Model sets control which LookML models a group can access. Permission sets control what they can do.

Keep model sets aligned with business domains:

  • Marketing Models — campaigns, attribution, web analytics
  • Sales Models — pipeline, revenue, forecasting
  • Finance Models — P&L, budgets, actuals
  • Core Models — shared dimensions like customers, products, dates

A Marketing User gets the Marketing Models + Core Models model set, paired with a "User" permission set that allows explore access and content creation. A Marketing Viewer gets the same model set but a "Viewer" permission set that only allows dashboard viewing.

Folder Structure for Content Governance

Your Looker folder structure should mirror your group structure:

Shared/
├── Marketing/
│   ├── Production/      # Marketing Viewers: View, Marketing Developers: Edit
│   ├── Development/     # Marketing Developers: Manage Access
│   └── UAT/             # Marketing Users: View, Marketing Developers: Edit
├── Sales/
│   ├── Production/
│   ├── Development/
│   └── UAT/
└── Finance/
    ├── Production/
    ├── Development/
    └── Restricted/      # Finance Developers only

The key principle: Production folders are read-only for non-developers. Development folders are where new content gets built. UAT is where stakeholders review before promotion. This prevents the common problem of 200 half-finished dashboards cluttering the production space.

Row-Level Security with User Attributes

Row-level security filters data based on who's looking at it. A regional manager sees their region. A global VP sees everything.

Step 1: Create a user attribute (e.g., user_region) in the Looker Admin panel. Assign values at the group level, not individual level.

Step 2: Apply the access filter in your explore:

explore: orders {
  access_filter: {
    field: orders.region
    user_attribute: user_region
  }
}

Users with user_region = "EMEA" only see EMEA orders. Users with user_region = "%" see everything.

Rules that prevent headaches:

  1. Always assign user attributes at the group level
  2. Use % or NULL for unrestricted access — never create an "all regions" value
  3. Test with at least three different user types before deploying
  4. Document which attributes are used where — this gets forgotten fast

Column-Level Security with Access Grants

Access grants hide sensitive fields from users who shouldn't see them. Revenue, margins, PII — anything that not everyone should access.

Step 1: Define the access grant in your model:

access_grant: see_revenue {
  user_attribute: can_see_revenue
  allowed_values: ["yes"]
}

Step 2: Apply it to specific fields:

dimension: revenue {
  required_access_grants: [see_revenue]
  type: number
  sql: ${TABLE}.revenue ;;
}

measure: total_margin {
  required_access_grants: [see_revenue]
  type: number
  sql: ${total_revenue} - ${total_cost} ;;
}

Users without can_see_revenue = "yes" won't see these fields in the explore at all. They don't get an error — the fields simply don't exist for them.

You can stack multiple grants:

dimension: customer_ssn {
  required_access_grants: [pii_access, customer_data_access]
  sql: ${TABLE}.customer_ssn ;;
}

Both grants must be satisfied. This is useful for fields that require multiple levels of authorization.

The Audit Checklist

Run this quarterly. It takes 30 minutes and prevents the permission drift that makes governance impossible.

  1. No individual permissions — every user's access comes through groups only
  2. No orphaned users — everyone belongs to at least one group
  3. Model sets are current — no deprecated models still in rotation
  4. User attributes are group-assigned — no individual overrides
  5. Production folders are locked — only developers can edit
  6. Access grants cover all sensitive fields — revenue, PII, internal metrics
  7. Row-level security is tested — log in as different user types and verify

Common Mistakes

Mistake 1: Using sql_always_where instead of access_filter. Both filter data, but sql_always_where applies to everyone and can't be user-specific. Use access_filter for row-level security.

Mistake 2: Granting see_sql permission to non-developers. Users with see_sql can see the underlying query, which may expose table names, column names, and join logic you'd rather keep internal.

Mistake 3: Not testing with cached results. Looker caches query results. If you change permissions, the cached result may still be visible until the cache expires. Always clear the cache after permission changes and verify.

Get the LookML Best Practices Guide + AI Skill

6 patterns covering auto-generated views, refinements, derived tables, and more — plus an AI agent skill that enforces best practices in your editor.

Labs4Change has trained 16,000+ analytics engineers and audited hundreds of Looker instances. Book a free strategy call if you need help getting your Looker permissions right.