> ## Documentation Index
> Fetch the complete documentation index at: https://hoopdev-docs-control-plane-owns-listeners.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Direct Access

> The straight-through path. Guardrails and Data Masking apply inline, with no model in the way.

Direct access is the default path through the [Sidecar](/core-concepts/sidecar). A request arrives, the Sidecar decodes it, evaluates it against the rules you wrote, and forwards it. The response comes back through the same gate and sensitive values are rewritten before they reach the client.

Nothing about this path is probabilistic. The same statement produces the same decision every time, there is no third-party API in the chain, and the only latency added is a parse and a scan.

```mermaid theme={null}
flowchart LR
    C(["client"]) --> GR["Guardrails<br/><i>on the request</i>"]
    GR -->|allowed| R["Resource"]
    GR -->|denied| D(["error in the<br/>protocol's own frame"])
    R -->|response| DM["Data Masking"]
    DM --> C

    style R fill:#2d5016,color:#fff
```

***

## Configuration

A listener is one upstream. Add [`guardrails`](/features/guardrails) to control what reaches the resource, and [`mask`](/features/data-masking) to control what comes back. Both are optional and independent.

```yaml config.yaml theme={null}
listeners:
  - name: appdb                 # the name audit rows and rules key on
    protocol: postgres          # postgres | mssql | http
    listen: 127.0.0.1:15432
    upstream: appdb:5432

    guardrails:
      rules:
        - name: no-destructive-sql
          type: operation
          operations: [drop, delete, truncate]
          message: destructive statements are not permitted on appdb

    mask:
      rules:
        - {name: emails, entities: [EMAIL_ADDRESS], strategy: redact}
```

Neither block takes a switch: a rule set that reaches a lane enforces, and a `mask` block carrying rules masks. Detection needs no `pii` section either — omit it and every supported entity is enabled.

Validate before deploying — nothing needs to be running:

```bash theme={null}
hoop start sidecar --config config.yaml --validate
```

```
config OK: 1 listener(s)
  appdb            postgres  1 rule(s) + masking
```

<Warning>
  **A lane always enforces.** There is no observe-only switch, so a rule that reaches a listener denies from the first request. Roll out on a staging lane, watch `/api/events?kind=violation`, and use `action: defer` for anything you are not ready to decide locally — see [Roll out without breaking anything](/features/guardrails#roll-out-without-breaking-anything).
</Warning>

***

## What the user sees when a rule denies

The refusal is written in the protocol's own frame, always to the client, carrying the message you wrote:

```bash theme={null}
PGSSLMODE=disable psql -h 127.0.0.1 -p 15432 -U appuser -d appdb \
  -c 'DELETE FROM customers WHERE id = 1;'
```

```
FATAL:  destructive statements are not permitted on appdb
```

That is a real pgwire `ErrorResponse`, so the developer reads the reason in `psql` rather than watching a connection drop. On an HTTP listener the equivalent is a `403` with an `X-Hoop-Denied` header.

***

## Direct or Agentic?

Both paths run in the same Sidecar and a listener picks per rule, so this is not an either/or for the deployment — only for a given class of statement.

|                     | Direct Access                                                               | [Agentic Access](/features/agentic-access)   |
| ------------------- | --------------------------------------------------------------------------- | -------------------------------------------- |
| Decides with        | rules you wrote                                                             | a language model classifying the statement   |
| Determinism         | same input, same verdict                                                    | a classification, with a cache               |
| Latency added       | parse and scan                                                              | a model call, roughly 100 ms to 2 s uncached |
| External dependency | none                                                                        | your model provider                          |
| Failure mode        | fails closed                                                                | fails open by default                        |
| Best for            | effects you can name — destructive verbs, protected tables, forbidden paths | intent you cannot enumerate in advance       |

The usual shape is direct rules for everything nameable, and an `ai_analysis` rule as the backstop for the rest.

***

## Next

<CardGroup cols={2}>
  <Card title="Guardrails" icon="shield-halved" href="/features/guardrails">
    Every rule type, and how a rule set resolves to a verdict.
  </Card>

  <Card title="Data Masking" icon="mask" href="/features/data-masking">
    Detection, masking strategies, and entity rules versus column rules.
  </Card>

  <Card title="Agentic Access" icon="robot" href="/features/agentic-access">
    Let a model classify the statement and pick the tool.
  </Card>

  <Card title="Config File Reference" icon="file-code" href="/setup/configuration/hoop-sidecar/config-file">
    Every listener field, inheritance between listeners, and what startup refuses.
  </Card>
</CardGroup>
