Getting Started with the Elisity CLI

Relevant Articles

This guide covers the Elisity CLI: installing it, pointing it at a Cloud Control Center instance, working through what it can do, and two use cases.

You need a Client ID and Client Secret from a CCC API Client first: see How to Access Elisity APIs.

Introduction

The Elisity CLI is a command-line interface to Cloud Control Center (CCC). It brings the data you read in the CCC user interface into the tools your team already uses: a terminal session, a scheduled job, a reporting pipeline. Anything you reach through the CCC API you reach through the CLI, with authentication, pagination, retries, and output formatting handled for you.

The CLI does not replace the interface. Use the interface to inspect and decide, and the CLI to carry the same fields into a report, a ticket, or a script.

The CLI tracks the CCC API and changes between CCC releases. The repository at github.com/Elisity/elisity-cli is the source of record for installation and the current version.

The guide covers the installation, then the CLI's capabilities — command groups, output formats, filtering — and then two use cases that show teams putting it to work.

Prerequisites

  • Access to the repository at github.com/Elisity/elisity-cli. It is the source of record: install from it, and check it for the current version and command reference.
  • Python 3.10 or later, as declared by the package.
  • Network reach over HTTPS to the CCC instance.
  • An API Client (Client ID and Client Secret) created under Settings > Admin > User Management > API Clients > Add API Client, per How to Access Elisity APIs.

An API Client expires according to the Access Duration set when it was created, unless Set Unlimited Access was selected. When the credentials expire, regenerate them in CCC and update the profile.

The role assigned to the API Client determines which endpoints it reaches; a too-narrow role returns a permission error.

1. Getting Started with the Installation

Step 1. Install the CLI

The CLI is not published on PyPI. Install it from a clone of the repository:

git clone git@github.com:Elisity/elisity-cli.git
cd elisity-cli

python3 -m venv .venv
source .venv/bin/activate
pip install -e .

The virtual environment is required: current Ubuntu and Debian releases block system-wide pip install under PEP 668. Confirm the install:

elisity --version

Compare the printed version against the repository. Re-activate the virtual environment in each new session.

Step 2. Configure a profile

A profile holds the base URL and credentials for one CCC instance:

elisity config set-profile prod \
  --base-url https://your-ccc.idp01.elisity.io \
  --client-id YOUR_CLIENT_ID \
  --client-secret 'YOUR_CLIENT_SECRET'

This writes ~/.elisity/config.yaml, and the first profile created becomes the active profile.

Important: ~/.elisity/config.yaml holds the client secret in plain text. Restrict it with chmod 600 ~/.elisity/config.yaml.

Repeat the command for each additional instance, then switch between profiles:

elisity config use-profile staging   # switch the active profile
elisity config list-profiles         # list profiles, active one marked
elisity config show                  # resolved configuration, secrets redacted

elisity config show redacts any key containing secret, so its output is safe to paste into a ticket.

Environment variables for pipelines and containers

On a build runner or in a container, export the settings instead:

export CCC_BASE_URL=https://your-ccc.idp01.elisity.io
export CCC_CLIENT_ID=YOUR_CLIENT_ID
export CCC_CLIENT_SECRET=YOUR_CLIENT_SECRET

CCC_TIMEOUT overrides the request timeout the same way.

Each field resolves independently: environment variable, then the profile named by -p, then the active profile. An exported CCC_BASE_URL therefore redirects the request while the profile supplies the credentials.

Step 3. Verify authentication

The CLI authenticates with the OAuth2 client_credentials grant against {base_url}/auth/realms/elisity/protocol/openid-connect/token, scope openid. Tokens are cached in memory and never written to disk.

elisity auth test

A working profile returns a healthy status:

{
  "status": "healthy",
  "code": 200,
  "authenticated": true
}

Any other result means you are not connected. Two commands narrow it down:

elisity auth token    # print the raw bearer token, for curl or another tool
elisity auth whoami   # decode the current JWT and show its claims

When it fails, re-run with --debug to see the request and response:

elisity --debug auth test

2. Using the CLI

Everything here is read-only and safe against a live tenant.

What the command groups cover

Commands are grouped by the part of CCC they address:

Group What it covers
policy Policy sets, policies, policy groups, service groups
topology Sites, zones, Virtual Edge and Virtual Edge Node objects
devices Device identity and enrichment
ad Active Directory and Microsoft Entra ID
connectors IdentityGraph connectors and configurations
insights Policy insights and suggestions
system Tasks, specifications, state sync
reporting Zero Trust metrics, site KPIs, traffic
flows Device state, flow search, noise
config CLI profiles, credentials, defaults
auth Authentication checks and tokens
glossary Product vocabulary lookup

