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].
| Key | Default | Meaning |
|---|---|---|
enabled | false | Serve the endpoint. It is independent of enabled in [facades] |
listen | 0.0.0.0:8445 | The address and port of the listener |
product_version | 4.1.2.0.0 | The 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
| Scope | Path prefix below /policy/api/v1 | Objects |
|---|---|---|
| Provider | /infra | The provider objects |
| A tenant, as an NSX project | /orgs/default/projects/{tenant}/infra | The 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.
| Endpoint | Methods |
|---|---|
{scope} | GET; PATCH and PUT with a hierarchical body |
{scope}/domains, {scope}/domains/default | GET |
{scope}/domains/default/groups, .../groups/{id} | GET list; GET, PUT, PATCH, DELETE |
.../groups/{id}/members/virtual-machines, .../members/ip-addresses | GET |
{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}/statistics | GET |
{scope}/realized-state/status?intent_path= | GET: REALIZED, IN_PROGRESS or ERROR |
{scope}/realized-state/virtual-machines, .../enforcement-points/default/virtual-machines | GET with external_id or display_name |
.../enforcement-points/default/virtual-machines?action=update_tags | POST with {virtual_machine_id, tags} |
{scope}/realized-state/virtual-machines/{id}/tags | POST with {tags}, replaces the tags |
{scope}/realized-state/enforcement-points/default/vifs | GET 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:
| Endpoint | Methods |
|---|---|
/api/session/create, /api/session/destroy | POST |
/api/v1/node/version | GET |
/api/v1/fabric/virtual-machines | GET; 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 object | Fields accepted | Kyvernon object and limits |
|---|---|---|
| Group | expression, group_type, tags | A 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 |
| Service | service_entries, service_type, tags | A named firewall service. L4PortSetServiceEntry (TCP, UDP, with destination_ports and source_ports), ICMPTypeServiceEntry (ICMPv4, ICMPv6, icmp_type, icmp_code) and IPProtocolServiceEntry (protocol_number) |
| SecurityPolicy | category, sequence_number, stateful, tcp_strict, scope, locked, comments, rules, tags | A 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 |
| Rule | sequence_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_id | A 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 |
| VirtualMachine | external_id, display_name, power_state, tags, compute_ids | A 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 |
| Statistics | packet_count, byte_count, hit_count | The 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_nameneed 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 leadingsys:gets the prefixnsx-, 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
_revisionof 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.
Search
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 id | Meaning |
|---|---|
error.nsx.unsupported | The request uses a field or an area outside the subset. The message names it |
error.nsx.invalid | A field has a value that is not valid |
error.nsx.not_found | The path names no object that the account can see |
error.nsx.revision | The _revision of the write is stale |
error.nsx.read_only | A built-in object, or a tenant user who writes into /infra |
error.nsx.xsrf | A write without a valid X-XSRF-TOKEN |
Errors of the native API keep their error.firewall.* id; see Firewall errors.
Differences and gaps
| Item | Behaviour |
|---|---|
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 expressions | Conditions on other keys or member types, and segment-port expressions, are refused with the field named |
tcp_strict, comments, group_type | Stored and returned, not acted on |
locked: true, connectivity_strategy, schedules | Refused |
Category Ethernet | Refused |
Rule profiles | Must be empty or ANY |
source_ports | Accepted in services and in the service_entries of a rule |
| Areas outside the subset | Answer 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 status | REALIZED when every connected host applied the change, ERROR while a host reports a firewall error, IN_PROGRESS otherwise |
| Session counts | The session fields of the statistics are always 0 |
| After a rename through another surface | The endpoint shows the native name, which can carry a suffix |
| PowerCLI | Scripts 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.
| Item | Operations 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_policy | Create, read, update, delete |
nsxt_policy_parent_security_policy | Create, read, delete |
nsxt_policy_security_policy_rule | Create, read, delete |
nsxt_policy_vm_tags | Create, read, delete |
Data sources nsxt_policy_service, nsxt_policy_group, nsxt_policy_vm, nsxt_policy_project | Read |
The vSphere side of Terraform is described in Terraform vSphere provider.
Related
Version 0.1. Last changed: 2026-11-14