Reference For: developers

NSX Policy API subset

The part of the NSX Policy API that Kyvernon serves for the distributed firewall: paths, objects, mapping to firewall objects, differences and gaps.

Kyvernon serves a subset of the NSX Policy API over its own distributed firewall, so that tools written for that API can manage groups, services, security policies, rules and virtual machine tags. It is not NSX. NSX is named here to describe the API that existing tools speak, and compatibility is claimed only for the endpoints, fields and tools listed on this page. Objects written through this endpoint are ordinary firewall objects: the console, the CLI and the native API show and change them as well.

Turning the endpoint on

The endpoint is off by default and has its own listener with the TLS certificate of the controller. The console does not offer these settings; they are part of the controller configuration (see Configuration) in the section [facades.nsx].

KeyDefaultMeaning
enabledfalseServe the endpoint. It is independent of enabled in [facades]
listen0.0.0.0:8445The address and port of the listener
product_version4.1.2.0.0The version that GET /api/v1/node/version reports. Clients enable features by it

Clients sign in with HTTP Basic on every request, or with POST /api/session/create (j_username and j_password), which answers with a JSESSIONID cookie; writes then carry the header X-XSRF-TOKEN. Both are facade sign-ins, so the sign-in policy for compatibility endpoints applies: by default the account needs a role assignment. The privileges are the native firewall privileges (Kyvernon.Firewall.*), see Firewall reference.

Scopes

ScopePath prefix below /policy/api/v1Objects
Provider/infraThe provider objects
A tenant, as an NSX project/orgs/default/projects/{tenant}/infraThe objects of one tenant. A tenant user works in its own project

Only the domain default exists. The tenants are listed, read only, at /orgs/default/projects.

Served endpoints

Below /policy/api/v1, with {scope} as in the table above.

EndpointMethods
{scope}GET; PATCH and PUT with a hierarchical body
{scope}/domains, {scope}/domains/defaultGET
{scope}/domains/default/groups, .../groups/{id}GET list; GET, PUT, PATCH, DELETE
.../groups/{id}/members/virtual-machines, .../members/ip-addressesGET
{scope}/services, {scope}/services/{id}GET list; GET, PUT, PATCH, DELETE
{scope}/domains/default/security-policies, .../security-policies/{id}GET list; GET, PUT, PATCH, DELETE
.../security-policies/{id}/rules, .../rules/{rid}GET list; GET, PUT, PATCH, DELETE
.../security-policies/{id}/statistics, .../rules/{rid}/statisticsGET
{scope}/realized-state/status?intent_path=GET: REALIZED, IN_PROGRESS or ERROR
{scope}/realized-state/virtual-machines, .../enforcement-points/default/virtual-machinesGET with external_id or display_name
.../enforcement-points/default/virtual-machines?action=update_tagsPOST with {virtual_machine_id, tags}
{scope}/realized-state/virtual-machines/{id}/tagsPOST with {tags}, replaces the tags
{scope}/realized-state/enforcement-points/default/vifsGET with owner_vm_id
/search/query?query=, /search?query=GET
/orgs, /orgs/default, /orgs/default/projects, /orgs/default/projects/{id}GET

Outside /policy/api/v1:

EndpointMethods
/api/session/create, /api/session/destroyPOST
/api/v1/node/versionGET
/api/v1/fabric/virtual-machinesGET; POST with ?action=update_tags, add_tags or remove_tags and {external_id, tags}

Lists answer {results, result_count, cursor} and take page_size and cursor. Every object carries id, display_name, description, path, parent_path, relative_path, unique_id, resource_type, tags, _revision, _create_time, _create_user, _last_modified_time, _system_owned, _protection and marked_for_delete, which is always false. PUT answers with the object, PATCH and DELETE with an empty 200, and deleting an object that is absent is not an error. _revision is the version of the record, and a PUT with a stale one fails with 412.

Objects and their mapping