Ask the CLI for the commands inside a group: elisity --help lists the groups, elisity topology --help that group's commands, elisity topology get-site-v2 --help one command. The CLI help and the repository are the current list; a printed one goes stale.

Running a command

Before routing a site issue, you want device and enforcement-node counts per site. One command returns what the per-site cards in CCC show:

elisity -f table reporting get-site-kpis

The response is one row per site:

siteName   onlineDevices  virtualEdgeNodes  activatedPolicies  policyEnforcementScore
Boston     143            1                 81                 100.0
CORK       1071           6                 245                84.9

Supporting commands fill in the rest:

elisity topology get-all-sites                     # the sites themselves
elisity topology get-site-v2 <SITE_ID>             # one site by ID
elisity devices get-device-header-data             # tenant-wide device totals
elisity reporting get-aggregate-enforcement-score  # tenant-wide enforcement score

On the sites endpoint the interface's site name is the label field, not name; filtering on name returns nothing and no error.

To carry recent policy-set modifications into a change-review workflow:

elisity policy get-all-as-nd-json

The endpoint streams newline-delimited JSON, which the CLI parses into an array. A typical record:

{
  "id": "29eef758-a1e3-49c0-a531-779ef835c325",
  "modifiedBy": "service-account@your-org.example",
  "modifiedAt": "2026-05-14T17:49:05.514081Z",
  "status": "Active"
}

Other read commands worth knowing:

elisity connectors read-all-connectors     # IdentityGraph connectors
elisity reporting get-zero-trust-metrics   # Zero Trust metrics per policy group

Output formats

Four output formats, selected with -f:

Format Use it for
json (default) Piping to jq or storing as a file
table Reading at the terminal; paginated responses are unwrapped
yaml Reading a deep record; key order is preserved
csv Spreadsheets and inventory feeds

Filtering and reshaping with JMESPath

-q takes a JMESPath expression, applied before rendering, so it works with every output format — selecting records and projecting fields:

elisity -q '[].label' topology get-all-sites     # site names
elisity -q 'length(@)' topology get-all-sites    # how many sites

# Active policy sets only, as a table of chosen fields
elisity -f table -q "[?status=='Active'].{name: name, coverage: deviceCoverage}" \
  policy get-all-as-nd-json

# Fields out of a paginated response
elisity -q 'content[].{id: id, name: deviceName}' \
  devices get-devices-view --body '{"pageable":{"page":0,"size":50}}'

Global flags go before the command

Important: -f, -q, -p, and --debug are options on elisity itself, and are not recognized after the command name.

elisity -f table -q '[].label' topology get-all-sites   # correct
elisity topology get-all-sites -f table                 # wrong, flag not applied

Destructive commands and --confirm

Destructive commands require --confirm:

elisity <group> <destructive-command> <ID>

Without the flag the CLI refuses, exits 1 without making an HTTP call, and prints:

Use --confirm to execute this destructive operation.

Destructive is decided by the API path, not the HTTP verb: every DELETE, plus the POST bulk deletes, the PUT decommission operations, and the Insights reset and recreate operations. Do not assume a POST is safe. Dry-run siblings are not gated.

Important: --confirm guards against accident; it does not make a bulk delete reversible. In a script, check that the target exists first and handle the non-zero exit.

3. Comparing CLI Output to the Cloud Control Center UI

The CLI and the interface read the same data from two surfaces. Two differences catch people out: timestamp rendering, and naming.

Timestamps: the CLI reports UTC, the interface renders local time

The same record can look like two different events. A policy set modified at 6:13 a.m. Eastern shows in the interface as August 5, 6:13 a.m. and in the CLI as:

"modifiedAt": "2026-08-05T10:13:42.118904Z"

The trailing Z means UTC; the four hours are the Eastern Daylight Time offset.

  • Convert a CLI timestamp, or label it UTC, before handing it to someone reading the interface. An unlabeled timestamp is read as local time.
  • Filter by time in UTC in a script, and expect the local offset to shift twice a year where daylight saving applies.

Vocabulary: mapping an interface term to a command

Elisity vocabulary does not always match the generic industry term: "monitor mode" is Simulation, "Zero Trust score" is the Policy Enforcement Score, "security group" is a Policy Group. A command guessed from the industry term is usually wrong.

The glossary group removes the guess. It makes no API call and needs no authentication:

