What We’re Testing
The CLI itself does not have dedicated segmentation commands — there is no ztna groups or ztna segment command. However, segmentation group data flows to clients through the heartbeat ACL bundle. When a machine sends a heartbeat (POST /api/machine-heartbeat), the backend:
- Queries
segmentation_groupsjoined withsegmentation_group_membersfor the entire org - Builds a
machineMapwhere each machine entry includes agroupsarray of group names - Returns this as part of the
aclBundlein the heartbeat response
This means group membership is visible indirectly through:
- The heartbeat response payload (inspectable via
ztna diag) - ACL evaluation behavior (covered in Chapter 34)
- The API CRUD endpoints for
segmentation_groupsandsegmentation_group_members
This chapter verifies that group membership data is consistent between the dashboard, API, and the data the CLI receives.
Your Test Setup
| Machine | Role |
|---|---|
| ⊞ Win-A | Admin dashboard + API testing |
| ⊞ Win-B | Connected client — member of engineering group |
| 🐧 Linux-C | Connected client — member of engineering and finance groups |
Prerequisite: Groups engineering and finance exist. ⊞ Win-B is in engineering. 🐧 Linux-C is in both engineering and finance (from Chapter 32).
ST1 — Verify Group Membership via Dashboard
What it verifies: The Segmentation page accurately reflects which machines belong to which groups.
Steps:
- On ⊞ Win-A , open
https://login.quickztna.com/segmentation. - Check the
engineeringgroup card:- Badge should show the correct machine count (e.g., “3 machines” if all three test machines were added).
- The member table should list each machine name and its “Added” date.
- Check the
financegroup card:- Badge should show the correct count (e.g., “1 machines” if only 🐧 Linux-C was added).
- The member table should list 🐧 Linux-C .
Pass: Member counts and machine names match expectations from Chapter 32 setup.
ST2 — Verify Membership via API Cross-Reference
What it verifies: The CRUD API for both tables returns consistent data that can be cross-referenced.
Steps:
- On ⊞ Win-A , list all groups and their members:
TOKEN="YOUR_ADMIN_TOKEN"
ORG_ID="YOUR_ORG_ID"
# List all groups
curl -s "https://login.quickztna.com/api/db/segmentation_groups?org_id=$ORG_ID" \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool
- For each group ID returned, list its members:
GROUP_ID="ENGINEERING_GROUP_ID"
curl -s "https://login.quickztna.com/api/db/segmentation_group_members?org_id=$ORG_ID&group_id=eq.$GROUP_ID" \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool
- Cross-reference
machine_idvalues with the machines table:
MACHINE_ID="SOME_MACHINE_ID"
curl -s "https://login.quickztna.com/api/db/machines?org_id=$ORG_ID&id=eq.$MACHINE_ID&select=id,name,status,os" \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool
Expected: Each machine_id in the members table resolves to a valid machine in the org. Machine names match what the dashboard displays.
Pass: All membership rows reference valid machines. Names are consistent across API and dashboard.
ST3 — Verify Heartbeat ACL Bundle Contains Group Data
What it verifies: The heartbeat response includes group membership in the aclBundle.machines map, which is how the CLI client learns about segmentation.
Steps:
- On ⊞ Win-B , ensure the VPN is connected:
ztna status
Confirm status is “Connected” or “Running”.
- Trigger a fresh heartbeat by restarting the connection:
ztna down
ztna up
- Run diagnostics to inspect the local state:
ztna diag
- Separately, verify what the heartbeat returns by checking the ACL bundle via API. On ⊞ Win-A :
# List ACL rules to confirm at least one exists (heartbeat only includes ACL bundle when rules exist)
curl -s "https://login.quickztna.com/api/db/acl_rules?org_id=$ORG_ID&select=id,name,source,destination" \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool
If no ACL rules exist, the heartbeat skips the ACL bundle entirely (the backend only queries groups when aclRules.length > 0). Create a temporary rule if needed:
curl -s -X POST "https://login.quickztna.com/api/db/acl_rules?org_id=$ORG_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"org_id\":\"$ORG_ID\",\"name\":\"temp-test-rule\",\"source\":\"*\",\"destination\":\"*\",\"ports\":\"*\",\"protocol\":\"*\",\"action\":\"allow\"}" | python3 -m json.tool
- After the next heartbeat cycle (approximately 30 seconds), the ACL bundle sent to clients will include a
machinesmap where each entry has agroupsarray. For 🐧 Linux-C , this array should contain["engineering", "finance"].
Pass: When ACL rules exist, the heartbeat includes group membership data in the machine metadata map. Machines with no groups have an empty array.
Fail / Common issues:
- Groups array is empty even though machine is in a group — ensure ACL rules exist. The backend only builds the group-augmented machine map when there are active ACL rules.
ztna diagdoes not explicitly display group names — the group data is embedded in the ACL bundle, which the client uses internally for ACL evaluation.
ST4 — Verify Member Role Cannot Modify Groups
What it verifies: Non-admin org members can read segmentation data but cannot create groups or modify membership.
Steps:
-
Obtain a JWT token for a user with the
memberrole (not admin or owner) in the same organization. -
Attempt to read groups (should succeed):
MEMBER_TOKEN="MEMBER_JWT_TOKEN"
ORG_ID="YOUR_ORG_ID"
curl -s "https://login.quickztna.com/api/db/segmentation_groups?org_id=$ORG_ID" \
-H "Authorization: Bearer $MEMBER_TOKEN" | python3 -m json.tool
Expected: success: true with the list of groups.
- Attempt to create a group (should fail):
curl -s -X POST "https://login.quickztna.com/api/db/segmentation_groups?org_id=$ORG_ID" \
-H "Authorization: Bearer $MEMBER_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"org_id\":\"$ORG_ID\",\"name\":\"unauthorized-group\"}" | python3 -m json.tool
Expected:
{
"success": false,
"error": {
"code": "FORBIDDEN",
"message": "Admin required for writes to this table"
}
}
- Attempt to add a member (should also fail):
curl -s -X POST "https://login.quickztna.com/api/db/segmentation_group_members?org_id=$ORG_ID" \
-H "Authorization: Bearer $MEMBER_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"group_id\":\"SOME_GROUP_ID\",\"machine_id\":\"SOME_MACHINE_ID\"}" | python3 -m json.tool
Expected: 403 Forbidden response.
Pass: Members can read but not write. Both segmentation_groups and segmentation_group_members are protected by the ADMIN_WRITE_TABLES gate.
ST5 — Edit Group Name and Description via Dashboard
What it verifies: The edit dialog updates the group name and description via a PATCH to segmentation_groups.
Steps:
- On ⊞ Win-A , on the Segmentation page, find the
marketinggroup card (created in Chapter 31). - Click the pencil (edit) icon.
- In the edit dialog:
- Change Group Name to
marketing-team - Change Description to
Global marketing department
- Change Group Name to
- Click Save Changes.
Expected: Toast “Group updated” appears. The card refreshes with the new name marketing-team and updated description.
- Verify via API:
curl -s "https://login.quickztna.com/api/db/segmentation_groups?org_id=$ORG_ID&name=eq.marketing-team" \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool
Expected: Returns one group with name: "marketing-team" and description: "Global marketing department".
- Verify that the old name
marketingno longer exists:
curl -s "https://login.quickztna.com/api/db/segmentation_groups?org_id=$ORG_ID&name=eq.marketing" \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool
Expected: Empty array "data": [].
Pass: Name and description updated. Old name no longer resolves. Any ACL rules using group:marketing would need to be manually updated to group:marketing-team.
Fail / Common issues:
- Rename to an existing group name fails with a unique constraint error — this is correct behavior; group names must be unique per org.
Summary
| Sub-test | What it proves | Pass condition |
|---|---|---|
| ST1 | Dashboard membership display | Correct machine counts and names per group |
| ST2 | API cross-reference | Membership rows resolve to valid machines, consistent with dashboard |
| ST3 | Heartbeat ACL bundle | Group data included in heartbeat when ACL rules exist |
| ST4 | Member role restrictions | Members can read but not write to segmentation tables |
| ST5 | Group name/description edit | Edit dialog updates name and description, old name removed |