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

# Rule protocol fields

> Reference protocol fields in rule conditions using the Data Dictionary

Rules read the same scan evidence you search. A protocol field you can query in
InfraQL is available to a rule condition under the `infrawatch` module, so there
is one field reference for both: the [Data Dictionary](/data-dictionary).

## Map a search field to a rule path

Take the service field and prefix it with `infrawatch.scan.`:

| InfraQL on `services`            | Rule condition                                   |
| -------------------------------- | ------------------------------------------------ |
| `http.response.status_code`      | `infrawatch.scan.http.response.status_code`      |
| `redis.authentication_required`  | `infrawatch.scan.redis.authentication_required`  |
| `mqtt.anonymous_connect_allowed` | `infrawatch.scan.mqtt.anonymous_connect_allowed` |
| `port`                           | `infrawatch.scan.port`                           |

That is the whole mapping. Browse the fields, their types, and their meanings in
the Data Dictionary, then write the condition against the prefixed path.

<CardGroup cols={2}>
  <Card title="Service fields" icon="ethernet" href="/data-dictionary/services">
    Every protocol, its fields, and what each value means.
  </Card>

  <Card title="Common fields" icon="list-tree" href="/data-dictionary/services/common">
    Port, transport, protocol, and the fields shared across every service.
  </Card>
</CardGroup>

## Write the condition

Guard a field with `defined` before comparing it. A service that was never
observed speaking the protocol has no value there, and an unguarded comparison
against it does not match:

```yara theme={null}
import "infrawatch"

rule Exposed_Redis_Without_Authentication {
  meta:
    description = "Redis accepted a probe without requiring authentication"

  condition:
    defined infrawatch.scan.redis.authentication_required and
    infrawatch.scan.port == 6379 and
    not infrawatch.scan.redis.authentication_required
}
```

String fields support the comparisons you would expect, including
case-insensitive matching:

```yara theme={null}
condition:
  defined infrawatch.scan.http.response.body.html.title and
  infrawatch.scan.http.response.body.html.title icontains "admin"
```

## Confirm the exact field set

The Data Dictionary is the readable reference. When you need certainty, ask the
API for the authoritative set:

| Endpoint                      | Use it for                                                                       |
| ----------------------------- | -------------------------------------------------------------------------------- |
| `GET /rules/authoring/schema` | The closed set of fields authorable for a rule input kind, including enum values |
| `POST /rules/validate`        | Compiling your source against the production modules without saving it           |

The authoring schema is derived from the protobuf descriptors linked into the
same binary as the rule runtime, so it is exact by construction. It is also
where to look for a protocol the Data Dictionary does not list yet, because
scanning can observe a protocol before it is exposed as a search field.

<Tip>
  Validate before saving. `POST /rules/validate` compiles the real source and
  returns compiler diagnostics, which is faster than finding a typo after the
  rule is live.
</Tip>

<CardGroup cols={2}>
  <Card title="Write a rule" icon="code" href="/scanning/rules/writing-rules">
    Structure, metadata, classification, and the rule lifecycle.
  </Card>

  <Card title="Copy an example" icon="flask" href="/scanning/rules/examples">
    Working detections for common exposure patterns.
  </Card>
</CardGroup>
