takestock
Take stock of an IT estate: what it runs, how it is protected, and what it needs next.
takestock collects evidence about an estate (public DNS and certificate logs, network probes you have authorised, and exports from the management tools you already run), grades what it finds against published standards, and writes:
| Output | What it is | Command |
|---|---|---|
| Observation | Every row found, graded, with the coverage gaps, as JSON and as a CycloneDX 1.6 cryptographic bill of materials (CBOM) | takestock observe |
| Configuration register | A draft CMDB: a schema plus every configuration item found, with how strongly each fact is known | takestock cmdb |
| IP address plan | Every site, subnet and address the evidence shows, each with its source and date | takestock ipam |
| Secure Government Email note | Every requirement of New Zealand's Secure Government Email framework, read as met, not met or not measured | takestock comply sge (HTML), takestock comply sge --format text (plain text) |
| Requirements | Requirements derived from the findings, written from public standards, ready to put to a supplier | takestock requirements |
Status: version 0.1.0, alpha. The commands work end to end on the sample organisation below; the command line and file formats may still change before 1.0, and
CHANGELOG.mdrecords each change.
Install
takestock needs Python 3.11 or later. From a clone of this repository:
make venv # .venv with takestock installed in editable mode, plus the dev tools
. .venv/bin/activate
takestock --version # takestock 0.1.0
Or into an environment of your own: pip install -e . (add '.[dev]' for
the test tools). Once a release is on PyPI, pip install takestock installs
it without a clone; the quick start below still needs the sample in
examples/, which is in the repository, not the package. The only Python
dependencies are PyYAML and openpyxl.
The collectors that probe hosts and query DNS drive external programs
(dig, curl, nmap, openssl, ssh-audit, ike-scan). None is needed
for the quick start below. docs/SETUP-SCANNERS.md
says which collector needs which, and how to install them.
Quick start on the sample organisation
examples/example-widgets/ is a complete workspace for Example Widgets
Ltd, a fictional manufacturer. Every name in it is a reserved domain and
every address is from a documentation range, so nothing in it is a real host.
It is graded against the bundled New Zealand standards (the NZISM, Secure
Government Email and the Protective Security Requirements), which are
defaults that any organisation, public or private, can adopt as they are or
replace with its own (see
docs/TARGET-PROFILE.md).
Copy it somewhere and work inside the copy, which makes the copy the workspace:
cp -R examples/example-widgets /tmp/example-widgets
cd /tmp/example-widgets
1. Take an observation, offline, so nothing is sent over the network and only the supplied exports are read:
$ takestock observe example-widgets --offline --inbox exports
observing Example Widgets Ltd into observations/2030-01-31T0930Z
inbox: /tmp/example-widgets/exports
· ssh_audit_inbox
· netdev
· software_inventory
· dns_zones
· winrm_config
observations/2030-01-31T0930Z
18 assets; verdicts {'weak': 2, 'strong': 3, 'unknown': 5, 'acceptable': 2, 'n/a': 6}; 5 coverage gap(s); 2 finding(s)
The observation directory is named for the UTC minute of the run, and
observations/latest points at the newest one. The command exits 1 because
it found two weak rows (see Exit codes). The five coverage
gaps record what this run could not see, including the seventeen collectors
an offline run does not start.
2. Build the configuration register from it:
$ takestock cmdb observations/latest
observations/latest/cmdb/cmdb.json
observations/latest/cmdb/csv/account.csv
...
observations/latest/cmdb/cmdb.xlsx
observations/latest/cmdb/keys.jsonl
3. Build the IP address plan from the plan file and the exports it names:
$ takestock ipam targets/example-widgets.ipam.yaml ipam --exports exports
ipam/example-widgets.json
ipam/example-widgets.csv
ipam/example-widgets.html
4. Write the Secure Government Email note for the profile's email domains:
$ takestock comply sge observations/latest example-widgets
observations/latest/sge-note.html
Offline, no mail record was read, so every requirement in the note reads
not measured, with the reason.
sge is the framework's id. takestock comply --list shows every standard
takestock can read an observation against, and --format text prints the
same reading as plain text instead of writing the note.
5. Derive requirements from the findings and gaps:
$ takestock requirements observations/latest
observations/latest/requirements/requirements.md
observations/latest/requirements/requirements.xlsx
observations/latest/requirements/requirements.json
6 requirement(s) derived
Run takestock <command> --help for every option.
What the tool writes, and what a person writes
takestock measures and drafts. It does not decide, and it cannot know what only people know.
| takestock produces | A person supplies |
|---|---|
Graded rows, coverage gaps and the CBOM (assets.json, summary.json, bom.cdx.json, and the raw transcripts under raw/) |
The target profile: the domains, the hosts authorised for probing, and the authorisation record for them |
| A proposed disposition for every graded row: a track, a reason and an effort size | The organisation's decisions, ladder, adoptions and dispensations, in a dispositions overlay beside the profile |
| A draft register of every item an instrument saw | Owners, services, contracts, sites and anything else no instrument reads |
| An IP plan placing every address an export or a dated document names | The plan file: sites, what each subnet is for, which sources to read |
| A conformance note that marks every requirement it cannot measure | The evidence only the organisation holds, such as its own mail transport logs |
| Requirements with standards, tests and an evidence sentence | The supplier's answers, in the columns the workbook leaves empty |
| The exports in the inbox, and lifecycle facts such as a planned retirement |
Every output says what it could not see. An empty section means not measured unless the output says otherwise.
Safety
Collectors come in three kinds:
| Kind | Sends | Runs |
|---|---|---|
| passive | DNS queries and certificate-log searches to public services; nothing to the organisation's hosts | on every observation, unless --offline |
| active | Probes to the organisation's hosts | only with --scan, and only when the target profile carries a complete authorisation: record |
| ingest | Nothing: reads exports someone supplied | always |
-
Without a complete authorisation record,
--scanis refused before anything is written or contacted. For a profile with no record at all:$ takestock observe example-widgets --scan takestock: REFUSED, nothing written or contacted: --scan needs an authorisation record in the target profile: no `authorisation:` stanza in the target profile
--scanand--offlinetogether are refused too. -
--carry-scan <observation>takes a new observation without probing again: the passive and ingest collectors run afresh, and the rows an earlier--scanobservation of the same target measured are carried in, each keeping the date it was measured. An observation older than--carry-max-agedays (31 unless set) is refused. A carried row graded cleartext-served on an HTTP port is re-checked with one plain-HTTP request, so a carry needs the authorisation record too whenever there is such a row; without it the carry is refused before anything is sent.summary.jsonrecords the carry undercarried_scan. Seedocs/ARCHITECTURE.md. -
Probes that run inside a network each need their own named, dated record as well, and every host must be named one at a time. Ranges, wildcards and lists over a ceiling are refused, never cut short.
-
No probe sweeps ports or logs in. Each contacts only the hosts and ports the profile names, and the list-driven probes print their whole plan before contacting anything.
-
The authorisation record is a record of who authorised what, not a security control. Run probes only against hosts you are authorised to test.
-
Observations map where an estate's cryptography is weak and how its hosts are named. Treat them, and every report built from them, as sensitive, and keep them out of any repository you publish. This repository's
.gitignoreignores anyinbox/orobservations/directory.
Exit codes
Every command follows one contract, so a script can act on the result:
| Code | Means |
|---|---|
0 |
Clean: the command did its work and found nothing adverse |
1 |
Findings present: observe found a weak verdict or work on an out-of-cycle rung; comply found an unmet MUST requirement; requirements derived at least one requirement |
2 |
Error: bad arguments, an unreadable input, a refused scan, or an observation that could not judge because a collector failed. The observation is still written, and summary.json lists the failures |
Documentation
| Guide | Covers |
|---|---|
docs/TARGET-PROFILE.md |
The workspace, the target profile and its overlays, key by key |
docs/ARCHITECTURE.md |
The pipeline, the data model, the registries, and how to add a collector |
docs/COLLECTORS.md |
What each collector reads or probes, and what it cannot see |
docs/PLUGINS.md |
Writing a plug-in collector for an export takestock has no reader for |
docs/SETUP-SCANNERS.md |
The external tools, and the authorisation record |
docs/DISPOSITIONS.md |
What to do about each finding: tracks, rules, decisions and dispensations |
docs/CMDB.md |
The configuration register |
docs/IPAM.md |
The IP address plan |
docs/SGE-NOTE.md |
The Secure Government Email note |
docs/REQUIREMENTS.md |
Requirements derived from the findings |
docs/STANDARDS.md |
The standards takestock grades against, and where they disagree |
docs/SECURE-GOVERNMENT-EMAIL.md |
How takestock reads the Secure Government Email framework |
docs/OBLIGATIONS.md |
The New Zealand laws and policies above the technical standards |
docs/RISK-SCALE.md |
The New Zealand government risk scale |
docs/CONTINUOUS-ASSURANCE.md |
How peer frameworks keep a security authorisation current |
Contributing
See CONTRIBUTING.md. In short: run make hooks once,
then make check. takestock carries no organisation's data: every
example and fixture is synthetic, and tools/guard.py enforces the parts of
that rule a machine can check. To report a vulnerability, see
SECURITY.md.
Licence
Apache License 2.0. See LICENSE and NOTICE.
Metadata
Release files for takestock 0.1.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 | Provenance | Actions |
|---|---|---|---|---|
| takestock-0.1.0.tar.gz | 683.4 kB | With provenance | Details for takestock-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| takestock-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for takestock-0.1.0-py3-none-any.whl |
Total release size: 1.2 MB
Release files / takestock-0.1.0.tar.gz
| Download URL | takestock-0.1.0.tar.gz |
|---|---|
| Size | 683.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4211c34b78eb18203ee122ca6b3045c78c635cc185bac6e49caace46fa3832cf
|
|
BLAKE2b-256 checksum How to use checksums |
55313a0c7f2721bc31e17ebb2af8d413d3b4fa8168018b27ee0509828cb8f9ea
|
| 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 Oct 16, 2026.
Transparency logRelease files / takestock-0.1.0-py3-none-any.whl
| Download URL | takestock-0.1.0-py3-none-any.whl |
|---|---|
| Size | 548.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
33fe716994b001f78d1efa94143911628145a806db42f49e904f59df232772ba
|
|
BLAKE2b-256 checksum How to use checksums |
637a6df62e85ec83df714babf1d89d0d6e269bfb7f73b3e87fc3b76a6c9c6c1d
|
| 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 Oct 16, 2026.
Transparency logSecurity for takestock 0.1.0
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for takestock-0.1.0.tar.gz
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 Oct 16, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.