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

# Policies

> Policy delivery is live; policy authoring is not built

# Policies

<Info>
  **What is shipped:** the delivery lane. Every endpoint fetches its policy set
  from the cloud on each heartbeat and applies whatever it receives.

  **What is not:** authoring. There is no API to create a policy, and no policy
  editor. Consequently **every organization is currently served an empty rule
  set**, so no rule reaches any endpoint and nothing is blocked.

  This page previously said policy management was "under active development" with
  blocking "on the roadmap." That understated the delivery half and overstated the
  authoring half. This is the corrected version.
</Info>

## GET /v1/machines/{id}/policies

Returns the policy set for one machine. Called by the daemon on its heartbeat
cycle, not by browsers.

|                 |                                                                    |
| --------------- | ------------------------------------------------------------------ |
| Auth            | API token with the `ingest` scope                                  |
| Response        | A JSON **array** of policy objects (bare array, not an envelope)   |
| Caching         | `ETag` on every response; a matching `If-None-Match` returns `304` |
| `Cache-Control` | `no-store` — the ETag is the only cache, deliberately              |

The `ETag` is the **same value** the machine reports as `policy_hash` on its
heartbeat, computed in one place. That single-source property is what lets the
daemon detect "my policy is stale" without a second request; if the two were
ever computed separately, every host in the fleet would re-fetch on every
heartbeat while both endpoints answered `200`.

An empty policy set gets a **real hash**, not an empty string — so a policy can
be withdrawn and the endpoint will notice.

## Why rule arrays are empty today

Enforcement runs in **shadow mode fleet-wide**, and that is a decision rather
than a gap. The response is assembled from each organization's security
profiles, and the rule list is deliberately never populated: capability names
(`fs:read`, `net:egress`) are not yet mapped to the tool patterns an endpoint
matches on, so emitting them would produce rules that match nothing while the
console reported actions as blocked.

Behind that sits a guard that withholds rules from any profile not explicitly in
`enforce` mode, and counts what it withheld. It exists so that the day
capability-to-tool mapping is added, the default behaviour is **not** to promote
every shadow-mode profile in every customer organization into live enforcement.

You can observe what enforcement *would* have done today: the scope compiler
evaluates every action against the session's declared scope and reports the
verdict it would have taken, at `LOG_ONLY`. See
[Shadow enforcement](/dashboard/shadow-enforcement).

## What exists for configuration

Security profiles are real and admin-gated: `POST`, `GET`, `PUT`, `DELETE` on
`/v1/security-profiles`, plus `PUT /v1/groups/{id}/profile` to attach one to a
group. A profile carries allowed/blocked/gated capability lists, an enforcement
mode, thresholds, and a priority. Every organization is created with a default
`Balanced` profile in `monitor` mode.

There is no dashboard UI for security profiles yet.

## Not built

* Creating or editing a policy through the API or the dashboard
* Historical preview / dry-run of a candidate policy
* Any control that turns blocking on

See [Events API](/api/events) and [Sessions API](/api/sessions) for what is
queryable today.
