Libre DevOps Helpers
ldo: importable Python helpers and a fast CLI for day-to-day DevOps and security work.
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
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 |
ldo entra |
devices and whether they are in a group, users, groups, roles, sign-ins, app credentials, Conditional Access; tokens | entra |
ldo intune |
managed devices: compliance, last sync, owner | entra |
ldo xdr |
Defender machines, alerts, vulnerabilities, indicators, Advanced Hunting, a device's timeline, custom detection rules (and their export to YAML) | defender |
ldo xdr incidents |
the Defender XDR queue, Sentinel's included: top, latest, between days, summary | defender |
ldo graph |
any Graph GET, objects by name, whoami, a Graph token, hunting |
graph |
ldo azure |
subscriptions, Resource Graph, role assignments, Defender for Cloud, splitting resource ids into their parts | azure |
ldo azure automation |
Automation accounts: runbook jobs, and each job's logs and output | azure |
ldo keyvault |
secrets, certificates and keys close to expiry | azure |
ldo logs |
KQL against a Log Analytics or Sentinel workspace, and which tables are receiving data | azure |
ldo pim |
eligible, active and standing access, requests, approvals, activation settings | pim |
ldo logicapp |
offline checks, export and validation for Consumption Logic Apps and Sentinel playbooks | logic apps |
ldo snow |
ServiceNow: sign in, whoami, the instance, applications, a token | servicenow |
ldo az |
switch the Azure CLI between profiles | signing in |
ldo network test |
test the way out through a corporate proxy: the proxy, the certificates, each service | network |
ldo json |
pretty-print any JSON (az rest ... | ldo json) in colour, or as YAML |
configuration |
ldo profiles, ldo config |
your profiles, and the config file | configuration |
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:
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.6.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). Each release is also in the
GitLab copy's package and container
registries (how).
Quickstart
Sign in with the Azure CLI, and ldo works as you at once, in the tenant and subscription
az is using. Nothing else is needed.
az login
ldo az whoami # who ldo reads as, and where
ldo devices check web01,web02 # in Entra and onboarded to Defender?
ldo xdr alerts --since 24h --severity high
A profile for each tenant or subscription you work in is optional: ldo config init, then
see Configuration.
Checking a change from its plan
Give it the plan: the workbook, the sheet, the column of names, and which rows to take. Here, the servers changing today, which should end up in two Entra groups:
ldo devices check -f plan.xlsx --sheet "Ring 1" --column FQDN --where "Scheduled Date=today" \
--group "Linux servers" --group "Linux pilot"
ldo devices watch -f plan.xlsx --sheet "Ring 1" --column FQDN --where "Scheduled Date=today" \
--group "Linux servers" --group "Linux pilot" --interval 5m --timeout 4h
check looks once; watch looks again every --interval until every server meets every
expectation, and exits 0 then, or 3 when --timeout comes first. Each row says how many
checks the server meets (MET): --sort met:desc puts the complete ones first. --where
takes a day (25/09/2026, tomorrow) or a span (last 7d,
2026-09-01..2026-09-14); see lists of names
and check and watch.
More:
ldo devices av-signature -f plan.xlsx --column FQDN # Defender Antivirus versions
ldo entra devices -f plan.xlsx --column FQDN --group "Linux pilot"
ldo azure automation logs aa-ops --runbook Rotate-Keys # the newest run's logs
ldo azure resource-graph "resources | summarize count() by type"
ldo keyvault expiry kv-app-prd --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 for those. Permissions lists what each command needs.
Documentation
- Configuration: profiles, common options, environment variables, exit codes
- Proxies and certificates: corporate proxies, cntlm, TLS inspection
- Signing in and Permissions
- Container images
- Using it as a library and Rebranding for your organisation
- Development:
justrecipes, tests, CI and releasing - AI.md: the instructions for AI coding assistants (Claude Code, Copilot, Codex, Kiro)
Contributions are welcome: see CONTRIBUTING.md, and SECURITY.md to report a vulnerability. Licensed under MIT.
Release files for libre-devops-helpers 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| libre_devops_helpers-0.6.0.tar.gz | 659.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| libre_devops_helpers-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 988.5 kB
Release files / libre_devops_helpers-0.6.0.tar.gz
| Download URL | libre_devops_helpers-0.6.0.tar.gz |
|---|---|
| Size | 659.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
db3f361979535c88dac81e6a871904ebacbb9b609e5f664a24298b95a07331fd
|
|
BLAKE2b-256 checksum How to use checksums |
bfc9d764d2331161550a1c47388508aba5b5dd62e9eba46b43725504494e233c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.
Transparency logRelease files / libre_devops_helpers-0.6.0-py3-none-any.whl
| Download URL | libre_devops_helpers-0.6.0-py3-none-any.whl |
|---|---|
| Size | 328.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f4979ae5373ae4751bb916f379264cedaa03e8492914968e68ec4f0950c425c5
|
|
BLAKE2b-256 checksum How to use checksums |
fae96ac9ad1b59a29694ccc71b6d7da64c717ee7596ba359f9938fbd4ca103d8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.
Transparency log