Security Group Tags API
Overview
Security Group Tags (SGTs) enable software-defined segmentation. Endpoints receive SGTs during authorization, and SGACLs enforce policy between groups.
SGT URL |
|
SGACL URL |
|
Mapping URL |
|
Matrix URL |
|
Setup
dsource d000 dev/network
ISE_HOST="${ISE_PAN_IP}"
ISE_AUTH="${ISE_API_USER}:${ISE_API_PASS}"
BASE_URL="https://${ISE_HOST}:9060/ers/config"
Security Group Tags
List All SGTs
netapi
netapi ise get-sgts
curl
# List all SGTs
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgt" \
-H "Accept: application/json" | jq '.SearchResult.resources[] | {name, id}'
List with Tag Values
# List SGTs with their tag values
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgt" \
-H "Accept: application/json" | jq -r '.SearchResult.resources[].id' | \
while read ID; do
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgt/${ID}" \
-H "Accept: application/json" | jq -r '.Sgt | "\(.value)\t\(.name)\t\(.description // "-")"'
done | sort -n | column -t -s$'\t'
Get SGT by Name
netapi
netapi ise get-sgt "Employees"
curl
# Get SGT by name
SGT_NAME="Employees"
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgt/name/${SGT_NAME}" \
-H "Accept: application/json" | jq '.Sgt'
Get SGT by Value
# Get SGT by tag value
SGT_VALUE="4"
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgt" \
-H "Accept: application/json" | jq -r '.SearchResult.resources[].id' | \
while read ID; do
SGT=$(curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgt/${ID}" \
-H "Accept: application/json")
VALUE=$(echo "$SGT" | jq -r '.Sgt.value')
if [ "$VALUE" = "$SGT_VALUE" ]; then
echo "$SGT" | jq '.Sgt'
break
fi
done
Create SGT
netapi
netapi ise create-sgt "Linux_Workstations" \
--value 10 \
--description "Linux workstations with EAP-TLS authentication"
curl
# Create new SGT
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgt" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-X POST \
-d '{
"Sgt": {
"name": "Linux_Workstations",
"description": "Linux workstations with EAP-TLS authentication",
"value": 10,
"propogateToApic": true
}
}'
Create with Reserved Range
# Create SGT with value in custom range
# ISE reserves 0-15 for system use, use 16+ for custom
# Define SGT scheme
# 16-99: Infrastructure (servers, network devices)
# 100-199: Users (employees, contractors, guests)
# 200-254: IoT and special devices
# 255: Quarantine
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgt" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-X POST \
-d '{
"Sgt": {
"name": "Domain_Controllers",
"description": "Active Directory domain controllers",
"value": 16,
"propogateToApic": true
}
}'
Update SGT
netapi
netapi ise update-sgt "Linux_Workstations" \
--description "Updated: Linux workstations - production EAP-TLS"
curl
# Update SGT description
SGT_NAME="Linux_Workstations"
# Get current SGT
SGT=$(curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgt/name/${SGT_NAME}" \
-H "Accept: application/json")
SGT_ID=$(echo "$SGT" | jq -r '.Sgt.id')
SGT_VALUE=$(echo "$SGT" | jq -r '.Sgt.value')
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgt/${SGT_ID}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-X PUT \
-d '{
"Sgt": {
"id": "'"${SGT_ID}"'",
"name": "'"${SGT_NAME}"'",
"description": "Updated: Linux workstations - production EAP-TLS",
"value": '"${SGT_VALUE}"',
"propogateToApic": true
}
}'
Security Group ACLs
List SGACLs
# List Security Group ACLs
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgacl" \
-H "Accept: application/json" | jq '.SearchResult.resources[] | {name, id}'
Get SGACL
# Get SGACL content
SGACL_NAME="Permit_IP"
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgacl/name/${SGACL_NAME}" \
-H "Accept: application/json" | jq '.Sgacl'
Create SGACL
# Create SGACL
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgacl" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-X POST \
-d '{
"Sgacl": {
"name": "Linux_to_Servers",
"description": "Allow Linux to access servers",
"aclcontent": "permit tcp dst eq 22\npermit tcp dst eq 443\npermit tcp dst eq 3389\ndeny ip"
}
}'
IP-SGT Mappings
List Mappings
# List IP-to-SGT static mappings
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgmapping" \
-H "Accept: application/json" | jq '.SearchResult.resources[] | {name, id}'
Create Mapping
# Create static IP-to-SGT mapping
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgmapping" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-X POST \
-d '{
"SGMapping": {
"name": "Server_Subnet",
"sgt": "Servers",
"deployType": "ALL",
"hostIp": "10.50.20.0",
"hostName": "server-subnet"
}
}'
Egress Matrix
# Get egress matrix cells (source -> destination policies)
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/egressmatrixcell" \
-H "Accept: application/json" | jq '.SearchResult.resources[] | {id}'
# Get specific cell
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/egressmatrixcell?filter=sourceSgtId.EQ.4&filter=destinationSgtId.EQ.6" \
-H "Accept: application/json" | jq '.SearchResult.resources[0]'
Common Patterns
SGT Assignment in AuthZ Profile
# Create authz profile that assigns SGT
SGT_VALUE="10" # Linux_Workstations
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/authorizationprofile" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-X POST \
-d '{
"AuthorizationProfile": {
"name": "Linux-EAP-TLS-TrustSec",
"description": "EAP-TLS with SGT assignment",
"accessType": "ACCESS_ACCEPT",
"authzProfileType": "SWITCH",
"vlan": {"nameID": "DATA", "tagID": 10},
"advancedAttributes": [
{
"leftHandSideDictionaryAttribue": {
"AdvancedAttributeValueType": "AdvancedDictionaryAttribute",
"dictionaryName": "Cisco",
"attributeName": "cisco-av-pair"
},
"rightHandSideAttribueValue": {
"AdvancedAttributeValueType": "AttributeValue",
"value": "cts:security-group-tag='"${SGT_VALUE}"'-00"
}
}
]
}
}'
Export TrustSec Config
# Export full TrustSec configuration
mkdir -p trustsec-backup
echo "Exporting SGTs..."
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgt" \
-H "Accept: application/json" | jq -r '.SearchResult.resources[].id' | \
while read ID; do
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgt/${ID}" \
-H "Accept: application/json"
done | jq -s '.' > trustsec-backup/sgts.json
echo "Exporting SGACLs..."
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgacl" \
-H "Accept: application/json" | jq -r '.SearchResult.resources[].id' | \
while read ID; do
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgacl/${ID}" \
-H "Accept: application/json"
done | jq -s '.' > trustsec-backup/sgacls.json
echo "Exporting IP-SGT Mappings..."
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgmapping" \
-H "Accept: application/json" | jq -r '.SearchResult.resources[].id' | \
while read ID; do
curl -sk -u "${ISE_AUTH}" \
"${BASE_URL}/sgmapping/${ID}" \
-H "Accept: application/json"
done | jq -s '.' > trustsec-backup/mappings.json
echo "TrustSec configuration exported to trustsec-backup/"
SGT Usage Report
# Generate SGT usage report from active sessions
echo "SGT Usage Report"
echo "================"
# Get SGT assignments from active sessions (via MnT)
curl -sk -u "${ISE_AUTH}" \
"https://${ISE_HOST}/admin/API/mnt/Session/ActiveList" \
-H "Accept: application/xml" | \
grep -oP '(?<=<security_group>)[^<]+' | sort | uniq -c | sort -rn