elisity glossary list                          # every term, with its domain
elisity glossary search "monitor mode"         # look up a synonym
elisity glossary explain "Zero Trust score"    # explanation plus ready-to-paste commands

Look the vocabulary up first, then run the command the glossary names. That is also what lets a workflow turn a plain-language request into a command — the basis of Use Case 2.

Use Case 1 — Integrating the CLI into an Existing Automation Framework

Once an operator can retrieve a field by hand, the next question is where that field should go. The answer is rarely "a terminal window." It is a record in the system the next person already works in.

Three destinations for Elisity CLI output: an inventory workflow mapping device records into the ServiceNow configuration database, a help-desk workflow attaching observations to a ServiceNow review task, and a security workflow bringing context into a Microsoft Sentinel investigation through Azure Logic Apps

There are several useful destinations for Elisity information, and three of them account for most of what teams build first:

  • Inventory. An inventory workflow maps device records into ServiceNow's configuration database, so the asset record and the network view describe the same device.
  • The service desk. A help-desk workflow attaches policy or reporting observations to a review task in ServiceNow. Tier 1 or Tier 2 picks the task up with the evidence already attached instead of gathering it again.
  • Security operations. A security workflow brings additional context into a Microsoft Sentinel investigation through Azure Logic Apps, so an analyst sees the Elisity view alongside the alert that started the investigation.

ServiceNow appears twice because inventory management and service-desk review are different jobs. Each uses different records and routing logic.

These are integration designs that your team configures. The CLI handles the Elisity read; your workflow handles the mapping, routing and assignment.

Following the help-desk branch: an enforcement-score review

To make that concrete, follow the help-desk branch through an Ansible example.

From CLI output to a service-desk task: a recorded aggregate enforcement score moving from 85.0 to 57.3, an example Ansible rule comparing that movement against a ten-point threshold, and the resulting ServiceNow handoff to Network Operations

Here, a reporting observation becomes the starting point for a review. The recorded aggregate enforcement score moves from 85.0 to 57.3, a decrease of 27.7 points. That reading is the trigger for the workflow, not its conclusion.

The read itself is one command:

elisity -f json reporting get-aggregate-enforcement-score

The example Ansible rule compares that movement with a threshold of ten points. A 27.7-point decrease crosses it. When the threshold is crossed, the workflow prepares a ServiceNow handoff with the observation and its evidence attached, and Network Operations reviews the change in context — with the reading, the previous value and the time it was taken already in the task.

Important: The threshold is an example chosen for this workflow. The calculation was checked in a local replay; the Ansible and ServiceNow steps shown here are illustrative. The score tells us something changed, but it does not establish the cause.

In this workflow, the team defines the reads, the comparison and the destination in advance. Every step is decided before the job runs, which is what makes the result predictable enough to route to a queue.

What your workflow consumes

The integration surface is structured output plus exit codes. A job that runs a shell command and parses JSON or CSV consumes CCC data with no SDK: -f json or -f csv for the shape, -q for the fields you need, and environment variables (CCC_BASE_URL, CCC_CLIENT_ID, CCC_CLIENT_SECRET) so the runner needs no config file and can pull its credentials from your secrets manager.

Exit codes let the job tell a configuration problem from a CCC error from a network failure:

Exit code Meaning
0 Success; the response is on stdout.
1 Generic — usage, JMESPath syntax, or validation.
2 Configuration — missing base URL or credentials.
3 HTTP error — non-2xx from CCC, body on stderr.
4 Network — DNS, connect, or timeout after retries.

An empty result is exit 0: treat [] as a valid answer, not a failure.

Use Case 2 — Using the Elisity CLI in Your Agentic Workflows

The previous workflow knew its next step before it ran. This one does not. Suppose someone asks an agent to show them monitor-mode policies. Before the agent can do anything at all, it has to connect that phrase to the product's terminology and the appropriate command.

From automation to agent-led questions: a plain-language request for monitor mode policies resolved through the CLI vocabulary lookup to the Elisity term Simulation and a matching command recipe

The CLI supplies a vocabulary lookup for that purpose:

elisity glossary search "monitor mode"

In this verified example, the lookup connects "monitor mode" with Simulation, the supported value, and a command recipe. The agent uses that recipe to select its next read:

elisity -q '[].{name: name, status: status}' policy get-all-as-nd-json

This is part of the answer to "Why use the CLI when the API already exists?" The repository supplies product mappings, command recipes and common request handling that the agent can reuse, and your team can adopt updated commands from that shared repository as its needs evolve.

The agent still interprets the request and owns the workflow. The CLI gives it a prepared set of building blocks.

