-
Notifications
You must be signed in to change notification settings - Fork 1
fix(ci): bump actions to latest versions (setup-python v7.0.0, trufflehog v3.96.0, pypi-publish v1.14.2) #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
19a61f6
78da046
0c72d46
1dc7bc7
02a3e06
1cc48a0
398cffe
c39a55e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ^tests/.* | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ | |
|
|
||
| from __future__ import annotations | ||
|
|
||
| import contextlib | ||
| import json | ||
| import os | ||
| from cryptography.hazmat.primitives.ciphers.aead import AESGCM | ||
|
|
@@ -65,11 +66,27 @@ def _load(self) -> None: | |
| ) from exc | ||
|
|
||
| def _save(self) -> None: | ||
| """Atomically write the keystore to disk. | ||
|
|
||
| Uses a temp file + os.replace so that a crash or disk-full mid-write | ||
| never truncates the existing store. The previous file remains intact | ||
| until the replacement is fully written. | ||
| """ | ||
| plaintext = json.dumps(self._entries, indent=2, default=str).encode("utf-8") | ||
| nonce = os.urandom(12) | ||
| ciphertext = self._aesgcm.encrypt(nonce, plaintext, None) | ||
| self._store_path.write_bytes(nonce + ciphertext) | ||
| os.chmod(str(self._store_path), 0o600) | ||
| data = nonce + ciphertext | ||
|
|
||
| tmp_path = self._store_path.with_suffix(self._store_path.suffix + ".tmp") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When two threads or CLI processes save the same keystore concurrently, both write Useful? React with 👍 / 👎. |
||
| try: | ||
| tmp_path.write_bytes(data) | ||
| os.chmod(str(tmp_path), 0o600) | ||
| os.replace(str(tmp_path), str(self._store_path)) | ||
|
Comment on lines
+82
to
+84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When the machine or filesystem crashes after Useful? React with 👍 / 👎. |
||
| except BaseException: | ||
| # Clean up the temp file on any failure so we don't leak .tmp files. | ||
| with contextlib.suppress(OSError): | ||
| tmp_path.unlink(missing_ok=True) | ||
| raise | ||
|
|
||
| def get_all(self) -> dict[str, dict[str, Any]]: | ||
| """Return all stored entries.""" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pattern excludes the entire
tests/tree from the TruffleHog step configured in.github/workflows/ci.yml, so any genuine credential accidentally committed in a test or fixture will pass the security job undetected. Since the reported false positive is confined to one location intests/test_keystore_atomic.py, narrow the suppression to that specific finding instead of disabling secret scanning for all test code.Useful? React with 👍 / 👎.