> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.hoop.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Access Control

> Control who can access which resource roles with group-based permissions

export const ObservabilityAnimation = () => {
  const ACTIONS = [{
    action: 'SELECT * FROM users',
    score: 'low',
    status: 'logged',
    color: 'rgba(var(--success-rgb),0.7)'
  }, {
    action: 'kubectl get pods -n prod',
    score: 'low',
    status: 'logged',
    color: 'rgba(var(--success-rgb),0.7)'
  }, {
    action: 'UPDATE config SET rate=500',
    score: 'medium',
    status: 'approved',
    color: 'var(--warm-gold)'
  }, {
    action: 'DELETE FROM cache WHERE 1=1',
    score: 'high',
    status: 'approved',
    color: 'var(--warm-gold)'
  }, {
    action: 'DROP TABLE temp_exports',
    score: 'critical',
    status: 'blocked',
    color: 'var(--error)'
  }];
  const ITEM_DELAY = 900;
  const CYCLE_PAD = 2500;
  const [cycle, setCycle] = useState(0);
  const [visible, setVisible] = useState(0);
  const timers = useRef([]);
  function T(fn, ms) {
    const id = setTimeout(fn, ms);
    timers.current.push(id);
  }
  useEffect(() => {
    timers.current.forEach(clearTimeout);
    timers.current = [];
    setVisible(0);
    ACTIONS.forEach((_, i) => {
      T(() => setVisible(i + 1), (i + 1) * ITEM_DELAY);
    });
    T(() => setCycle(c => c + 1), ACTIONS.length * ITEM_DELAY + CYCLE_PAD);
    return () => timers.current.forEach(clearTimeout);
  }, [cycle]);
  const logged = ACTIONS.slice(0, visible).length;
  const blocked = ACTIONS.slice(0, visible).filter(a => a.status === 'blocked').length;
  return <div className="ob-root" aria-hidden="true">
      <div className="mock-container ob-mock">
        <div className="mock-toolbar" style={{
    justifyContent: 'space-between'
  }}>
          <div style={{
    display: 'flex',
    gap: 6
  }}>
            <div className="mock-dot" /><div className="mock-dot" /><div className="mock-dot" />
          </div>
          <span className="ob-title">agent session · sess_01jkx7r2nb4f</span>
          <span style={{
    width: 48
  }} />
        </div>

        {}
        <div className="ob-header">
          <span className="ob-col-action">Action</span>
          <span className="ob-col-risk">Risk</span>
          <span className="ob-col-status">Status</span>
        </div>

        <div className="ob-list">
          {ACTIONS.map((a, i) => {
    const show = i < visible;
    return <div key={i} className={`ob-row${show ? ' ob-vis' : ''}`}>
                <span className="ob-action">{a.action}</span>
                <span className="ob-risk" style={{
      color: a.color
    }}>{show ? a.score : ''}</span>
                <span className={`ob-status ob-status-${a.status}`}>{show ? a.status : ''}</span>
              </div>;
  })}
        </div>

        <div className="ob-footer">
          <span className="ob-footer-dot" />
          <span>{logged} actions logged · {blocked} blocked</span>
        </div>
      </div>

      <style>{`
        .ob-root { width: 100%; }
        .ob-mock { border-radius: 12px; overflow: hidden; }
        .ob-title { font-family: var(--mono); font-size: 11px; color: rgba(var(--sand-100-rgb),0.2); }

        .ob-header {
          display: grid; grid-template-columns: 1fr 70px 80px; gap: 8px;
          padding: 8px 16px; border-bottom: 1px solid rgba(var(--sand-100-rgb),0.06);
          font-family: var(--sans); font-size: 10px; font-weight: 500;
          text-transform: uppercase; letter-spacing: 0.06em;
          color: rgba(var(--sand-100-rgb),0.25);
        }

        .ob-list { padding: 4px 16px; min-height: 180px; }

        .ob-row {
          display: grid; grid-template-columns: 1fr 70px 80px; gap: 8px;
          padding: 7px 0; border-bottom: 1px solid rgba(var(--sand-100-rgb),0.04);
          opacity: 0; transform: translateY(4px);
          transition: opacity 0.3s ease, transform 0.3s ease;
        }
        .ob-row.ob-vis { opacity: 1; transform: translateY(0); }

        .ob-action { font-family: var(--mono); font-size: 11px; color: rgba(var(--sand-100-rgb),0.5); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        .ob-risk { font-family: var(--sans); font-size: 10px; font-weight: 600; text-transform: uppercase; }

        .ob-status {
          font-family: var(--sans); font-size: 10px; font-weight: 500;
        }
        .ob-status-logged { color: rgba(var(--sand-100-rgb),0.3); }
        .ob-status-approved { color: var(--warm-gold); }
        .ob-status-blocked { color: var(--error); }

        .ob-footer {
          display: flex; align-items: center; gap: 7px;
          padding: 10px 16px; border-top: 1px solid rgba(var(--sand-100-rgb),0.06);
          font-family: var(--sans); font-size: 11px; color: rgba(var(--sand-100-rgb),0.25);
        }
        .ob-footer-dot {
          width: 6px; height: 6px; border-radius: 50%; background: var(--warm-gold);
          animation: ob-p 2s ease-in-out infinite;
        }
        @keyframes ob-p { 0%,100%{opacity:.5} 50%{opacity:1} }
      `}</style>
    </div>;
};