A longer review: vendor access against approved maintenance

One lookup is a small thing. The value shows up when several of those blocks go together in a review that nobody wrote a script for.

An agent-led review loop: Microsoft Copilot Studio reads the approved maintenance window from ServiceNow, issues successive Elisity CLI reads for site, device, group, policy and communication context, and prepares a ServiceNow review task for a security analyst and site owner

Imagine asking an agent to check vendor access against approved maintenance and prepare a review task for any exceptions. A customer-configured schedule or a maintenance event could initiate that review.

Microsoft Copilot Studio first gets the approved assets, service and time window from ServiceNow. It then chooses CLI reads to establish site and device context, identify relevant groups, inspect policy sets and rules, and examine communications. The results inform its next question, so the investigation can require additional reads and follow-up. That is the difference from the Ansible example: the third read depends on what the second one returned.

In this illustrative example, activity appears outside the approved maintenance window. That gives the agent a specific question to investigate — was an extension approved? It should resolve that context before treating the activity as an exception to the approval.

The agent prepares the ServiceNow draft with the relevant evidence and the open question attached. The security analyst and site owner decide what happens next.

Notice who owns the loop: Copilot Studio queries and reasons; the CLI returns Elisity evidence. The agent's separate ServiceNow action handles the task.

Illustrative workflow. Customer-configured trigger and connectors; no live integration was executed.

Keeping the agent inside a boundary

An agent that picks its own next step needs a boundary that does not depend on it choosing well. Four hold that line:

  • Read-only scope. Destructive commands require --confirm by design. Do not supply it automatically.
  • Named commands, not arbitrary execution. Allow-list what the agent may call rather than handing it a shell.
  • Scoped credentials. Use an API Client whose role grants only what the workflow needs. The role is the boundary, not the prompt.
  • A person reviews the result. The agent assembles evidence and frames the question; a person decides.

One CLI, whichever agent environment you use

The shared interface is the useful part of this approach.

Nine command- or tool-capable agent products arranged around a single Elisity CLI, illustrating the range of agent environments a team could expose the CLI to

Your team can expose the Elisity CLI to a command- or tool-capable agent through a configured runtime or a hosted adapter. The products shown above — Codex, Claude Code, Grok Bot, Hermes Agent, OpenClaw, Perplexity Computer, Microsoft Copilot Studio, Microsoft Agent Framework and LangGraph — illustrate that broader ecosystem. They are integration options, rather than a list of certified connectors.

The broader benefit is a reusable starting point: supplied vocabulary, commands and structured results that your agent can work with. The harness still owns orchestration and memory. The CLI does not automatically make a new session remember the last one.

Begin with a single useful workflow and build from there.

In a pilot across five paired runs, the CLI approach used 48 percent fewer uncached input tokens and 43 percent fewer output tokens than the baseline, and both approaches answered every task correctly. Those figures describe this pilot.

Troubleshooting

Symptom Cause and fix
No CCC_BASE_URL configured or Missing CCC_CLIENT_ID or CCC_CLIENT_SECRET No active profile, or an incomplete one. Create a profile, or export the values.
Profile 'X' does not exist The profile is not in the config file. Run elisity config list-profiles.
CCC authentication failed. Check credentials. Wrong client ID or secret, wrong base URL, no network path, or an expired API Client. Run elisity --debug auth test for the error body.
Requests time out Timeouts are retried three times with exponential backoff. Raise the timeout with export CCC_TIMEOUT=120, or set --timeout on the profile.
SSL certificate errors Expected against a lab instance with a self-signed certificate. Add verify_ssl: false to that profile in ~/.elisity/config.yaml. Never disable verification against production.
A flag appears to be ignored A global flag was placed after the command name.
A JMESPath projection returns nothing Usually a wrong field name, not a wrong filter; label versus name is the classic. Run the command without -q and read the keys.
Commands that worked before now fail authentication The API Client has reached the end of the Access Duration set when it was created. Regenerate the credentials in CCC and update the profile.

Otherwise --debug prints request details to stderr, leaving stdout clean:

elisity --debug topology get-all-sites 2> debug.log | jq '.[].label'

Next Steps

  • Full command reference — the repository at github.com/Elisity/elisity-cli, which also carries the configuration guide.
  • Explore from the CLIelisity --help, elisity <group> --help, and elisity glossary list when you know the term but not the command.
  • Start with a recurring operational question. Reproduce something you answer by hand each week as a command.
  • Feedback and issuesgithub.com/Elisity/elisity-cli/issues.
Was this article helpful?
0 out of 0 found this helpful