NSX objectFields acceptedKyvernon object and limits
Groupexpression, group_type, tagsA firewall group. Condition on VirtualMachine with the key Tag and the operator EQUALS (value scope|tag) becomes a tag criterion; AND is allowed between tag conditions, OR between criteria, and the criteria are at most 64. NestedExpression becomes a nested group. IPAddressExpression takes addresses, prefixes and ranges a-b. MACAddressExpression lists MAC addresses. PathExpression takes group paths of the same or the provider scope and /infra/segments/network-N (a host-bridge network). ExternalIDExpression takes virtual machine instance UUIDs, and adapters as <instance UUID>-<device key>. group_type is stored and not acted on
Serviceservice_entries, service_type, tagsA named firewall service. L4PortSetServiceEntry (TCP, UDP, with destination_ports and source_ports), ICMPTypeServiceEntry (ICMPv4, ICMPv6, icmp_type, icmp_code) and IPProtocolServiceEntry (protocol_number)
SecurityPolicycategory, sequence_number, stateful, tcp_strict, scope, locked, comments, rules, tagsA firewall policy. The categories are Emergency and Infrastructure (provider only), Environment and Application. scope is the applied-to list: ANY or group paths. A tenant sequence_number n is the sequence 1,000,000 + n of the policy; provider policies stay below 1,000,000. tcp_strict and comments are stored and not acted on
Rulesequence_number, source_groups, destination_groups, sources_excluded, destinations_excluded, services, service_entries, action, direction, ip_protocol, logged, disabled, scope, profiles, notes, tag, tags; read only: rule_idA firewall rule. Groups are paths, ANY, or literal addresses, prefixes and ranges. ALLOW, DROP, REJECT and JUMP_TO_APPLICATION map to allow, drop, reject and pass. ip_protocol is IPV4, IPV6 or IPV4_IPV6. profiles must be empty or ANY. Rules are ordered by sequence_number, and rule_id is the rule number
VirtualMachineexternal_id, display_name, power_state, tags, compute_idsA virtual machine. external_id is its instance UUID. A tag with scope and tag is the inventory tag tag in the category scope; an empty scope uses the category nsx
Statisticspacket_count, byte_count, hit_countThe counters of the rule. hit_count equals the packets, and the session fields are 0

An address range becomes the smallest list of prefixes that covers exactly that range, at most 256, and the endpoint returns the range as it was written.

The built-in services are read only (_system_owned is true): SSH, HTTP, HTTPS, DNS, DNS-UDP, NTP, SMTP, SMTP_TLS, SMTP-Submission, IMAP, IMAPS, POP3, POP3S, RDP, VNC, FTP, TFTP, LDAP, LDAP-UDP, LDAP-over-SSL, KERBEROS, KERBEROS-UDP, SNMP, SNMP-Trap, Syslog-UDP, Syslog-TCP, MySQL, PostgreSQL, MS-SQL-S, DHCP-Server, DHCP-Client, ICMP_Echo_Request, ICMP_Echo_Reply, ICMPv6_Echo_Request, ICMPv6_Echo_Reply, ICMP-ALL and ICMPv6-ALL.

Identity, names and concurrent writes

  • The id is chosen by the client, as in NSX, and is unique per scope. An object that the native API created appears under its native id, such as fwgroup-3, and clients cannot create objects under ids of that form.
  • display_name need not be unique and can have up to 255 characters. The endpoint returns it as written. The firewall object behind it has a unique name that Kyvernon derives: control characters, / and \ become _, a leading sys: gets the prefix nsx-, and a name that is taken or longer than 80 characters is shortened and followed by the id in brackets. After a change through another surface, the endpoint shows the native name.
  • Fields that the firewall model has no place for, such as tcp_strict, are kept as the client wrote them and returned unchanged while the object is not changed through another surface.
  • Writes that run at the same time, such as the parallel resources of Terraform, are each computed from the state they read. A write that loses the race to another writer runs again on the new state, up to 12 times. Only a stale _revision of the client is refused.
  • A write through the endpoint raises the same events as the native API, for example when a rule is added, changed, deleted or moved.
  • Tags that this endpoint created for virtual machines are removed with their last use, unless a firewall group names them. The tags carry the description Created for NSX tags. Tenant users neither see nor change tag categories that the provider manages.

