Files
Samsara/audit/SECURITY_AUDIT.md
oceans2alaska 610a3bb447 Privacy hardening, remote-peer IP masking and review fixes
- Add privacy projection (core/privacy.py), private report storage, bounded
  process capture; omit identities, free text and unapproved paths
- Mask remote peer IPs: only loopback/host/wildcard stay numeric, others are
  reduced to remote_scope private/public (schema + scoring updated)
- Map ss TCP states to canonical names; ASCII-only numeric fields; fix
  "Microsoft Visual C++" product matching (Python and PowerShell)
- Merge 7fed3b9: -Diagnostic switch, serialization exit code 3, PS7 module
  path, UI error detail; keep hardened task/certificate collectors
- Add audit docs, privacy docs and regression tests

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-04 18:50:24 -08:00

249 lines
33 KiB
Markdown

# Samsara security and healthcare-data audit
**Audit date:** 2026-10-30. **Method:** offline, source-only review. **Overall assessment:** High risk against the stated healthcare production requirements; **not ready for production approval**. This is not a HIPAA compliance certification, legal determination, penetration test, vulnerability-database scan, or evidence that an actual patient-data breach occurred.
## Scope, provenance and limitations
Reviewed the available working-tree Python application, PowerShell modules, schema, dependency declarations, tooling, tests, fixtures, documentation and artifact metadata. All application entry points and first-party source files were examined; static AST/import/call inventories and text searches were used without importing or running the application. Read installed distribution metadata and limited validator source to establish dependencies; the vendored third-party codebase/native binaries were not exhaustively audited.
The local `.git` directory is an empty read-only environment placeholder, not a usable Git checkout. `Samsara.bundle` advertises `57e716b71052a5c2e06bd2cdd121973c6c3f0359`. That is an artifact reference, **not proof the working tree is a clean checkout of that commit**. The separately reported upstream `7fed3b9` reliability changes cannot be certified as included: no network request was made and remote Git history was not fetched. Audit the actual proposed release again after verifying its provenance. The snapshot manifest below identifies the bytes reviewed.
No collectors, application GUI, unit tests, PowerShell, package installers, scanners, production queries or network clients were executed. Tests were inspected as source, not used as runtime evidence. Only the new `audit/` documents were written. No production reports or patient data were requested. Fixture flags identify synthetic test data; flags are not a general guarantee that arbitrary imported data are non-sensitive. Git-object history, opaque bundle contents beyond reference metadata, production ACLs, OS logging, native module behavior, binary provenance, telemetry and current CVEs remain **Unverified**.
**Status convention:** Pass confirms a narrowly scoped source-level control; Fail means code contradicts a requested assurance/control; Unverified means source evidence does not establish the runtime or organizational claim. A confirmed exposure-capable path is not confirmation that its actual values are PHI. Names, accounts and IP addresses are not automatically PHI; unrestricted values can become PHI when they identify a patient in a healthcare context.
## Executive summary
1. **Samsara cannot currently be described as PHI-free.** Names, paths, identities, certificate subjects and other strings flow into memory, UI, temporary output and reports without a patient-data exclusion policy.
2. **Open-file aggregation is not collection minimization.** `Get-SmbOpenFile` obtains objects before aggregate projection; filenames and client/user metadata can enter PowerShell memory even when absent from final JSON.
3. **Configuration-changing Windows collector commands were not identified.** This supports a narrow read-only configuration intent. It does not establish zero host writes: temporary output, report files, process creation/termination, interpreter/native caches and OS logging are separate issues.
4. **No explicit first-party HTTP upload, telemetry, database connection or remote Windows collection was identified.** Arbitrary filesystem paths can nevertheless reach UNC/mapped/network-backed destinations; native dependencies/OS behavior have not been egress-tested.
5. **Dependency assurance is incomplete.** Broad direct version ranges, no lockfile/hashes/SBOM, unneeded installed Qt components and unverified native/transitive vulnerability status prevent approval.
6. **Existing redaction is selective.** Error-category normalization and omission of command arguments/private keys are valuable controls, but do not remove sensitive values from approved free-text fields or undo earlier processing.
## Entry points and traced execution
| Entry | Execution and trust boundary |
| --- | --- |
| `samsara/main.py:5-24` | Creates Qt application, configures process identity, imports the existing UI. Native Qt plugins and desktop integration enter the trusted runtime. |
| `samsara/ui/window.py:19-54`, `:361-408` | User action starts `CollectionJob`; local OS determines the Windows/Linux backend, a file invokes JSON import, and samples read bundled fixtures. The UI receives a complete data dictionary and derives assessment results. |
| `samsara/collectors/windows.py:129-175` | Fixed section dispatch -> system PowerShell executable -> JSON in temporary stdout -> section validation -> field projection -> final v1 validation. The data have already been collected and written to temporary storage before final projection. |
| `powershell/Get-ServerInventory.ps1:1-56` | Independent fixed section or full-envelope dispatch. Modules are dot-sourced from the checkout. Full mode lacks the Python timeout supervisor. |
| `samsara/collectors/windows.py:178-193` | Headless local Windows collection and exclusive creation of a user-selected inventory file. |
| `samsara/collectors/linux.py:100-215` | Local metadata/configuration reads and fixed utility invocations; separate CLI writes JSON. No remoting parameters. |
| `tools/validate_windows_host.py:14-51` | Intentionally performs real local collection, creates directories, exports JSON/HTML/sidecar, writes a diagnostic summary and prints status metadata. **Not executed in this audit.** |
| `samsara/reporting/export.py:15-86` | Public export functions write all supplied data without enforcing a privacy profile or approved output root. GUI calls them at `samsara/ui/window.py:486-498`. |
| `tests/test_powershell.py:9-16`, `tests/test_linux.py:36-65` | Development-only paths. Native test launcher executes PowerShell when present; some Linux tests mock commands but still invoke functions that read real local metadata/cron. Do not assume the suite is wholly host-isolated. |
## Confirmed findings
### S-01 — PHI-capable free-text collection and export — High — Fail
**Evidence:** `powershell/Get-ServerServices.ps1:5-7`; `Get-ServerTasks.ps1:12-16`; `Get-ServerCertificates.ps1:9-12`; `Get-ServerSoftware.ps1:8-12`; `Get-ServerStorage.ps1:17-19`; `Get-ServerSystem.ps1:24-31`. All paths are under `powershell/`.
Service/task names, account identities, share paths, certificate subject/issuer and registry display fields are copied as strings. `samsara/models/inventory.py:22-41` selects property names, not privacy-approved values. `samsara/analyzers/dependencies.py:118`, `:145-167`, `:220-240` embeds names, accounts, paths and endpoints in evidence; `samsara/reporting/export.py:15-25`, `:50-86` exports them. A healthcare identifier in any retained field can therefore reach reports and temporary collector output.
**Impact:** potential PHI processing/disclosure through metadata, not evidence that a patient record was actually collected. **Action:** define a CHS-approved field/source policy. Suppress high-risk strings at source or explicitly classify the workflow as potentially processing PHI and apply approved controls. Post-query redaction cannot prove that PHI never entered memory.
### S-02 — Unrestricted provider objects precede redaction — High — Fail
**Evidence:** `powershell/Get-ServerStorage.ps1:22-43` retrieves all open-file objects, processes full paths/relative filenames and client computer values, then exports counts. Administrative shares are excluded only after the broad query. `Get-ServerTasks.ps1:4-16` receives full task definitions before selecting fields. `Get-ServerCertificates.ps1:5-12` receives provider certificate objects before selecting metadata.
**Impact:** the raw SMB result includes potentially identifying file/client metadata in PowerShell/provider memory. Task arguments/descriptions/event-trigger payloads and certificate extension material may also be present in provider objects; exact provider materialization is **Unverified** without native inspection. Their omission from JSON is not proof of non-collection. **Action:** disable unapproved sources by default; redesign acquisition to avoid retrieving patient-bearing fields where possible, or approve it as controlled sensitive processing. Never use real PHI to test this boundary.
### S-03 — Exports/history retain more information than the main report shows — High — Fail
**Evidence:** `samsara/reporting/export.py:15-29`, `:39-41`, `:81-86`; `samsara/ui/window.py:401-417`, `:460-479`.
An HTML save automatically creates a full inventory JSON sidecar. JSON assessment export includes complete inventory and evidence. Full data and assessments accumulate in `self.records` for the session; there is no data TTL, history size limit or explicit secure disposal. Neither export function independently validates/redacts its supplied dictionaries. HTML escaping prevents markup execution, not PHI disclosure. SHA-256 is neither anonymization nor encryption.
**Action:** approved minimal exports by default, separate privileged authorization for raw artifacts, central privacy projection before every output, bounded session retention, restricted storage and a documented purge policy. Label/hash/signature and access controls must not imply de-identification.
### S-04 — Arbitrary output/input paths; no approved destination or file-permission policy — High — Fail
**Evidence:** `samsara/ui/window.py:330-359`, `:486-498`; `samsara/reporting/export.py:16-28`, `:86`; `samsara/collectors/windows.py:185-186`; `samsara/collectors/linux.py:207-208`; `tools/validate_windows_host.py:20-43`.
Paths may be local, network-backed, symlinks/reparse points or destinations outside an approved directory. HTML/JSON `write_text` truncates an existing file and follows ordinary path resolution. Sidecar exclusive creation is a positive control, but its existing-file `read_bytes` comparison follows the existing path and is unbounded. There is no explicit restrictive ACL/mode, encryption, destination allowlist or retention enforcement. Ordinary CLI `x` mode prevents overwriting an existing path, not network use or unsafe newly created permissions.
**Impact:** unauthorized disclosure/clobbering under the operator's rights; use of a writable hostile directory creates additional race/link risk. These are conditional, not observed exploits. **Action:** canonical approved roots, safe handle-based creation, reparse/symlink policy, least-privilege ACLs, explicit overwrite decisions and encrypted approved storage. Treat remote destinations as a separately authorized feature.
### S-05 — Collection writes unredacted stdout to host temporary storage — High — Fail for a PHI-free/zero-write claim
**Evidence:** `samsara/collectors/windows.py:60-92`; `samsara/collectors/linux.py:29-53`.
Subprocess output is directed to a disk-backed temporary file before JSON parsing/projection. For Windows, this runs on the assessed local execution host. Deletion/closing in `finally` is beneficial but is not secure erasure and does not cover pagefiles, crash dumps, storage snapshots, EDR or transcription. Temporary-file ACLs and actual placement have not been tested on Windows. The 10 MiB size check is polled, so it is not a hard disk quota; collection can overshoot between polls.
**Action:** an approved bounded IPC/spooling design, no raw patient-bearing acquisition, controlled temporary storage if unavoidable, OS protection/retention and documented exceptions. Do not promise reliable zeroization of Python/PowerShell strings or SSD files.
### S-06 — Full parent environment is copied into the Windows child — Medium — Fail for strict data minimization
**Evidence:** `samsara/collectors/windows.py:57-64`; `powershell/Get-ServerInventory.ps1:9`. Only `PSModulePath` is narrowed. Other inherited variables can include secrets. The application does not intentionally dump the environment into reports, but copies it in memory and passes it to PowerShell. Also review default registry `GetValue` expansion for expandable strings (`powershell/Get-ServerSoftware.ps1:8-11`); whether production values expose substituted environment data is **Unverified**.
**Action:** a tested minimum child-environment allowlist; preserve required Windows operation without carrying unrelated credentials. Read approved registry types with explicit non-expansion semantics where appropriate. Validate with synthetic secret canaries.
### S-07 — Dependency/release integrity is not reproducible — High — Fail
**Evidence:** `requirements.txt:1-2`; `samsara/collectors/windows.py:19`, `:45-64`; `powershell/Get-ServerInventory.ps1:15-17`; `samsara/core/startup.py:14`; `samsara/ui/branding.py:20-22`.
There are no exact dependency locks, required hashes, build manifest/SBOM or first-party release verification in the available tree. Absolute script location and a system PowerShell path reduce search-path risk, but the checkout's Python/scripts/schema/assets remain trusted executable/configuration inputs without application-enforced release authenticity. A writable elevated deployment could execute altered code with that token. Qt/native image/plugin dependencies extend this boundary. No exploitation or compromised dependency was established.
The local PySide6 meta-package also installs WebEngine, PDF and Addons components not used by the application's imports. Installed capability is not evidence that these components are launched or transmit telemetry.
**Action:** immutable reviewed deployment ACLs, organization-approved signatures/publisher enforcement, platform-specific hashed locks, approved wheelhouse and full native/Python SBOM. Evaluate a minimal Qt distribution after functional/security testing.
### S-08 — Allowlist/schema validation is not fully fail-closed — Medium — Fail
**Evidence:** `schemas/inventory-v1.schema.json:25-80`, `:81-145`, `:167-190`, `:216-250`; `samsara/models/inventory.py:15-41`; `samsara/collectors/importer.py:10-53`.
Nested objects generally permit extra properties; some retained keys (e.g. `server.last_boot`, optional network process/PID/direction metadata) lack complete type/value constraints. Projection is shallow, so an object in a retained but weakly typed field can preserve nested unapproved data. Arbitrary check names survive import and enter evidence/report text. Imports first deserialize all content, including discarded fields; live Windows projection occurs after temporary output has already been written. Arrays/strings/depth lack comprehensive structural limits despite the 10 MiB input cap.
The local jsonschema `_format.py:395-402` registers date-time validation only when `rfc3339_validator` can import; that module/distribution is absent in the reviewed isolated venv metadata. `_format.py:111-129` silently returns for an unavailable checker. Effective format enforcement is consequently not assured by merely constructing `FormatChecker`; alternative externally injected module availability is **Unverified**.
**Action:** close nested schemas, type/bound every retained field, enumerate check identifiers, reject unapproved structures before normal processing, enforce depth/count/value limits and explicitly assert the required format validators are available. Privacy classification must go beyond types.
### S-09 — Offline/no-exfiltration is not enforced — High — Fail for an unconditional no-network claim
**Evidence:** arbitrary `Path.open`/writes in `samsara/collectors/importer.py:11`, `samsara/analyzers/policy.py:19-23`, `samsara/reporting/export.py:16-28`, `:86`, and `tools/validate_windows_host.py:20-43`.
No explicit first-party HTTP/API upload was found. Nevertheless UNC/mapped/network-backed filesystem paths can cause OS network reads/writes and authentication. Destination restrictions or egress policies do not exist in the source. Qt native dialogs/desktop integration, certificate validation, OS providers, endpoint security and dependencies have not been observed offline. Public URLs in documentation and the schema identifier do not themselves demonstrate network activity.
**Action:** approved local-only path policy, deny-by-default host/network egress as appropriate, and isolated synthetic runtime tracing. Do not disable enterprise audit/security logging to conceal data; minimize what is collected and establish approved logging destinations.
### S-10 — No independently verified read-only/least-privilege release acceptance — Medium — Unverified
**Evidence:** local subprocess paths and all PowerShell modules; token check `powershell/Get-ServerInventory.ps1:19-23`; conservative permissions handling `powershell/Inventory.Common.ps1:45-54`; native test launcher `tests/test_powershell.py:9-16`.
No explicit assessed registry/service/task/certificate mutation was found. There is no automatic privilege elevation or remoting enablement. Those are positive controls, not proof of all native provider side effects or required access rights. Exact permission needs, silent provider filtering, module caches/logs and release behavior on each Windows Server version remain unverified in this audit. The application checks OS/permissions, not CHS change authorization or host ownership.
**Action:** a signed exact-release lab acceptance plan with synthetic data; standard-user and narrowly delegated accounts; registry/task/service/certificate/configuration diffs and filesystem/process/egress traces; organizational host/scope authorization. See the read-only and remediation documents.
## Positive controls confirmed by source
- Production subprocesses use argument lists with `shell=False`; Windows has a fixed section enum, `-NoProfile`, `-NonInteractive`, a repository script path and no execution-policy bypass (`samsara/collectors/windows.py:35-64`). Linux callers use fixed arguments and timer-name validation (`samsara/collectors/linux.py:20-32`, `linux_schedules.py:77-82`). This does not protect a tampered deployment itself.
- Software reads both registry views and opens child keys read-only; no `Win32_Product` query (`powershell/Get-ServerSoftware.ps1:6-12`, `:22-32`). Registry handles are disposed.
- No explicit credential prompt, password storage, service restart, scheduled-task modification, registry write, certificate/private-key export, WinRM/SSH setup, clinical database query, packet capture or event/application-log collector was identified.
- Provider errors are converted to fixed categories rather than raw exception serialization (`powershell/Inventory.Common.ps1:4-18`). Import maps error text/codes and removes source-label assertions (`samsara/collectors/importer.py:25-53`). Raw errors still can exist in process/OS memory or external logs.
- HTML values and relative artifact links are escaped/encoded (`samsara/reporting/export.py:32-36`, `:40`, `:82`). UI text labels are plain text (`samsara/ui/window.py:158-164`). Generated HTML contains no script or external content source.
- Failed checks remain explicit and coverage is separate from workload risk (`samsara/analyzers/assessment.py:37-78`). Retirement review is always required. This is not a validated business-dependency or privacy classifier.
## Network-capable paths
| Path | Destination / payload | Conditions and disablement | Assessment |
| --- | --- | --- | --- |
| Report/CLI/tool filesystem writes | User-selected UNC/mapped/mounted path; full inventory/evidence or summary | User selects path; no local-only/approved-root enforcement. Constrain via future code/OS policy. | Capability confirmed; actual connections not observed. |
| Inventory/policy input and existing sidecar reads | User-selected filesystem destination; remote file read and possibly OS authentication | File selection/path argument or existing sidecar comparison; no remote-path prohibition. | Capability confirmed. Not an HTTP integration. |
| `samsara/main.py:14-20` Qt/native file dialogs | Desktop IPC/portal/file-dialog providers; app identity, displayed UI and path metadata; possible network browsing | Desktop launch/native dialogs. No dedicated Samsara network-disable switch. | IPC/native behavior Unverified here. Qt signal `.connect` calls are not sockets. |
| Windows OS/CIM/storage/certificate providers | Local provider calls by source; possible downstream provider/OS/CRL/EDR destinations depend on host | Local collection/executable load. No `-ComputerName` or `-CimSession` supplied. | Native downstream effects Unverified. Do not infer remote queries merely from cmdlet capability. |
| Deployment on a network share | Python imports, scripts, schema and assets read from a network-backed checkout; OS file/authentication traffic | Source root is derived from `__file__`; no local-only deployment restriction. Approved immutable local deployment can avoid this route. | Capability conditional on deployment; actual destination Unverified. |
| Dependency setup in README | Configured pip index/mirrors or OS package repositories; package/version/platform metadata | Manually executed setup only; not GUI auto-update. Offline approved wheelhouse is possible but not provided. | Documented network-capable workflow; not executed. |
| Schema/URLs and helpers | Current schema uses an identifier URL, no remote `$ref`; `urllib.parse.quote` encodes strings, `socket.gethostname` obtains local name | Local parse/hostname. No current first-party resolver/connect/upload call. | No direct network request identified in these uses. |
A source/credential-pattern search found only synthetic credential canaries in tests, not a confirmed live hardcoded secret. This is not a complete history/binary secret scan. No network requests or captured assessment data were sent during the audit.
## Final management assessment
| Question | Status | Evidence-based answer |
| --- | --- | --- |
| 1. Can Samsara potentially collect PHI? | **Fail** against the PHI-free requirement | Yes. S-01/S-02: unrestricted metadata can carry patient information into memory, temporary stdout and reports. Field names do not establish privacy safety. |
| 2. Are there confirmed paths that collect or expose PHI? | **Unverified** for actual PHI occurrence | Confirmed **PHI-capable paths** include service/task/share/certificate strings and broad SMB objects (S-01/S-02/S-03). No actual patient values or production reports were examined; no actual PHI incident is established. |
| 3. Is it fully read-only with respect to assessed Windows Servers? | **Unverified** | Source-level configuration mutation scan passes narrowly. Local execution still creates/terminates collector processes and writes temporary/report files; providers/caches/logging are not instrumented. An absolute zero-state-change claim would fail. |
| 4. What can modify local files or other state? | **Fail** for approved-write enforcement | Export JSON/HTML/sidecars, CLI inventory output, validation directories/summary, temporary creation/deletion, child-process lifecycle and shell identity. Implicit Python/Qt/OS caches/logs are Unverified. Approved directory/ACL restrictions are missing (S-03-S-05). |
| 5. Does it make external network connections? | **Unverified** | No direct application HTTP upload/telemetry/database connection was found. Actual runtime egress was not observed. Network-backed paths are allowed and can transmit inventory/authentication; the unconditional no-network control fails, and native/OS/dependency behavior is unverified (S-09). |
| 6. Are all dependencies identified and justified? | **Fail** | Direct and discoverable Python dependencies are inventoried; unused Qt components, native closure, exact Windows versions/provenance and CVEs remain unresolved. No reproducible release lock/SBOM (S-07). |
| 7. What prevents production approval? | **Fail — approval not supportable** | PHI-capable acquisition/exports, unapproved storage/egress, incomplete release/dependency integrity and native/least-privilege evidence; no completed organizational privacy/security review. |
| 8. What must change before proposing CHS deployment? | **Fail — not ready** | Close P0/P1 items in REMEDIATION_PLAN.md, define the allowed-data/read-only model, validate exact release in a synthetic isolated lab and obtain CHS security/privacy/operations approvals. Successful code tests alone cannot establish HIPAA compliance. |
## Deliverables and evidence assurance
- [Collector data flow and PHI exposure](PHI_DATA_FLOW.md)
- [Read-only command, write and privilege verification](READ_ONLY_VERIFICATION.md)
- [Dependencies, native runtime and outstanding scans](DEPENDENCY_INVENTORY.md)
- [Prioritized remediation and acceptance plan](REMEDIATION_PLAN.md)
The final audit integrity check compares pre-existing source/artifact hashes against the initial snapshot; its result is recorded below. No remediation has been implemented as part of this audit.
## Snapshot manifest and no-change verification
Verified **74 pre-existing first-party/source/artifact files unchanged** against the initial audit snapshot. Only the five requested Markdown documents under `audit/` were created. The hash scope excludes the environment-owned `.git/.aws/.codex/.agents` placeholders, the third-party `.venv`, bytecode caches and the new audit documents. Those exclusions are scope boundaries, not proof of their contents or integrity.
Snapshot SHA-256: `a8fc056071b1d519097a2b07bcf2d7fd3678408b3124972260eb5a593718ca1c`. Reproduction: compute SHA-256 of each listed file's bytes, serialize the path-to-hash dictionary using Python `json.dumps(files, sort_keys=True, separators=(',', ':')).encode()`, then SHA-256 that serialization. These hashes identify the reviewed snapshot; they are not a digital signature or evidence of release publisher authenticity.
| Reviewed file/artifact | SHA-256 |
| --- | --- |
| `.gitignore` | `4586fa19892a2c7b5edd2f13882c6b0243e629a55b85478cdd4563fb236cf6f3` |
| `App Logo/Samsara Logo.jpg` | `469796ad788c77a8c4e5cc30e36f6884c4d76182b45d3894413554ad9d0ec421` |
| `README.md` | `ca505acd1777e7e8f2c8e025823980dc7a529bb3b291b89b0ad8c33ce3dc8986` |
| `Samsara.bundle` | `95f6c32d41f81b245c0c854210c94af6ebd7ec17c0fdcc72c49130d8fe50ce00` |
| `docs/DEVELOPMENT.md` | `9775086dd05281fd0312e00bdb756baa855057f3e268421494656e59f9a6aa88` |
| `docs/IMPLEMENTATION_PLAN.md` | `bbca88844a99de02a79d1c0515d9aacdaeb26a986fab4d85df850036862b3ab4` |
| `docs/PLATFORMS.md` | `544d0d3703bf77fe0021477f15e6290eb0aab4b4d9ab2b9cf143bf88f4246a04` |
| `docs/SCORING.md` | `81899ab358ed8a3042b9dcde04aa303df0e6762a857b9cfe6f3b56f459ff034e` |
| `powershell/Get-ServerCertificates.ps1` | `dc54aa83d7814b22319a83fca64266927ead7a53a1d2416ec12e79afe6ea4d49` |
| `powershell/Get-ServerInventory.ps1` | `cd5cea83271018370b13007e6a5ffcbc40d2a5828b58a9a6af60a8c9ebf84206` |
| `powershell/Get-ServerNetwork.ps1` | `dacee9c73e1f622e42285c920e3d0c912623bcb668a9fe2e384137923edd3caa` |
| `powershell/Get-ServerRoles.ps1` | `fa34a5d98d6bc7c78dda7dab0d0184be43d961e159c2f13a4d37a290f47e4999` |
| `powershell/Get-ServerServices.ps1` | `7a0a63c456ab21f465aaf608a36eb586021235a4abad44247100c0508384e5ff` |
| `powershell/Get-ServerSoftware.ps1` | `30e69b8cdc05c9c844b6a3c820ab22d674ef3d14a47ef0bd9c960b23c90f78d5` |
| `powershell/Get-ServerStorage.ps1` | `513c90a98e2ee7ada4be37be9c08b57488edcee47968b074dbf6d4a210478c7b` |
| `powershell/Get-ServerSystem.ps1` | `82a0bd12c30aafa7b9edfbe77d6dca655dec8019118f9290c53a22bd3657f9ea` |
| `powershell/Get-ServerTasks.ps1` | `bd716c72ec1584317702779e4ab9bfdecfc2da5616f1713d6a1ec21cb55844d0` |
| `powershell/Inventory.Common.ps1` | `4a43ebe04e1ed30f47dca3fbaa59aa2e601e7f7a6631563fddb90fe42b4264b1` |
| `powershell/README.md` | `20b9d647b9db95283f2374e6256b8acc605b61964508fe94fcf8671403dcb3e0` |
| `requirements.txt` | `a2c54b88e249231a1d295b2d69aa17bac18f310d53916a8f98eb58abfdbff210` |
| `samsara/__init__.py` | `01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b` |
| `samsara/analyzers/__init__.py` | `01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b` |
| `samsara/analyzers/assessment.py` | `019f8c1686c95a2bebacef05ed10d8029e32cf28b4d212f26cce89fcc48cb549` |
| `samsara/analyzers/dependencies.py` | `46960c00169ed9e591eb3682c126033b76859d39ddc3093005ad3b68c66ada14` |
| `samsara/analyzers/policy.py` | `68fddefc819503f5d6114567806f69c1e5c4db30922a8911f6f094c4ccce4cbf` |
| `samsara/analyzers/summary.py` | `31b66ff0270ffe1917cd5fcc72f1ce7be1159dff30c003dc205e5112e6139b67` |
| `samsara/assets/demo_inventory.json` | `106123be22212cd6f9863ee53be88a29872c52a90211920e05e4ca2d6a82e263` |
| `samsara/assets/demo_linux_inventory.json` | `480007766fc86891caec2b08d316ddbd4da72a9c6d2f71d10563770d087e2919` |
| `samsara/assets/samsara-logo.jpg` | `469796ad788c77a8c4e5cc30e36f6884c4d76182b45d3894413554ad9d0ec421` |
| `samsara/assets/scoring_policy.json` | `070b8b2ebcddb7fb7461ed74ca6d9bcc01cbacdb0cd0c681e18f0964e6a9064b` |
| `samsara/collectors/__init__.py` | `01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b` |
| `samsara/collectors/demo.py` | `d231c66ec17a732f4e0a43dd5b5b3617695fc32348a507d53afebdb81f75d3a5` |
| `samsara/collectors/importer.py` | `459282230e2cee80cbfb026e17ac9013cd20f2ba2999595fe972f310856c6e96` |
| `samsara/collectors/linux.py` | `1b5469b5a65b973f6b636236bd887bcae8b4f9d1559127bee9147ec1011ec748` |
| `samsara/collectors/linux_schedules.py` | `77c112f7904d7fd5c7cc99364edfb53417cf643a9e4b3fc50b67efa413625a61` |
| `samsara/collectors/windows.py` | `d20922cbb72c5aa1d105dcafa75ad5fa696a37730a7e29f1194503503f2e277b` |
| `samsara/core/__init__.py` | `01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b` |
| `samsara/core/detection.py` | `87d5d79b50220d82365108ae746dcc3d6b0d257cc0cb2e3a365fece02bb1efd2` |
| `samsara/core/startup.py` | `7488cb7ed8fddd96989baef52447c6d99ec1cc36d56451191c014b928c92356f` |
| `samsara/core/validation.py` | `0acf902316b6b408dcee064bf85acb5cddbe419c44a6a22bd883f11bf31bff6a` |
| `samsara/main.py` | `8f4ed1b7ca80fc3745f4ab09a9d8ace027cd64827ca98818adc1e94cfab12280` |
| `samsara/models/__init__.py` | `01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b` |
| `samsara/models/inventory.py` | `0d2e2d05fca23fde4f33003cd363f72ce72a1c7402c1e688eee01ee15eba88eb` |
| `samsara/reporting/__init__.py` | `01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b` |
| `samsara/reporting/export.py` | `248057ada2607039e9606745b72a942a9b3e3cecf15e6a918744a2ca09649a49` |
| `samsara/ui/__init__.py` | `01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b` |
| `samsara/ui/branding.py` | `9d488c96491edfdb30e9df7537b52f4e21a98c46f6616cf67de48936059215bf` |
| `samsara/ui/window.py` | `4e4a063c43b55244dce60a9a3a436652638ca54fd87be568b2f4fda032eeda56` |
| `schemas/inventory-v1.schema.json` | `e747c7c90cbd939da4d5fa4cd08993feec1d07635af1e07ef8747c264467ef11` |
| `tests/fixtures/scoring/active_file_server.json` | `ffe6ec28840320b9574ac88dcf92cf49840c5f661725abf7a284cf2e2f6928c6` |
| `tests/fixtures/scoring/active_iis_server.json` | `5a636dd1274983ac6e1841430fe5e16682282ad016be716be964539bb81e3483` |
| `tests/fixtures/scoring/active_sql_server.json` | `0e79ff728a31bb3839baaf81103b358c3a8d5a541ec9389154faf7737438dd6c` |
| `tests/fixtures/scoring/clean_windows.json` | `f80d20573af20cc646f7096e5e6e5e467e08e866dbc9280151eae58c0a35249f` |
| `tests/fixtures/scoring/domain_controller.json` | `4a1a92418d4eafd5ab80fbafa9e01f611e946fb28aa408d5ddad1141ea621c9d` |
| `tests/fixtures/scoring/inactive_game_server.json` | `183d84029bdc3c24666123c29690d676273a595e85a88bf33b414f2845c084a9` |
| `tests/fixtures/scoring/incomplete_collection.json` | `abeb6d55a6d78e0fe7f05277abb759357ad0d624929c2e1a2d8c1953671714b7` |
| `tests/fixtures/synthetic_inventory.json` | `921a7841858cd9205ece3fc8d7d18a63b76c7c0a2179dfb4ed7085fcca91b55f` |
| `tests/fixtures/windows/server-2016.json` | `d2735abdcc597b503c72889e75232ca9012b886d9a9d7a535d782d434f1341f4` |
| `tests/fixtures/windows/server-2019.json` | `0c33bab3ad781af897ff21797ac6ca63eeb41cab8e9b5c86deab1e97ac2e44f7` |
| `tests/fixtures/windows/server-2022.json` | `dae9016a891b01ffafdbd66dfc0e50d39a4a2c9fa7225188abff1f97012814ca` |
| `tests/fixtures/windows/server-2025.json` | `47ee9d459ebb165b1def7b44fe745c71c193c0626d8a1a7fba7576f091bea308` |
| `tests/powershell/Test-Collectors.ps1` | `36b4ffc7a95e21663ac956c2e2a2c6b64802441f113f2be3e56f031ef1709331` |
| `tests/test_core.py` | `308afb153858871cf627bbfdbf3522ac002d40e8a24a181c8c2153113f054cf3` |
| `tests/test_detection.py` | `7325d65fbe46b95dbf14e6e7a2fa979cbe155e4394acdfa21f27794246d5f7e6` |
| `tests/test_import.py` | `ea9f4a9bd4ea5f6a24a053b3058f37ed41050c23e4c8e54b68c00eda14d465fc` |
| `tests/test_linux.py` | `dd6960e86ea60576c78512a7f23e7b34d242947584960ad16d23e40a0ed89987` |
| `tests/test_powershell.py` | `44b7d38cbea0c732380751ff84b7a6d1f9a48e20c290e5843885d39f9ed567e5` |
| `tests/test_schedules.py` | `e8aa0b86d25ee3053d339776bb94946625ace3d404f56a30d40bc3bd4abd31fb` |
| `tests/test_scoring.py` | `a4898b8b612aea29214a391ddfb745983b2bf3be9cc170a16a7ea25e6e6f7736` |
| `tests/test_startup.py` | `1d46d1d183f7cb75998722660bc38e61d580558f8f7941b780ab3ea19f51efa4` |
| `tests/test_summary.py` | `9a87b734dc565711057abbd0fc19ebcafdabf6afe09b49d7ddc1b035c5c2ca96` |
| `tests/test_ui.py` | `3b6de4af474d326d070a0154df706a37a7f663755d46110f0859692d0d91f97e` |
| `tests/test_windows.py` | `b5076af4d95f3530c97313f607578b5f0b98262eb71fdb99e188164ae1c551a7` |
| `tools/validate_windows_host.py` | `dabfae5f7c3948e45dc4bef9d4a00138979cc2b1cf9fd13b3bbaea417aa40213` |