- Security & Policies
- Policy set input
Policy set input
Every evaluation of a policy set gets one input document. The document has two views. This page lists every field. The published JSON schema has the same fields. ironflow policy pull writes it to .ironflow/input.schema.json.
Native view
Section titled “Native view”The native view is present for every check.
input.request
Section titled “input.request”| Field | Type | Meaning |
|---|---|---|
action | string | The verb, for example functions:invoke, orgs:manage, runs:read. It is the action that the route maps to, not the resource name in the URL. Every non-GET write on /api/v1/policy-set has orgs:manage. |
resource | string | The IRN of the resource, for example irn:ironflow:org_acme:proj_default:function:env_default:fn_payments. It is an empty string when the check has no resource. A ConnectRPC call at the route gate has an empty resource. For events:emit on a user emit, it is the event IRN irn:ironflow:{org}:{project}:event:{env}:{name}. Raw event names and invoked function IDs are encoded once: % becomes %25, then : becomes %3A. The resource is compared without percent-decoding. |
environment | string | The environment ID (for example env_default), not its name. |
org_id | string | The organization of the caller. |
input.subject
Section titled “input.subject”The shape is the same for API-key callers and for dashboard (JWT) callers.
| Field | Type | Meaning |
|---|---|---|
id | string | The user ID (user_...). Empty for a raw API key. |
user_email | string | The email of the user. Empty for a raw API key without a bound user. |
roles | array of strings | The role names of the caller. Always an array, never null. |
groups | array of strings | The group memberships. Always an array, never null. It is empty today. |
org | string | The home organization of the caller. |
project | string | The home project of the caller. |
env | string | The home environment of the caller. |
api_key_id | string | The key ID (ak_...) for an API-key caller. Empty otherwise. |
is_platform | boolean | True for a platform principal. |
webhook_source_id | string | The webhook source ID for an event that a webhook delivery emits. Empty otherwise. Such a subject has no role and may only do events:emit. |
Envoy view
Section titled “Envoy view”The Envoy view is present when the check is for an HTTP request: the pre-route gate for every HTTP and ConnectRPC request. Handler-side checks, such as the impersonation check, have no HTTP request and carry the native view only. The view copies the input of the OPA-Envoy plugin.
| Field | Type | Meaning |
|---|---|---|
input.attributes.request.http.method | string | The HTTP method. |
input.attributes.request.http.path | string | The path with the raw query string. The path is the one that the router acts on. It is normalized, and percent-decoding is applied as the router applies it. The token query parameter is removed. |
input.attributes.request.http.host | string | The Host of the request. |
input.attributes.request.http.scheme | string | http or https. |
input.attributes.request.http.headers | object | Header values by lower-case name. A header with many values is joined with a comma. The pseudo-headers :method, :path and :authority are present, as in Envoy. |
input.parsed_path | array of strings | The path without the query, split on /, with a leading / removed. Each segment is percent-decoded. An encoded slash stays inside its segment. |
input.parsed_query | object | Each query key maps to an array of values. The token key is removed. |
What is never present
Section titled “What is never present”- Headers. These headers never enter
input:authorization,proxy-authorization,cookie,set-cookie,ironflow-lease-token,x-api-keyandsec-websocket-protocol. The last one carries the bearer token of the WebSocket client. A policy can copy any input value into a deny reason, and reasons reach the audit log, so credentials must not be ininput. - The
tokenquery parameter. It is a legacy bearer credential and the webhook ingest token. Ironflow removes it frompathandparsed_query. If the query does not parse, Ironflow drops the whole query. - The body.
input.attributes.request.http.bodyandinput.parsed_bodyare absent. Ironflow does not buffer bodies, because that would break file uploads and streaming. - Source and destination.
input.attributes.sourceandinput.attributes.destinationare absent.
A policy that decodes the bearer token itself needs an adapter that reads input.subject. See Run an Envoy policy.
Example
Section titled “Example”This document is the input for a runs:read check from a dashboard user. The test suite uses it as a golden input.
{ "request": {"action": "runs:read", "resource": "irn:ironflow:o:p:run:e:*", "environment": "env_default", "org_id": "org_test"}, "subject": {"id": "u1", "user_email": "a@example.test", "roles": ["admin"], "groups": [], "org": "org_test", "project": "", "env": "", "api_key_id": "", "webhook_source_id": "", "is_platform": false}, "attributes": {"request": {"http": { "method": "GET", "path": "/api/v1/runs/run_1?expand=steps", "host": "ironflow.example.test", "scheme": "https", "headers": {"x-request-id": "r-1", ":method": "GET", ":path": "/api/v1/runs/run_1?expand=steps", ":authority": "ironflow.example.test"} }}}, "parsed_path": ["api", "v1", "runs", "run_1"], "parsed_query": {"expand": ["steps"]}}Dry-run input
Section titled “Dry-run input”A dry-run takes the same document. It must have an input.request object and an input.subject object. It evaluates the decision rule of the set only when the document has an attributes key. Without it, the dry-run behaves like a handler-side check and evaluates deny only.
Type checking
Section titled “Type checking”The server type-checks rules in package ironflow.authz against the schema when you write a set. A rule that treats a string field as a number fails with policy_set_schema_error. Other packages are not checked. They are your own policies, for your own input shape.