Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## 2024-05-22 - TOCTOU Race Condition in File Permissions

Check failure on line 1 in .jules/sentinel.md

View workflow job for this annotation

GitHub Actions / Lint Documentation

First line in a file should be a top-level heading

.jules/sentinel.md:1 MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "## 2024-05-22 - TOCTOU Race Co..."] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md041.md

Check failure on line 1 in .jules/sentinel.md

View workflow job for this annotation

GitHub Actions / Lint Documentation

Headings should be surrounded by blank lines

.jules/sentinel.md:1 MD022/blanks-around-headings Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "## 2024-05-22 - TOCTOU Race Condition in File Permissions"] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md022.md
**Vulnerability:** SSH private keys were written to disk with default permissions and then restricted with `chmod` immediately after. This creates a Time-of-Check-Time-of-Use (TOCTOU) race condition window where the file is world-readable (depending on system umask).

Check failure on line 2 in .jules/sentinel.md

View workflow job for this annotation

GitHub Actions / Lint Documentation

Line length

.jules/sentinel.md:2:81 MD013/line-length Line length [Expected: 80; Actual: 267] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md
**Learning:** `chmod` is not atomic with file creation. Relying on it for sensitive files leaves a security gap.

Check failure on line 3 in .jules/sentinel.md

View workflow job for this annotation

GitHub Actions / Lint Documentation

Line length

.jules/sentinel.md:3:81 MD013/line-length Line length [Expected: 80; Actual: 112] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md
**Prevention:** Use `umask` in a subshell or the `install` command (if portable) to ensure files are created with restrictive permissions from the start. Example: `(umask 077; echo secret > file)`

Check failure on line 4 in .jules/sentinel.md

View workflow job for this annotation

GitHub Actions / Lint Documentation

Line length

.jules/sentinel.md:4:81 MD013/line-length Line length [Expected: 80; Actual: 196] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md
Comment on lines +1 to +4
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟑 Minor

Fix markdownlint violations flagged by the Lint Documentation check.

The linter reports several failures:

  1. MD041: First line should be a top-level heading (#), not ##.
  2. MD022: Heading must be surrounded by blank lines.
  3. MD013: Lines 2–4 exceed the 80-character limit β€” wrap long lines or restructure into shorter sentences.

Also, the date 2024-05-22 looks incorrect given the PR was created on 2026-02-06.

Proposed structure (content abbreviated)
-## 2024-05-22 - TOCTOU Race Condition in File Permissions
-**Vulnerability:** SSH private keys were written to disk with default permissions and then restricted with `chmod` immediately after. This creates a Time-of-Check-Time-of-Use (TOCTOU) race condition window where the file is world-readable (depending on system umask).
-**Learning:** `chmod` is not atomic with file creation. Relying on it for sensitive files leaves a security gap.
-**Prevention:** Use `umask` in a subshell or the `install` command (if portable) to ensure files are created with restrictive permissions from the start. Example: `(umask 077; echo secret > file)`
+# Sentinel Security Journal
+
+## 2026-02-06 - TOCTOU Race Condition in File Permissions
+
+**Vulnerability:** SSH private keys were written to disk with default
+permissions and then restricted with `chmod` immediately after. This
+creates a TOCTOU race condition window where the file is
+world-readable (depending on system umask).
+
+**Learning:** `chmod` is not atomic with file creation. Relying on it
+for sensitive files leaves a security gap.
+
+**Prevention:** Use `umask` in a subshell or the `install` command
+(if portable) to ensure files are created with restrictive permissions
+from the start. Example: `(umask 077; echo secret > file)`
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## 2024-05-22 - TOCTOU Race Condition in File Permissions
**Vulnerability:** SSH private keys were written to disk with default permissions and then restricted with `chmod` immediately after. This creates a Time-of-Check-Time-of-Use (TOCTOU) race condition window where the file is world-readable (depending on system umask).
**Learning:** `chmod` is not atomic with file creation. Relying on it for sensitive files leaves a security gap.
**Prevention:** Use `umask` in a subshell or the `install` command (if portable) to ensure files are created with restrictive permissions from the start. Example: `(umask 077; echo secret > file)`
# Sentinel Security Journal
## 2026-02-06 - TOCTOU Race Condition in File Permissions
**Vulnerability:** SSH private keys were written to disk with default
permissions and then restricted with `chmod` immediately after. This
creates a TOCTOU race condition window where the file is
world-readable (depending on system umask).
**Learning:** `chmod` is not atomic with file creation. Relying on it
for sensitive files leaves a security gap.
**Prevention:** Use `umask` in a subshell or the `install` command
(if portable) to ensure files are created with restrictive permissions
from the start. Example: `(umask 077; echo secret > file)`
🧰 Tools
πŸͺ› GitHub Check: Lint Documentation

[failure] 4-4: Line length
.jules/sentinel.md:4:81 MD013/line-length Line length [Expected: 80; Actual: 196] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md


[failure] 3-3: Line length
.jules/sentinel.md:3:81 MD013/line-length Line length [Expected: 80; Actual: 112] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md


[failure] 2-2: Line length
.jules/sentinel.md:2:81 MD013/line-length Line length [Expected: 80; Actual: 267] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md


[failure] 1-1: First line in a file should be a top-level heading
.jules/sentinel.md:1 MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "## 2024-05-22 - TOCTOU Race Co..."] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md041.md


[failure] 1-1: Headings should be surrounded by blank lines
.jules/sentinel.md:1 MD022/blanks-around-headings Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "## 2024-05-22 - TOCTOU Race Condition in File Permissions"] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md022.md

πŸ€– Prompt for AI Agents
In @.jules/sentinel.md around lines 1 - 4, Change the first line to a top-level
heading (use a single leading '#') and ensure there is a blank line before and
after that heading to satisfy MD041 and MD022; break the long lines in the body
(lines mentioning the TOCTOU race, chmod, umask example) into sentences under 80
characters to fix MD013; update the date string "2024-05-22" to "2026-02-06" and
keep the heading text "TOCTOU Race Condition in File Permissions" intact so
reviewers can locate the entry.

16 changes: 12 additions & 4 deletions tools/setup-ssh-keys.sh
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,20 @@ cmd_restore() {

say "Restoring SSH key from 1Password..."

# Create SSH directory
mkdir -p "$SSH_DIR"
# Create SSH directory securely
if [[ ! -d "$SSH_DIR" ]]; then
(
umask 077
mkdir -p "$SSH_DIR"
)
fi
chmod 700 "$SSH_DIR"

# Read private key from 1Password and save locally
op read "op://$VAULT/$KEY_NAME/private_key" > "$PRIVATE_KEY_FILE"
# Read private key from 1Password and save locally securely
(
umask 077
op read "op://$VAULT/$KEY_NAME/private_key" > "$PRIVATE_KEY_FILE"
)
chmod 600 "$PRIVATE_KEY_FILE"

# Read public key from 1Password and save locally
Expand Down
Loading