<div style={{background: 'linear-gradient(135deg, #111111 0%, #1A1A1A 35%, #2A2A2A 70%, #3A3A3A 100%)', borderRadius: 14, overflow: 'hidden', padding: 24, height: 350}}>
  <ObservabilityAnimation />
</div>

## What You'll Accomplish

Access Control lets you restrict which users can see and use specific resource roles. Instead of giving everyone access to everything, you can:

* Limit production database access to senior engineers
* Give read-only access to analysts
* Restrict sensitive systems to specific teams
* Automatically sync permissions from your identity provider

***

## How It Works

Access Control uses **groups** to manage permissions. Users belong to groups, and resource roles are configured to allow access from specific groups.

<Steps>
  <Step title="User Authenticates">
    User logs in via your identity provider (Okta, Auth0, etc.)
  </Step>

  <Step title="Groups Synced">
    User's group memberships are synced from the identity provider
  </Step>

  <Step title="Access Evaluated">
    When accessing a resource role, Hoop checks if the user's groups are allowed
  </Step>

  <Step title="Access Granted or Denied">
    User sees the resource role if allowed, or gets an access denied error
  </Step>
</Steps>

### Example

| User  | Groups                  | Can Access                  |
| ----- | ----------------------- | --------------------------- |
| Alice | `engineering`, `senior` | prod-db, staging-db, dev-db |
| Bob   | `engineering`           | staging-db, dev-db          |
| Carol | `analytics`             | analytics-db (read-only)    |
| Dave  | `support`               | support-db                  |

***

## Groups and Roles

Access is granted to **groups**, not individual users. Groups come from two places:

* **Synced from your identity provider** — when users log in, their group memberships (Okta, Auth0, Azure AD, etc.) are synced to Hoop automatically.
* **Created in Hoop** — you can also manage groups directly in the Web App.

### Built-in Roles

| Role      | Description                                    |
| --------- | ---------------------------------------------- |
| `admin`   | Full access to all resource roles and settings |
| `auditor` | Read-only access to sessions and audit logs    |

<Note>
  Admin users bypass Access Control and can access all resource roles. Use admin sparingly.
</Note>

***

## Common Patterns

### Pattern 1: Environment-Based Access

Restrict production access to senior team members:

| Resource Role | Allowed Groups               |
| ------------- | ---------------------------- |
| prod-db       | `senior-engineers`, `dba`    |
| staging-db    | `engineering`                |
| dev-db        | `engineering`, `contractors` |

### Pattern 2: Team-Based Access

Each team only sees their own resources:

| Resource Role | Allowed Groups                   |
| ------------- | -------------------------------- |
| payments-db   | `payments-team`                  |
| inventory-db  | `inventory-team`                 |
| analytics-db  | `analytics-team`, `data-science` |

### Pattern 3: Role-Based Access

Different access levels for different roles:

| Resource Role     | Allowed Groups           |
| ----------------- | ------------------------ |
| prod-db-readwrite | `dba`                    |
| prod-db-readonly  | `engineering`, `support` |
| prod-db-analytics | `analytics`              |

<Tip>
  Create multiple resource roles to the same database with different credentials for different access levels.
</Tip>

### Pattern 4: Contractor Access

Temporary access for external contractors:

1. Create a `contractors` group
2. Add contractors to the group
3. Only allow `contractors` group on specific, limited resource roles
4. Remove from group when contract ends

***

## Combining with Other Features

Access Control works with other Hoop security features:

| Feature               | Combined Behavior                                        |
| --------------------- | -------------------------------------------------------- |
| **Access Requests**   | Users in allowed groups can request access; others can't |
| **Guardrails**        | Allowed users still subject to query restrictions        |
| **Live Data Masking** | Allowed users see masked data                            |
| **Session Recording** | All access is audited regardless of permissions          |

### Example: Layered Security

For a production database:

1. **Access Control:** Only `senior-engineers` can see the resource role
2. **Access Requests:** Require JIT approval before connecting
3. **Guardrails:** Block `DROP TABLE` and `DELETE` without WHERE
4. **Live Data Masking:** Redact PII in query results
5. **Session Recording:** Log all queries for audit

***

## Best Practices

<CardGroup cols={2}>
  <Card title="Least Privilege" icon="shield-check">
    Grant minimum access needed for each role
  </Card>

  <Card title="Use Groups, Not Users" icon="users">
    Assign access to groups, not individual users
  </Card>

  <Card title="Regular Audits" icon="clipboard-check">
    Review access permissions quarterly
  </Card>

  <Card title="Document Policies" icon="file-lines">
    Write down who should have access to what
  </Card>
</CardGroup>

### Access Review Checklist

Quarterly, review:

* Are all group memberships still appropriate?
* Are there users who left but still have access?
* Are there resource roles that should have stricter access?
* Are contractors' access limited to their engagement period?

***

<Note>
  Ready to set it up? The [Access Control configuration guide](/setup/configuration/access-control-configuration) walks through enabling Access Control, configuring resource roles, managing groups, and syncing groups from your identity provider.
</Note>

## Next Steps

<CardGroup cols={2}>
  <Card title="Configuration Guide" icon="gear" href="/setup/configuration/access-control-configuration">
    Detailed configuration options
  </Card>

  <Card title="Identity Providers" icon="id-card" href="/setup/configuration/idp/get-started">
    Set up SSO and group sync
  </Card>

  <Card title="Access Requests" icon="clock" href="/learn/features/access-requests/jit">
    Add approval workflows
  </Card>

  <Card title="Guardrails" icon="shield" href="/learn/features/guardrails">
    Block dangerous operations
  </Card>
</CardGroup>
