Skip to content

Harden the token store, macOS signing, the release integrity check and the MSI check - #216

Merged
Gorka Gonzalo (d0ubl3g) merged 7 commits into
devfrom
fix/codex-2026-10-21
Oct 21, 2026
Merged

Gorka Gonzalo (d0ubl3g) merged 7 commits into
devfrom
fix/codex-2026-10-21

Conversation

@d0ubl3g

Copy link
Copy Markdown
Contributor

Hardening from a security scan of the release and sign-in code.

  • Plain-text token store on macOS: mode bits do not cover extended ACLs, which a folder can pass on to what is created in it. The sessions directory and the token file are now stripped of any ACL when the CLI creates them, and one that already carries an ACL is refused. On Linux, chmod 600 sets the POSIX ACL mask to no access, so no change is needed there.
  • macOS signing: the Developer ID certificates must belong to an expected Apple Team ID, which is repository policy (MACOS_TEAM_ID in release.yml and macos-signing-check.yml). It is compared exactly with the binary's TeamIdentifier and the installer certificate. The value is empty for now, so macOS signing fails closed until it is set.
  • Release integrity check: the files that must carry a Sigstore bundle are now SHA256SUMS, every file it lists, and every archive or installer, whichever bundles are attached. A deleted bundle is reported.
  • MSI check before signing: msiexec /a runs the package's administrative sequence. The check now:
    • accepts only the tables and the standard actions of the published package;
    • pins the registry and PATH rows;
    • fails closed on any read error;
    • compares LICENSE, NOTICE and USER-INFORMATION.md with the repository copies.
  • Stops tracking a compiled Python cache file and ignores __pycache__/.

The integrity check derived the files to authenticate from the bundles
attached to the release, so removing a bundle together with replacing
its file went unnoticed as long as one bundle remained. The required
set is now SHA256SUMS, every file it lists and every attached archive
or installer, whichever bundles are present; a missing bundle is
reported.

Signed-off-by: d0ubl3g <48954024+d0ubl3g@users.noreply.github.com>
The signing steps accepted any Developer ID certificate with a
TeamIdentifier, and never read the installer certificate's team. The
expected Team ID is now a constant in the workflows, compared exactly
with the binary's TeamIdentifier and the installer certificate's Team
ID. An empty or malformed value fails the first step. The constant is
empty until a maintainer sets it.

Signed-off-by: d0ubl3g <48954024+d0ubl3g@users.noreply.github.com>
The administrative extraction of the MSI runs AdminExecuteSequence, so
standard actions such as SelfRegModules could load a DLL shipped under
the name of a payload file. The check now also refuses the tables that
make such actions load payload code, requires every action of the
administrative sequences to be a passive standard action, and compares
LICENSE, NOTICE and USER-INFORMATION.md with the repository's copies by
SHA-256. The signing job now checks out the commit for that comparison.

Signed-off-by: d0ubl3g <48954024+d0ubl3g@users.noreply.github.com>
The MSI check now reads _Tables once and refuses any table the package
does not use, reads every row without swallowing errors, allows only the
standard actions seen in each sequence (as a subset) and pins the
Registry and Environment rows to the InstallDir value and the PATH entry.

Signed-off-by: d0ubl3g <48954024+d0ubl3g@users.noreply.github.com>
Mode bits do not cover NFSv4-style ACLs, which a parent folder can pass
on to the sessions directory and the token file. On macOS the CLI now
removes any ACL from the directory and the temporary file it creates,
before a token is written, and refuses an existing directory or file
that has one. On Linux a POSIX ACL is limited by the mask that chmod 600
sets, so nothing changes there.

Signed-off-by: d0ubl3g <48954024+d0ubl3g@users.noreply.github.com>
It was committed by accident; __pycache__/ is now ignored.

Signed-off-by: d0ubl3g <48954024+d0ubl3g@users.noreply.github.com>
…-0383

rustls-webpki 0.103.16 rejects certificate paths through the distrusted intermediates, and
webpki-root-certs 1.0.10 drops the root that issued them.

Signed-off-by: d0ubl3g <48954024+d0ubl3g@users.noreply.github.com>
@d0ubl3g
Gorka Gonzalo (d0ubl3g) merged commit 82ae954 into dev Oct 21, 2026
42 checks passed
@d0ubl3g
Gorka Gonzalo (d0ubl3g) deleted the fix/codex-2026-10-21 branch October 21, 2026 11:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant