Certificate Operations
Overview
Manage ISE certificates including system certs, trusted CAs, and Let’s Encrypt integration.
Commands
netapi ise cert [COMMAND]
| Command | Description |
|---|---|
|
List system certificates on ISE node |
|
List trusted CA certificates |
|
Import system certificate from local files (Vault PKI, etc.) |
|
Import trusted CA certificate |
|
Add Let’s Encrypt CA chain to ISE |
|
Prepare LE certs for manual import |
|
Import from certmgr-01 (Let’s Encrypt) |
|
Run mTLS preflight checks |
List System Certificates
netapi ise cert list [OPTIONS]
| Option | Default | Description |
|---|---|---|
|
(off) |
Show detailed info (expiry, issuer, key size, self-signed) |
|
(none) |
Filter by usage (Admin, EAP, Portal, pxGrid, SAML) |
|
|
ISE node hostname |
# Basic list
netapi ise cert list
# Detailed view with expiration dates
netapi ise cert list --detail
# Filter by usage
netapi ise cert list --usage Portal
netapi ise cert list --usage EAP
netapi ise cert list --usage pxGrid
# Different node (multi-node deployment)
netapi ise cert list --hostname ise-psn-01
Shows certificates installed on the ISE node for:
-
Admin portal
-
EAP authentication
-
pxGrid
-
Portal (Guest/Sponsor)
-
SAML
-
RADIUS DTLS
-
ISE Messaging Service
List Trusted CAs
netapi ise cert list-trusted [OPTIONS]
| Option | Default | Description |
|---|---|---|
|
(off) |
Fetch ALL trusted certs (auto-paginate) |
|
(none) |
Filter by name (case-insensitive) |
|
|
Results per page (max 100) |
|
|
Page number |
# List all trusted certs (auto-paginate)
netapi ise cert list-trusted --all
# Search for Let's Encrypt certs
netapi ise cert list-trusted --all --search LetsEncrypt
# Search for AD CS certs
netapi ise cert list-trusted --all --search HOME-ROOT
# First page with 50 results
netapi ise cert list-trusted --size 50 --page 1
|
Naming convention: Prefix trusted CA names with the issuer (e.g., |
Add Let’s Encrypt CA
# Add LE root and intermediate CAs to ISE trust store
netapi ise cert add-letsencrypt-ca
Required for trusting Let’s Encrypt certificates used by:
-
External RADIUS clients
-
API clients with LE certs
-
pxGrid subscribers
Prepare Let’s Encrypt Certs
# Prepare LE certs for manual ISE import
netapi ise cert prepare-for-import
Creates certificate bundle in format ISE expects.
Import from Certmgr
# Import certificate from certmgr-01 server
netapi ise cert import-from-certmgr --help
Quick Import (Recommended)
# Load credentials
dsource d000 dev/network
# Import Let's Encrypt portal cert from certmgr-01
netapi ise cert import-from-certmgr --cert-dir public-portals --portal
Options
| Option | Default | Description |
|---|---|---|
|
|
certmgr host |
|
|
SSH user for certmgr |
|
|
Certificate domain name |
|
(domain) |
Certbot directory name |
|
|
Certificate friendly name in ISE |
|
|
Use for Portal |
|
|
Use for Admin |
|
|
Use for EAP |
Import System Certificate (Local Files)
Import a system certificate and private key directly from local files. This is the preferred method for Vault-issued certificates and other internal CA certificates.
|
ISE OpenAPI Requirement: The private key must be in PEM format. The API automatically handles base64 encoding. The field name |
netapi ise cert import CERT_FILE KEY_FILE [OPTIONS]
Options
| Option | Default | Description |
|---|---|---|
|
(from filename) |
Certificate friendly name in ISE |
|
|
ISE node hostname (for display only) |
|
|
Use for Admin interface |
|
|
Use for EAP authentication |
|
|
Use for Portal |
|
|
Use for pxGrid |
|
|
Use for RADIUS DTLS |
|
|
Use for SAML |
|
(empty) |
Private key password (if encrypted) |
|
|
Allow replacing existing cert with same usage |
Import Vault-Issued EAP/Admin Certificate
For internal certificates issued by HashiCorp Vault PKI:
# Issue certificate from Vault
ssh certmgr-01 "vault write pki_int/issue/domus-server \
common_name=ise-02.inside.domusdigitalis.dev \
alt_names=ise-02.inside.domusdigitalis.dev \
ip_sans=10.50.1.21 \
ttl=8760h" > /tmp/ise-cert.json
# Extract cert and key
jq -r '.data.certificate' /tmp/ise-cert.json > /tmp/ise-eap.crt
jq -r '.data.private_key' /tmp/ise-cert.json > /tmp/ise-eap.key
# Import to ISE for Admin and EAP authentication
dsource d000 dev/network
netapi ise cert import /tmp/ise-eap.crt /tmp/ise-eap.key \
--name ISE-VAULT-EAP --admin --eap
Import pxGrid Certificate
# Issue pxGrid certificate from Vault
vault write pki_int/issue/domus-pxgrid \
common_name=netapi-pxgrid.inside.domusdigitalis.dev \
ttl=8760h > /tmp/pxgrid.json
jq -r '.data.certificate' /tmp/pxgrid.json > /tmp/pxgrid.crt
jq -r '.data.private_key' /tmp/pxgrid.json > /tmp/pxgrid.key
netapi ise cert import /tmp/pxgrid.crt /tmp/pxgrid.key \
--name ISE-PXGRID-VAULT --pxgrid
Ansible Automation (certmgr-01)
Alternative to netapi for CI/CD pipelines or when running from certmgr-01 directly.
Prerequisites
# On certmgr-01
export ISE_API_USER="domus_ers_admin"
export ISE_API_PASS="<password>"
Run Playbook
cd ~/ansible
ansible-playbook playbooks/deploy-ise.yml \
-i inventory/hosts.yml \
-e "cert_domain=public-portals" \
--limit ise-02
Playbook Details
Location: certmgr-01:~/ansible/playbooks/deploy-ise.yml
|
The playbook uses the |
Inventory
# ~/ansible/inventory/hosts.yml
ise_nodes:
hosts:
ise-02:
ansible_host: 10.50.1.21
cert_domain: guest.domusdigitalis.dev
vars:
ansible_connection: local
Certbot Auto-Renewal Hook
The certbot deploy hook at /etc/letsencrypt/renewal-hooks/deploy/deploy-certs.sh can trigger automatic deployment on renewal. Currently uses curl directly (not Ansible).
# Manual trigger
sudo /etc/letsencrypt/renewal-hooks/deploy/deploy-certs.sh
# Force renewal + deploy
sudo certbot renew --force-renewal --cert-name public-portals
mTLS Preflight Check
# Verify mTLS configuration before enabling
netapi ise cert mtls-preflight
Checks:
-
Client certificate validity
-
CA chain completeness
-
ISE trust store configuration
-
API endpoint accessibility
Use Cases
Audit Certificate Expiry
# List system certificates (table view)
netapi ise cert list
# List trusted CAs
netapi ise cert list-trusted
Check Expiration Dates (JSON + jq)
# Get expiration dates for all certs
netapi ise cert --format json list | jq '.[] | {name: .friendlyName, expires: .expirationDate, usedBy: .usedBy}'
# Find certs expiring within 30 days
netapi ise cert --format json list | jq '.[] | select(.expirationDate | contains("2026")) | {name: .friendlyName, expires: .expirationDate}'
# Check specific role (Portal, Admin, EAP, pxGrid)
netapi ise cert --format json list | jq '.[] | select(.usedBy | contains("Portal"))'
Quick Portal Cert Check
# Is the portal cert valid?
netapi ise cert --format json list | jq '.[] | select(.usedBy | contains("Portal")) | {name: .friendlyName, expires: .expirationDate}'
Verify Let’s Encrypt Chain
# Check if LE CA chain is complete in ISE trust store
netapi ise cert list-trusted --all --search LetsEncrypt
# Expected output (4 certs):
# - Letsencrypt-ISRG-Root-X1 (Root)
# - Letsencrypt-ISRG-Root-X2 (Root)
# - LetsEncrypt-E7 (Intermediate)
# - Letsencrypt-E8 (Intermediate)
# JSON output for scripting
netapi ise cert --format json list-trusted --all --search LetsEncrypt | jq '.[].friendlyName'
Let’s Encrypt Setup
#!/bin/bash
# Full LE setup
echo "Adding Let's Encrypt CA chain..."
netapi ise cert add-letsencrypt-ca
echo "Preparing certificates for import..."
netapi ise cert prepare-for-import
echo "Done. Import certs via ISE GUI:"
echo " Administration > System > Certificates > System Certificates"
Count Trusted Certificates
# Total count of trusted CAs
netapi ise cert --format json list-trusted --all | jq 'length'
Find ISE Internal CA Certs
# ISE's internal Certificate Services CA chain
netapi ise cert list-trusted --all --search "Certificate Services"
# Just the root CAs
netapi ise cert --format json list-trusted --all | jq '.[] | select(.friendlyName | contains("Root CA"))'
Find Certs by Issuer
# All certs issued by DigiCert
netapi ise cert --format json list-trusted --all | jq '.[] | select(.issuedBy | contains("DigiCert"))'
# All certs issued by Cisco
netapi ise cert list-trusted --all --search Cisco
Find Self-Signed Certs
# Self-signed = subject matches issuer
netapi ise cert --format json list-trusted --all | jq '.[] | select(.friendlyName | test("self-signed"; "i"))'
System Cert Usage Report
# What's each system cert used for?
netapi ise cert --format json list | jq '.[] | {name: .friendlyName, usage: .usedBy, expires: .expirationDate}'
# Find the EAP cert
netapi ise cert --format json list | jq '.[] | select(.usedBy | contains("EAP"))'
# Find the Admin cert
netapi ise cert --format json list | jq '.[] | select(.usedBy | contains("Admin"))'
# Find the pxGrid cert
netapi ise cert --format json list | jq '.[] | select(.usedBy | contains("pxGrid"))'
Export Cert Inventory (CSV-ready)
# System certs as CSV
netapi ise cert --format json list | jq -r '.[] | [.friendlyName, .usedBy, .expirationDate] | @csv'
# Trusted CAs as CSV
netapi ise cert --format json list-trusted --all | jq -r '.[] | [.friendlyName, .issuedBy] | @csv'
# Full inventory to file
netapi ise cert --format json list > /tmp/system-certs.json
netapi ise cert --format json list-trusted --all > /tmp/trusted-certs.json
Expiration Monitoring
# All system cert expiration dates (sorted)
netapi ise cert --format json list | jq -r '.[] | "\(.expirationDate) - \(.friendlyName)"' | sort
# Find certs expiring in 2026
netapi ise cert --format json list | jq '.[] | select(.expirationDate | contains("2026"))'
# Portal cert expiry specifically
netapi ise cert --format json list | jq '.[] | select(.usedBy | contains("Portal")) | {name: .friendlyName, expires: .expirationDate}'
Quick Health Check
#!/bin/bash
# cert-health.sh - Quick ISE certificate health check
echo "=== System Certificates ==="
netapi ise cert list
echo -e "\n=== Trusted CA Count ==="
netapi ise cert --format json list-trusted --all | jq 'length'
echo -e "\n=== Let's Encrypt Chain ==="
netapi ise cert list-trusted --all --search LetsEncrypt
echo -e "\n=== Expiration Dates ==="
netapi ise cert --format json list | jq -r '.[] | "\(.expirationDate) - \(.friendlyName)"' | sort
Enterprise Use Cases
Certs Expiring Within 90 Days
#!/bin/bash
# Find certs expiring within N days
DAYS=90
CUTOFF=$(date -d "+${DAYS} days" +%s)
netapi ise cert --format json list | jq -r --argjson cutoff "$CUTOFF" '
.[] |
select(.expirationDate) |
{name: .friendlyName, expires: .expirationDate, usage: .usedBy}
' | while read -r line; do
echo "$line"
done
# Quick check - certs expiring in 2026
netapi ise cert --format json list | jq '.[] | select(.expirationDate | contains("2026")) | {name: .friendlyName, expires: .expirationDate, usage: .usedBy}'
Find Enterprise CA Certs (AD CS)
# Find your enterprise/AD CS root CAs
netapi ise cert list-trusted --all --search "ROOT-CA"
netapi ise cert list-trusted --all --search "Enterprise"
netapi ise cert list-trusted --all --search "AD-CS"
# Find by domain name
netapi ise cert --format json list-trusted --all | jq '.[] | select(.friendlyName | test("corp|enterprise|internal"; "i"))'
pxGrid Readiness Check
# Is pxGrid cert configured?
netapi ise cert --format json list | jq '.[] | select(.usedBy | contains("pxGrid")) | {name: .friendlyName, expires: .expirationDate}'
# Which CAs are trusted for pxGrid?
netapi ise cert --format json list-trusted --all | jq '[.[] | select(.trustForIseAuth == true)] | length'
# (Note: requires full cert details - check ISE GUI for trust settings)
EAP-TLS Readiness Check
# EAP cert configured?
netapi ise cert --format json list | jq '.[] | select(.usedBy | contains("EAP")) | {name: .friendlyName, expires: .expirationDate, issuer: .issuedBy}'
# Count CAs trusted for endpoint auth
netapi ise cert --format json list-trusted --all | jq 'length'
Compliance Audit Report
#!/bin/bash
# compliance-audit.sh - Certificate compliance report
DATE=$(date +%Y-%m-%d)
REPORT="/tmp/ise-cert-audit-${DATE}.txt"
{
echo "ISE Certificate Compliance Audit - $DATE"
echo "=========================================="
echo -e "\n## System Certificates"
netapi ise cert --format json list | jq -r '.[] | "- \(.friendlyName): \(.usedBy) (expires: \(.expirationDate))"'
echo -e "\n## Trusted CA Count: $(netapi ise cert --format json list-trusted --all | jq 'length')"
echo -e "\n## Certificate Usage Summary"
echo "- Admin: $(netapi ise cert --format json list | jq '[.[] | select(.usedBy | contains("Admin"))] | length')"
echo "- EAP: $(netapi ise cert --format json list | jq '[.[] | select(.usedBy | contains("EAP"))] | length')"
echo "- Portal: $(netapi ise cert --format json list | jq '[.[] | select(.usedBy | contains("Portal"))] | length')"
echo "- pxGrid: $(netapi ise cert --format json list | jq '[.[] | select(.usedBy | contains("pxGrid"))] | length')"
echo "- SAML: $(netapi ise cert --format json list | jq '[.[] | select(.usedBy | contains("SAML"))] | length')"
echo -e "\n## Expiration Timeline"
netapi ise cert --format json list | jq -r '.[] | "\(.expirationDate) - \(.friendlyName)"' | sort
} > "$REPORT"
echo "Report saved to: $REPORT"
cat "$REPORT"
Before/After Change Comparison
# Before making cert changes - save baseline
netapi ise cert --format json list > /tmp/certs-before.json
netapi ise cert --format json list-trusted --all > /tmp/trusted-before.json
# After changes - compare
netapi ise cert --format json list > /tmp/certs-after.json
diff <(jq -S . /tmp/certs-before.json) <(jq -S . /tmp/certs-after.json)
# Quick count comparison
echo "Before: $(jq 'length' /tmp/trusted-before.json) trusted CAs"
echo "After: $(jq 'length' /tmp/trusted-after.json) trusted CAs"
Find Duplicate/Similar Certs
# Find certs with similar names (potential duplicates)
netapi ise cert --format json list-trusted --all | jq -r '.[].friendlyName' | sort | uniq -d
# Group by issuer
netapi ise cert --format json list-trusted --all | jq 'group_by(.issuedBy) | .[] | {issuer: .[0].issuedBy, count: length}'
Cert Documentation for DR/Runbook
#!/bin/bash
# Generate cert documentation for disaster recovery runbook
echo "# ISE Certificate Documentation"
echo "Generated: $(date)"
echo ""
echo "## System Certificates"
echo '```'
netapi ise cert list
echo '```'
echo ""
echo "## System Cert Details (JSON)"
echo '```json'
netapi ise cert --format json list | jq '.'
echo '```'
echo ""
echo "## Trusted CA Summary"
echo "Total CAs: $(netapi ise cert --format json list-trusted --all | jq 'length')"
echo ""
echo "### By Category:"
echo "- Let's Encrypt: $(netapi ise cert --format json list-trusted --all | jq '[.[] | select(.friendlyName | test("LetsEncrypt|ISRG"; "i"))] | length')"
echo "- Cisco: $(netapi ise cert --format json list-trusted --all | jq '[.[] | select(.friendlyName | test("Cisco"; "i"))] | length')"
echo "- DigiCert: $(netapi ise cert --format json list-trusted --all | jq '[.[] | select(.friendlyName | test("DigiCert"; "i"))] | length')"
echo "- ISE Internal: $(netapi ise cert --format json list-trusted --all | jq '[.[] | select(.friendlyName | test("Certificate Services"; "i"))] | length')"
Verify Cert Chain Completeness
# Check if your enterprise CA chain is complete
# Example: Verify HOME-ROOT-CA chain
netapi ise cert list-trusted --all --search "HOME"
# Check portal cert issuer is trusted
PORTAL_ISSUER=$(netapi ise cert --format json list | jq -r '.[] | select(.usedBy | contains("Portal")) | .issuedBy')
echo "Portal cert issued by: $PORTAL_ISSUER"
netapi ise cert --format json list-trusted --all | jq --arg issuer "$PORTAL_ISSUER" '.[] | select(.friendlyName | contains($issuer))'
Weekly Cert Check (Cron-ready)
#!/bin/bash
# weekly-cert-check.sh - Run via cron for proactive monitoring
# 0 8 * * 1 /path/to/weekly-cert-check.sh | mail -s "ISE Cert Report" admin@company.com
# Load credentials
source ~/.config/netapi/d000-dev-network.env # or use dsource
echo "ISE Certificate Weekly Report - $(date)"
echo "========================================"
# Check for certs expiring within 60 days
echo -e "\nā ļø CERTS EXPIRING WITHIN 60 DAYS:"
SIXTY_DAYS=$(date -d "+60 days" "+%Y")
netapi ise cert --format json list | jq -r --arg year "$SIXTY_DAYS" '
.[] | select(.expirationDate | contains($year)) |
" - \(.friendlyName): \(.expirationDate)"'
# Summary
echo -e "\nš SUMMARY:"
echo " System certs: $(netapi ise cert --format json list | jq 'length')"
echo " Trusted CAs: $(netapi ise cert --format json list-trusted --all | jq 'length')"
# Next expiration
echo -e "\nš
NEXT EXPIRATION:"
netapi ise cert --format json list | jq -r '.[] | "\(.expirationDate) - \(.friendlyName)"' | sort | head -1
Multi-Environment Comparison
#!/bin/bash
# Compare certs across environments (dev/test/prod)
for ENV in dev test prod; do
echo "=== $ENV ==="
dsource d000 $ENV/network 2>/dev/null
echo "System certs: $(netapi ise cert --format json list 2>/dev/null | jq 'length')"
echo "Trusted CAs: $(netapi ise cert --format json list-trusted --all 2>/dev/null | jq 'length')"
echo ""
done
Related Commands
-
cert-profiles - Certificate auth profiles
-
saml - SAML IdP configuration