ClickNick 0.23.4 trust report
Generated 2026-10-11 20:21 UTC from uv.lock at commit 7523f965fc8c.
This file is self-contained: no scripts, no external resources. Latest reports and the explanation of this
format: pyrung.com/clicknick/security.
All release checks passed.
For IT / security review
The narrative below comes from docs/security/index.md in this
report's source checkout. It describes intended behavior; the generated checks below provide
release-specific evidence, not a formal security audit.
ClickNick is a Windows desktop tool that reads and edits CLICK projects and adds nickname autocomplete to CLICK Programming Software.
ClickNick was written with security in mind: keep dependencies limited, prefer pure Python where practical, run without administrator rights, and make the software's behavior easy to inspect.
This page describes its file access, network connections, code execution, and installation for IT and security review. ClickNick is open source (AGPL-3.0), written and maintained by one author.
Each release includes a trust report and dependency inventory, generated from the release source, built package, and dependency lock file. These are release checks, not a formal security audit. A static scan shows what the code contains; it cannot prove what it never does.
Software characteristics
ClickNick installs no Windows services, drivers, or scheduled tasks. It has no telemetry, analytics, or automatic update agent. Updates are initiated by the user.
ClickNick's own package is readable Python source, with no obfuscated or encrypted modules, packed executables, or compiled code. Its installation also includes a Python interpreter and dependencies with native binaries, identified in the release report. Source code for every dependency is publicly available.
The default uv installation stays under the user's profile. Project exports and durable workspaces are written to the folders the user chooses.
Runtime behavior
- Project database access. ClickNick reads and writes
SC_.mdbin the temporary folder CLICK creates when it opens a project. It uses Windows ODBC, or a 32-bit PowerShell worker using the Windows Jet engine when a 64-bit Access driver is unavailable. - Autocomplete. ClickNick reads and fills text fields in CLICK Programming Software
through standard Windows APIs, then sends Enter, Tab, or Escape after a nickname is
selected. It installs no keyboard hook and injects no code into
Click.exe. - Editor command listener. While ClickNick is running,
clicknick-clican connect to its local TCP port to read or stage address edits, check workspace code, and apply ladder proposals. This listener runs even when the offline console is closed. It binds tolocalhost, with the port chosen by Windows. Connections are unauthenticated, and ClickNick does not check the connecting process's user identity. Other local users and processes that can reach the port can connect. Address edits are staged and undoable; they reach the project when the user saves. - PLC connection. The Dataview editor connects over Modbus TCP (port 502 by default) after the user asks to go live, to the address they enter. It reads values and writes values when the user clicks Write.
- Generated Python. On project connection, ClickNick translates the ladder into Python and runs the generated code in-process to build the model behind Check Program. This step does not run files found in the project folder.
- Workspace Python. Check Program, applying a proposal, and the offline console run
the user's editable workspace (
src/plc,run.py,project_to_csv.py) in a child Python process. Thetag applycommand executes workspacetags.pyinside ClickNick to export its nickname changes. These are intentional code execution features, with the signed-in user's permissions. Treat a workspace received from outside like any other script folder. - Documentation links. Clicking a documentation link opens
github.comorpyrung.comin the default browser.
ClickNick has no background internet connection for telemetry or updates. Installation downloads are described below; workspace scripts can perform whatever file or network operations their code requests.
What endpoint monitoring will see
The paths below describe the default uv installation.
| Event | Cause |
|---|---|
Unsigned clicknick.exe in %USERPROFILE%\.local\bin starts Python from %APPDATA%\uv\tools\clicknick\ |
Normal launch. uv generates the small entry-point launcher; ClickNick runs as python.exe or pythonw.exe. |
Python starts SysWOW64\...\powershell.exe -EncodedCommand ... |
The Jet database worker, on machines without a 64-bit Access driver. The full command and script identity are below. |
Python listening on 127.0.0.1:<random port> |
The editor command listener for clicknick-cli; the offline console uses a separate pyrung live connection for simulation. |
| Python starts a child Python process | Check Program, applying a proposal, or the offline console running the user's workspace. |
Python connects to <PLC address>:502 |
Dataview editor, after the user asks to go live. |
Native .pyd, .dll, and .exe files appear under %APPDATA%\uv\ |
The Python interpreter and dependencies such as pywin32 and pyodbc. pywin32 includes Pythonwin.exe and pythonservice.exe; ClickNick does not run them. |
HKCU\Environment PATH changed |
The uv installer adds its executable directory to the user's PATH. |
The database worker's command line is:
%SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -NoLogo -NoProfile -NonInteractive -EncodedCommand <base64>
The payload is the text of the shipped clicknick/resources/jet_sidecar.ps1 script,
with line endings normalized to LF, encoded as UTF-16LE and then Base64. Each release
report includes the shipped file's SHA256 for review. Project paths and values travel
separately as JSON on standard input; they are not inserted into PowerShell source.
The encoded invocation keeps the worker usable under Windows PowerShell's Restricted
execution policy, which permits commands but blocks script files invoked with -File.
It does not change execution policy or relax application-control rules. Endpoint tools
may flag the invocation; any exception depends on the controls in use. To use Access ODBC
without falling back to PowerShell, start clicknick --db-backend odbc. The
--db-backend none option uses CSV mode without either database backend.
Installation and updates
uv is an open-source Python package manager from Astral. For ClickNick, it downloads the package and dependencies from PyPI, installs them in an isolated environment, and creates the launcher. It also downloads a Python interpreter if needed. ClickNick does not call uv at runtime.
Installation and upgrades use these hosts:
| Purpose | Hosts |
|---|---|
| uv installer | astral.sh |
| Python builds from python-build-standalone | github.com, objects.githubusercontent.com |
| ClickNick and Python dependencies | pypi.org, files.pythonhosted.org |
uv checks package files against hashes published by PyPI and Python downloads against hashes built into uv. Installing ClickNick's wheel unpacks files; the wheel has no install-time scripts.
If a script piped into PowerShell is against policy, install uv with
winget install --id astral-sh.uv. If your policy prefers pip, install ClickNick into a
virtual environment using Python 3.11 or newer. See Install.
To update: uv tool upgrade clicknick.
ClickNick pins its whole dependency tree to exact versions, so installing a given ClickNick
version installs exactly the dependency versions in that release's report. Dependency
updates, including security fixes, arrive only through a new ClickNick release, and every
release runs uv audit before it ships.
Where things live on disk
Default locations for an installation through uv:
| Item | Location |
|---|---|
| uv itself | %USERPROFILE%\.local\bin\uv.exe |
| Python interpreter downloaded by uv | %APPDATA%\uv\python\ |
| ClickNick and its dependencies | %APPDATA%\uv\tools\clicknick\ |
| Launcher stub | %USERPROFILE%\.local\bin\clicknick.exe |
| uv download cache | %LOCALAPPDATA%\uv\cache\ |
| Live-session files | The CLICK temp folder for the open project, or %LOCALAPPDATA%\ClickNick\live\. CLICK does not read these files. |
| Generated engineering workspace | %TEMP%\clicknick_* while running, or the folder the user chooses for a durable workspace |
| Project data it edits | SC_.mdb in %LOCALAPPDATA%\Temp\CLICK (...)\. CLICK writes it back into the .ckp on save. |
Uninstall
uv tool uninstall clicknick
This removes ClickNick's tool environment and launchers. User-saved workspaces and exports remain in their chosen folders.
uv, its downloaded Python interpreters, and its cache remain available for other tools.
Removing %APPDATA%\uv\ also removes other uv tool environments and shared Python builds.
Remove those shared directories only if you are retiring uv and all tools that use them;
the same applies to removing %USERPROFILE%\.local\bin from PATH, since other commands may
live there.
Reporting a problem
Report security issues through the repository's private vulnerability reporting form. For other problems, open an issue. Include the release version and its trust report.
Release summary
| Release | ClickNick 0.23.4 |
| Python | >=3.11,<4.0 |
| Runtime distributions | 11 |
| First-party | 4 |
| Third-party | 7 |
| Known vulnerabilities | 0 (10 dependencies audited against the advisory database; ClickNick itself is the package being built) |
| Non-PyPI third-party dependencies | 0 |
| Unresolved licenses | 0 |
| SBOM SHA256 (clicknick-sbom-0.23.4.cyclonedx.json) | 0580d8d8f7c352dcd725cb39c53afa50b9ce6ea90687678122a4d9111b8e68a1 |
| Wheel SHA256 (clicknick-0.23.4-py3-none-any.whl) | 10f71d0b3a1f13e0ce438d42bdee73926ade9be22b96e1069d4794c8d92bc67a |
| PowerShell worker SHA256 (clicknick/resources/jet_sidecar.ps1) | 763e4e76efbd6dd7631411e3f819d9511ffc1011285f80332c0db7530d209347 |
| Generated from | uv.lock, exported as CycloneDX 1.5 by uv 0.12.1 |
| Source commit | 7523f965fc8c6ef70d8331aa7bcfdc5b4758264f |
Release checks
- ✓ All third-party dependencies come from PyPI10 distributions, all from pypi.org
- ✓ Every runtime distribution has a resolved licenselicense expression or classifier found for each
- ✓ Every runtime distribution has a documented purposepurpose column filled from PURPOSES in devtools/trust_report.py
- ✓ Every runtime distribution is pinned exactly in pyproject.toml to its locked version10 distributions pinned with ==; a fresh install matches this table
- ✓ No known vulnerabilities (uv audit)advisory database reports none for the runtime set
- ✓ Wheel contains no compiled code or executables125 files: 4 (none), 3 .md, 6 .png, 1 .ps1, 109 .py, 1 .txt, 1 .typed
- ✓ No HTTP client dependency (requests, httpx, aiohttp, urllib3, ...)none of the known HTTP client packages in the runtime set
- ✓ No telemetry or analytics SDK dependencynone of the known telemetry SDKs in the runtime set
- ✓ No HTTP, FTP or mail client imports in runtime sourceno urllib.request, http.client, ftplib, smtplib or third-party HTTP imports
- ✓ No external runtime endpointsevery URL in runtime source points at github.com or pyrung.com (browser links, listed below)
- ✓ Local listeners bind to localhost onlysrc/clicknick/live/server.py:295 (localhost)
- ✓ Subprocesses launch only the same Python interpreter or the built-in Windows PowerShell4 launch sites, all sys.executable or powershell_path()
- ✓ No download commands in shipped scriptsno Invoke-WebRequest, WebClient, BitsTransfer, curl or wget
- ✓ No Python decoded at runtime (base64/zlib/marshal fed to exec/eval/compile)no module both decodes a blob and executes it; the PowerShell worker is Base64 of a shipped .ps1, hashed above
Runtime dependencies
Every distribution that uv tool install clicknick==0.23.4 installs. ClickNick pins its
whole runtime tree exactly (the "Pin" column), so a fresh install matches this table and the SBOM; a release check
below confirms the pins match uv.lock. "Used by" names the package that needs it. "First-party" means
written by the ClickNick author. "Native code" reflects the Windows x64 wheels installed in the build environment.
| Package | Version | Pin | Source | License | Used by | Native code | Purpose |
|---|---|---|---|---|---|---|---|
| clicknick | 0.23.4 | This release | AGPL-3.0 | no | Application | ||
| executing | 2.2.1 | ==2.2.1 | PyPI | MIT | pyrung | no | Python source introspection (used by pyrung) |
| laddercodec | 0.2.2 | ==0.2.2 | First-party | MPL-2.0 | ClickNick | no | Ladder diagram codec (read/write CLICK ladder) |
| pyclickplc | 0.4.0 | ==0.4.0 | First-party | MIT | ClickNick, pyrung | no | CLICK project formats, address model, Modbus access |
| pymodbus | 3.12.1 | ==3.12.1 | PyPI | BSD-3-Clause | pyclickplc | no | Modbus TCP protocol (used by pyclickplc) |
| pyodbc | 5.3.0 | ==5.3.0 | PyPI | MIT | ClickNick | yes (1 .pyd) | ODBC access to the CLICK project database |
| pyrsistent | 0.20.0 | ==0.20.0 | PyPI | MIT | pyrung | yes (1 .pyd) | Immutable data structures (used by pyrung) |
| pyrung | 0.15.2 | ==0.15.2 | First-party | MPL-2.0 | ClickNick | no | PLC program model: offline run and static checks |
| pywin32 | 311 | ==311 | PyPI | PSF | ClickNick | yes (6 .dll, 2 .exe, 49 .pyd) | Windows API (window detection, overlay placement) |
| tksheet | 7.6.0 | ==7.6.0 | PyPI | MIT | ClickNick | no | Spreadsheet widget for the Address Editor |
| tomlkit | 0.15.1 | ==0.15.1 | PyPI | MIT | pyrung | no | TOML editing that preserves formatting for check settings (used by pyrung) |
Dependency tree
clicknick 0.23.4
executing 2.2.1
laddercodec 0.2.2
pyclickplc 0.4.0
pymodbus 3.12.1
pymodbus 3.12.1
pyodbc 5.3.0
pyrsistent 0.20.0
pyrung 0.15.2
executing 2.2.1
pyclickplc 0.4.0
pyrsistent 0.20.0
tomlkit 0.15.1
pywin32 311
tksheet 7.6.0
tomlkit 0.15.1
Source transparency
Evidence behind the release checks, listed so a reviewer can look at the exact lines.
URLs in runtime source
Every URL found in a string literal of the runtime code (comments and docstrings excluded). All of these are opened in the user's browser on click or shown as help text. None is contacted by ClickNick.
| File | URL |
|---|---|
| src/clicknick/app.py:1713 | https://github.com/ssweber/clicknick |
| src/clicknick/app.py:1717 | https://github.com/ssweber/clicknick/issues |
| src/clicknick/views/dialogs.py:192 | https://github.com/ssweber/clicknick |
| src/clicknick/views/dialogs.py:199 | https://github.com/ssweber/clicknick/issues |
| src/clicknick/views/dialogs.py:397 | https://pyrung.com/clicknick/help/#database-connection |
| src/clicknick/views/dialogs.py:208 | https://pyrung.com/clicknick/help/#database-connection |
| src/clicknick/views/dialogs.py:272 | https://pyrung.com/clicknick/help/#database-connection |
Subprocess launch sites
| Location | Program |
|---|---|
| src/clicknick/live/rung_commands.py:817 | sys.executable |
| src/clicknick/services/dap_service.py:375 | sys.executable |
| src/clicknick/services/program_check.py:89 | sys.executable |
| src/clicknick/utils/jet_sidecar.py:137 | str(powershell_path()) |
Dynamic code execution
Every exec or eval call in runtime code. Each one runs Python that ClickNick
generated from the user's own ladder project, or files from the user's project workspace. Nothing downloaded,
nothing decoded.
| Location | Call |
|---|---|
| src/clicknick/live/tag_commands.py:318 | exec(compile(tags_source, 'src/plc/tags.py', 'exec'), ns) |
| src/clicknick/services/analysis_service.py:276 | exec(compile(code, '<analysis>', 'exec'), namespace) |
Verify it yourself
Rebuild from a clean checkout of the tagged release using its own build recipe. Build dependencies are pinned in pyproject.toml; Hatch supplies stable timestamps when SOURCE_DATE_EPOCH is unset, and Git attributes select LF checkout line endings. Compare the rebuilt wheel's SHA256 with this report to verify that its bytes match. Older release tags retain their original settings.
git clone https://github.com/ssweber/clicknick cd clicknick git checkout v0.23.4 uv export --frozen --no-dev --format cyclonedx1.5 # the dependency list in this report uv audit --frozen --no-dev --no-group docs # the vulnerability check uv build certutil -hashfile dist\clicknick-0.23.4-py3-none-any.whl SHA256 uv run python devtools/trust_report.py # regenerate this page into dist/trust/
To check the copy that was installed: uv tool dir shows the install folder; the wheel's files are
unpacked there, and pip download clicknick==0.23.4 --no-deps fetches the exact wheel
from PyPI for hashing. To install this exact version rather than the latest:
uv tool install clicknick==0.23.4.