Configuration Schema
Reference for Neuwerk policy payloads accepted by the management API.
This page documents the singleton policy payload accepted by the management API. The authoritative
machine-readable source is the generated OpenAPI document at /openapi/neuwerk-v1.json,
especially these components:
PolicyConfigSourceGroupConfigSourcesConfigRuleConfigRuleMatchConfigTlsMatchConfig
Scope
The current configuration schema is the payload accepted by the singleton policy API:
GET /api/v1/policyPUT /api/v1/policy
PUT /api/v1/policy accepts the policy document directly:
{
"default_policy": "deny",
"source_groups": []
}
Top-Level PolicyConfig
PolicyConfig has two top-level fields:
{
"default_policy": "deny",
"source_groups": [
{
"id": "branch-office",
"mode": "enforce",
"sources": {
"cidrs": ["10.10.0.0/16"]
},
"rules": []
}
]
}
default_policyAccepted as a policy string such asallowordenyOmit it to leave the default policy unset in the config objectsource_groupsOrdered list of source-group definitions Omit or leave empty to create a policy with no source groups
SourceGroupConfig
Each source group defines a source population and the rules applied to that population.
{
"id": "branch-office",
"mode": "enforce",
"priority": 100,
"sources": {
"cidrs": ["10.10.0.0/16"],
"ips": ["10.10.1.20"]
},
"rules": [],
"default_action": "deny"
}
Fields:
idRequired stable identifier for the source groupmodeRequired rollout mode for the source group, eitherauditorenforcepriorityOptional explicit evaluation priority If omitted, the control plane falls back to list ordersourcesRequired source selector blockrulesOptional list of rule definitionsdefault_actionOptional fallback action within the source group
SourcesConfig
sources can be populated from static IP material, Kubernetes selectors, or both.
{
"cidrs": ["10.10.0.0/16"],
"ips": ["10.10.1.20"],
"kubernetes": [
{
"integration": "cluster-a",
"pod_selector": {
"namespace": "payments",
"match_labels": {
"app": "api"
}
}
}
]
}
Fields:
cidrsList of IPv4 CIDR stringsipsList of individual IPv4 stringskubernetesList of Kubernetes-backed dynamic source selectors
Validation semantics:
- The effective source set must not be empty.
- Each Kubernetes source must set exactly one of
pod_selectorornode_selector. integrationis required and must refer to an existing Kubernetes integration when the policy is written through the HTTP API.
Kubernetes Source Selectors
Pod selector form:
{
"integration": "cluster-a",
"pod_selector": {
"namespace": "payments",
"match_labels": {
"app": "api"
}
}
}
Node selector form:
{
"integration": "cluster-a",
"node_selector": {
"match_labels": {
"topology.kubernetes.io/zone": "eu-central-1a"
}
}
}
RuleConfig
Each rule combines metadata, an action, an optional mode override, and a match block. Rule mode,
when present, overrides the containing source-group mode.
{
"id": "allow-dns",
"priority": 10,
"action": "allow",
"mode": "enforce",
"match": {
"proto": "udp",
"dst_ports": [53]
}
}
Fields:
idRequired rule identifierpriorityOptional explicit evaluation priorityactionPolicy string such asallowordenymodeOptional rule-local mode, eitherauditorenforcematchRequiredRuleMatchConfig
RuleMatchConfig
The match object combines L3, L4, ICMP, DNS, and TLS selectors.
{
"dst_cidrs": ["203.0.113.0/24"],
"dst_ips": ["203.0.113.20"],
"dns_hostname": "*.example.com",
"proto": "tcp",
"src_ports": ["1024-65535"],
"dst_ports": [443],
"icmp_types": [],
"icmp_codes": [],
"tls": {
"mode": "metadata",
"sni": {
"exact": ["api.example.com"]
}
}
}
Fields:
dst_cidrsDestination CIDR stringsdst_ipsDestination IPv4 stringsdns_hostnameOptional hostname matcher for DNS policy compilationprotoProtocol selectorsrc_portsSource port selectorsdst_portsDestination port selectorsicmp_typesICMP type selectorsicmp_codesICMP code selectorstlsOptional TLS and HTTP matcher block
ProtoValue
proto accepts either a string or a numeric protocol value.
Examples:
"proto": "tcp"
"proto": 6
PortSpec
Port arrays accept either integers or strings.
Examples:
"dst_ports": [443, 8443]
"dst_ports": ["80-81", "10000-10100"]
Validation semantics:
- TLS matchers require
prototo resolve totcporany. - ICMP type and code filters require
prototo resolve toicmporany. - ICMP rules cannot use source or destination port filters.
- If
protoresolves toicmpand no ICMP types or codes are set, the compiler injects a default set of common ICMP controls.
TLS Matchers
TLS matching lives under match.tls.
{
"mode": "intercept",
"sni": {
"exact": ["api.example.com"],
"regex": ".*\\.example\\.com"
},
"server_dn": "CN=api.example.com,O=Example Corp",
"server_san": ["api.example.com", "www.example.com"],
"server_cn": "api.example.com",
"fingerprint_sha256": [
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
],
"trust_anchors_pem": [
"-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n"
],
"tls13_uninspectable": "deny",
"http": {
"request": {
"methods": ["GET"],
"path": {
"prefix": ["/admin"]
}
}
}
}
Fields:
modemetadataorinterceptsniTLS name matcherserver_dnRaw distinguished-name string matchserver_sanTLS name matcher for SAN valuesserver_cnTLS name matcher for CN valuesfingerprint_sha256List of certificate fingerprintstrust_anchors_pemPEM-encoded trust anchorstls13_uninspectableallowordenyhttpOptional HTTP request and response matcher block for intercepted traffic
TlsNameMatchConfig
TLS name matchers accept three encodings:
String form:
"sni": ".*\\.example\\.com"
List form:
"server_san": ["api.example.com", "www.example.com"]
Object form:
"server_cn": {
"exact": ["api.example.com"],
"regex": ".*\\.example\\.com"
}
HTTP Matchers Inside TLS
When tls.http is present, at least one of request or response must be set.
HttpRequestPolicyConfig
{
"host": {
"exact": ["api.example.com"]
},
"methods": ["GET", "POST"],
"path": {
"prefix": ["/v1/"]
},
"query": {
"keys_present": ["tenant"],
"key_values_exact": {
"env": ["prod"]
}
},
"headers": {
"require_present": ["x-request-id"],
"exact": {
"x-env": ["prod"]
}
}
}
Fields:
hostExact and/or regex hostname matchermethodsHTTP methods, normalized to uppercase by the compilerpathExact, prefix, and/or regex path matcherqueryPresence, exact value, and regex value matching for query paramsheadersPresence, deny-presence, exact, and regex matching for headers
HttpResponsePolicyConfig
{
"headers": {
"deny_present": ["set-cookie"]
}
}
This currently supports response-header matching only.
Field Encoding Notes
- Most optional fields can be omitted entirely.
- Arrays default to empty arrays when omitted.
- Several matcher enums are intentionally untagged, so the same field may accept either a scalar, an array, or an object depending on context.
- The OpenAPI artifact captures those unions explicitly and should be treated as the authoritative machine-readable form.
Compatibility Notes
This schema reflects the current Rust implementation, not a versioned long-term compatibility contract yet.
Today, the safest assumptions are:
- new optional fields may be added
- matcher validation may tighten as unsupported combinations are rejected earlier
- write-time validation is authoritative over docs prose
If you need exact field shapes for tooling, consume /openapi/neuwerk-v1.json and pin to a tested
Neuwerk version rather than relying only on this page.