Metadata-Version: 2.5
Name: libre-devops-helpers
Version: 0.5.1rc2
Summary: Libre DevOps Helpers: a fast, read-only CLI and importable helpers for Entra ID, Defender XDR, Intune, Azure, Graph, PIM, Logic Apps and ServiceNow, also shipped as a container image.
Project-URL: Homepage, https://github.com/libre-devops/python-helpers
Project-URL: Documentation, https://github.com/libre-devops/python-helpers/tree/main/docs
Project-URL: Changelog, https://github.com/libre-devops/python-helpers/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/libre-devops/python-helpers/issues
Author: Craig Thacker
License-Expression: MIT
License-File: LICENSE
Keywords: azure,azure-cli,defender-for-endpoint,defender-xdr,entra-id,intune,key-vault,log-analytics,logic-apps,microsoft-graph,microsoft-sentinel,pim,servicenow
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Security
Classifier: Topic :: System :: Systems Administration
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: requests>=2.31
Requires-Dist: typer>=0.12
Provides-Extra: keychain
Requires-Dist: keyring>=25; extra == 'keychain'
Description-Content-Type: text/markdown

<div align="center">

<a href="https://libredevops.org">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://libredevops.org/assets/libre-devops-white.png">
    <img alt="Libre DevOps" src="https://libredevops.org/assets/libre-devops-black.png" width="320">
  </picture>
</a>

# Libre DevOps Helpers

`ldo`: importable Python helpers and a fast CLI for day-to-day DevOps and security work.

[![Lint and Test](https://github.com/libre-devops/python-helpers/actions/workflows/ci.yml/badge.svg)](https://github.com/libre-devops/python-helpers/actions/workflows/ci.yml)
[![Coverage](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/libre-devops/python-helpers/badges/coverage.json)](https://github.com/libre-devops/python-helpers/actions/workflows/ci.yml)
[![CodeQL](https://github.com/libre-devops/python-helpers/actions/workflows/codeql.yml/badge.svg)](https://github.com/libre-devops/python-helpers/actions/workflows/codeql.yml)
[![Container](https://github.com/libre-devops/python-helpers/actions/workflows/container.yml/badge.svg)](https://github.com/libre-devops/python-helpers/actions/workflows/container.yml)

[![Release](https://img.shields.io/github/v/release/libre-devops/python-helpers?label=release&color=1793D1)](https://github.com/libre-devops/python-helpers/releases)
[![PyPI](https://img.shields.io/pypi/v/libre-devops-helpers?label=pypi&logo=pypi&logoColor=white&color=3775A9)](https://pypi.org/project/libre-devops-helpers/)
[![Container images](https://img.shields.io/badge/ghcr.io-python--helpers-2496ED?logo=docker&logoColor=white)](https://github.com/libre-devops/python-helpers/pkgs/container/python-helpers)
[![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-3776AB?logo=python&logoColor=white)](https://github.com/libre-devops/python-helpers/blob/main/pyproject.toml)
[![Licence: MIT](https://img.shields.io/badge/licence-MIT-blue.svg)](https://github.com/libre-devops/python-helpers/blob/main/LICENSE)

</div>

---

`ldo` is a fast, read-only command line for day-to-day security and platform work across
Microsoft (Entra ID, Defender XDR, Intune, Azure, Graph, PIM, Logic Apps) and ServiceNow. It
signs in as you, through the Azure CLI by default, and can read only what you can. The Python
sibling of the [LibreDevOpsHelpers](https://github.com/libre-devops/powershell-helpers)
PowerShell module, and importable as a library too.

---

## Commands

| Command | What it does | Docs |
| --- | --- | --- |
| `ldo devices` | check a list of devices across Entra, Defender and Intune, watch until they are all there, show one, read Defender Antivirus versions | [devices](https://github.com/libre-devops/python-helpers/blob/main/docs/devices.md) |
| `ldo entra` | devices and whether they are in a group, users, groups, roles, sign-ins, app credentials, Conditional Access; tokens | [entra](https://github.com/libre-devops/python-helpers/blob/main/docs/entra.md) |
| `ldo intune` | managed devices: compliance, last sync, owner | [entra](https://github.com/libre-devops/python-helpers/blob/main/docs/entra.md) |
| `ldo xdr` | Defender machines, alerts, vulnerabilities, indicators, Advanced Hunting, a device's timeline, custom detection rules (and their export to YAML) | [defender](https://github.com/libre-devops/python-helpers/blob/main/docs/defender.md) |
| `ldo xdr incidents` | the Defender XDR queue, Sentinel's included: top, latest, between days, summary | [defender](https://github.com/libre-devops/python-helpers/blob/main/docs/defender.md#incidents-sentinels-included) |
| `ldo graph` | any Graph GET, objects by name, `whoami`, a Graph token, hunting | [graph](https://github.com/libre-devops/python-helpers/blob/main/docs/graph.md) |
| `ldo azure` | subscriptions, Resource Graph, role assignments, Defender for Cloud | [azure](https://github.com/libre-devops/python-helpers/blob/main/docs/azure.md) |
| `ldo azure automation` | Automation accounts: runbook jobs, and each job's logs and output | [azure](https://github.com/libre-devops/python-helpers/blob/main/docs/azure.md#automation) |
| `ldo keyvault` | secrets, certificates and keys close to expiry | [azure](https://github.com/libre-devops/python-helpers/blob/main/docs/azure.md#key-vault) |
| `ldo logs` | KQL against a Log Analytics or Sentinel workspace, and which tables are receiving data | [azure](https://github.com/libre-devops/python-helpers/blob/main/docs/azure.md#log-analytics) |
| `ldo pim` | eligible, active and standing access, requests, approvals, activation settings | [pim](https://github.com/libre-devops/python-helpers/blob/main/docs/pim.md) |
| `ldo logicapp` | offline checks, export and validation for Consumption Logic Apps and Sentinel playbooks | [logic apps](https://github.com/libre-devops/python-helpers/blob/main/docs/logic-apps.md) |
| `ldo snow` | ServiceNow: sign in, whoami, the instance, applications, a token | [servicenow](https://github.com/libre-devops/python-helpers/blob/main/docs/servicenow.md) |
| `ldo az` | switch the Azure CLI between profiles | [signing in](https://github.com/libre-devops/python-helpers/blob/main/docs/authentication.md) |
| `ldo network test` | test the way out through a corporate proxy: the proxy, the certificates, each service | [network](https://github.com/libre-devops/python-helpers/blob/main/docs/network.md) |
| `ldo json` | pretty-print any JSON (`az rest ... \| ldo json`) in colour, or as YAML | [configuration](https://github.com/libre-devops/python-helpers/blob/main/docs/configuration.md#json-yaml-and-logs) |
| `ldo profiles`, `ldo config` | your profiles, and the config file | [configuration](https://github.com/libre-devops/python-helpers/blob/main/docs/configuration.md) |

Every command takes `-p` for a profile and `-o table|json|csv|tsv`, lists take `--sort` and
`--unique` by column, and lists of names come from arguments, stdin, a text file, or a
column of a CSV or Excel workbook.

---

## Install

From [PyPI](https://pypi.org/project/libre-devops-helpers/):

```bash
uv tool install libre-devops-helpers     # the ldo command, in an environment of its own
pipx install libre-devops-helpers        # the same, with pipx
uv pip install libre-devops-helpers      # into the current environment, to use it as a library
pip install libre-devops-helpers         # the same, with pip
uv tool upgrade libre-devops-helpers     # later, to the newest release
```

Add the `keychain` extra (`"libre-devops-helpers[keychain]"`) to keep sign-ins in the macOS
Keychain or the Linux Secret Service. A tagged release installs straight from GitHub too:
`uv tool install git+https://github.com/libre-devops/python-helpers@v0.5.0`.

Or run the container image, which has the Azure CLI inside:
`podman run --rm -it ghcr.io/libre-devops/python-helpers:latest --help`
(see [Container images](https://github.com/libre-devops/python-helpers/blob/main/docs/containers.md)).

---

## Quickstart

```bash
az login                        # the default sign-in is the Azure CLI's
ldo config init                 # write ~/.config/ldo/config.toml
$EDITOR "$(ldo config path)"    # put your tenant id in a profile
ldo profiles                    # your profiles, and whether each can sign in
```

Then:

```bash
ldo devices check web01,web02                        # in Entra and onboarded to Defender?
ldo devices check -f plan.xlsx --column FQDN --tag linux-servers
ldo devices av-signature web01                       # Defender Antivirus versions
ldo entra devices -f plan.xlsx --column FQDN --group "MDE Pilot Devices"
ldo azure automation logs aa-ops --runbook Rotate-Keys    # the newest run's logs
ldo graph get-device web01
ldo xdr alerts --since 24h --severity high
ldo azure resource-graph "resources | summarize count() by type"
ldo keyvault expiry --all-vaults --within 30d
```

Incidents, Graph hunting and PIM for Entra roles need scopes the Azure CLI's token never
has: sign in through [your own app registration](https://github.com/libre-devops/python-helpers/blob/main/docs/authentication.md#your-own-app-registration)
for those. [Permissions](https://github.com/libre-devops/python-helpers/blob/main/docs/permissions.md) lists what each command needs.

---

## Documentation

- [Configuration](https://github.com/libre-devops/python-helpers/blob/main/docs/configuration.md): profiles, common options, environment variables, exit codes
- [Proxies and certificates](https://github.com/libre-devops/python-helpers/blob/main/docs/network.md): corporate proxies, cntlm, TLS inspection
- [Signing in](https://github.com/libre-devops/python-helpers/blob/main/docs/authentication.md) and [Permissions](https://github.com/libre-devops/python-helpers/blob/main/docs/permissions.md)
- [Container images](https://github.com/libre-devops/python-helpers/blob/main/docs/containers.md)
- [Using it as a library](https://github.com/libre-devops/python-helpers/blob/main/docs/library.md) and [Rebranding](https://github.com/libre-devops/python-helpers/blob/main/docs/rebranding.md) for your organisation
- [Development](https://github.com/libre-devops/python-helpers/blob/main/docs/development.md): `just` recipes, tests, CI and releasing
- [AI.md](https://github.com/libre-devops/python-helpers/blob/main/AI.md): the instructions for AI coding assistants (Claude Code, Copilot, Codex)

Contributions are welcome: see [CONTRIBUTING.md](https://github.com/libre-devops/python-helpers/blob/main/CONTRIBUTING.md), and
[SECURITY.md](https://github.com/libre-devops/python-helpers/blob/main/SECURITY.md) to report a vulnerability. Licensed under [MIT](https://github.com/libre-devops/python-helpers/blob/main/LICENSE).

---

<div align="center">
<sub>
Part of <a href="https://libredevops.org">Libre DevOps</a>. Everything we publish is open and
provided as-is; review and test it against your own requirements before production use.
</sub>
</div>