Hierarchical call

PATCH and PUT on {scope} take an Infra body with ChildResourceReference or ChildDomain of the domain default. Below it, ChildGroup, ChildSecurityPolicy with ChildRule children, and ChildService at the top level are served; marked_for_delete removes an object. Any other child is refused with its position in the body. The whole body is checked as one: Kyvernon validates the objects and the result, and commits all of it or none of it. Objects that the body creates may refer to each other. This is the call that the Terraform NSX provider uses to write security policies.

GET /policy/api/v1/search/query?query= takes terms joined with AND : field:value on resource_type, id, display_name, path, parent_path, marked_for_delete, external_id, tags.scope, tags.tag or any top-level string field, and bare values, which match the id, the display name, the external id and the path. * is a wildcard, \ escapes, and quotes are allowed. The resource types are Group, Service, SecurityPolicy, Rule, VirtualMachine, Domain and Project. OR, NOT, parentheses and ranges are refused.

Errors

The endpoint answers with the NSX error body (httpStatus, error_code, module_name, error_message, related_errors) and the native message id in details.

Message idMeaning
error.nsx.unsupportedThe request uses a field or an area outside the subset. The message names it
error.nsx.invalidA field has a value that is not valid
error.nsx.not_foundThe path names no object that the account can see
error.nsx.revisionThe _revision of the write is stale
error.nsx.read_onlyA built-in object, or a tenant user who writes into /infra
error.nsx.xsrfA write without a valid X-XSRF-TOKEN

Errors of the native API keep their error.firewall.* id; see Firewall errors.

Differences and gaps

ItemBehaviour
Identity groups (IdentityGroupExpression)Refused. They need a directory service and an agent in every guest that reports user logins, which the platform does not have. Group virtual machines by tag instead
Other expressionsConditions on other keys or member types, and segment-port expressions, are refused with the field named
tcp_strict, comments, group_typeStored and returned, not acted on
locked: true, connectivity_strategy, schedulesRefused
Category EthernetRefused
Rule profilesMust be empty or ANY
source_portsAccepted in services and in the service_entries of a rule
Areas outside the subsetAnswer 400 error.nsx.unsupported with the feature named: gateway policies, segments, tier-0 and tier-1 gateways, context profiles, IDS, redirection, endpoint and forwarding policies, the exclusion list and infrastructure settings, load balancers, IP pools and blocks, schedules, the Manager API firewall sections, and domains other than default
Realization statusREALIZED when every connected host applied the change, ERROR while a host reports a firewall error, IN_PROGRESS otherwise
Session countsThe session fields of the statistics are always 0
After a rename through another surfaceThe endpoint shows the native name, which can carry a suffix
PowerCLIScripts that call the same paths work as far as the paths and fields above go; they were not run against the endpoint

Verified with Terraform

The Terraform NSX provider vmware/nsxt 3.12.2 was run against the endpoint through create, read, update, import and destroy.

ItemOperations that work
nsxt_policy_service (port set, ICMP and IP protocol entries, tags)Create, read, update, delete
nsxt_policy_group (tag conditions, addresses and ranges, MAC addresses, paths, external ids, project context)Create, read, update, import, delete
nsxt_policy_security_policyCreate, read, update, delete
nsxt_policy_parent_security_policyCreate, read, delete
nsxt_policy_security_policy_ruleCreate, read, delete
nsxt_policy_vm_tagsCreate, read, delete
Data sources nsxt_policy_service, nsxt_policy_group, nsxt_policy_vm, nsxt_policy_projectRead

The vSphere side of Terraform is described in Terraform vSphere provider.

Version 0.1. Last changed: 2026-11-14