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
6 changes: 6 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Sentinel's Journal

## 2025-02-13 - Secure File Creation in Shell Scripts

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

View workflow job for this annotation

GitHub Actions / Lint Documentation

Headings should be surrounded by blank lines

.jules/sentinel.md:3 MD022/blanks-around-headings Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "## 2025-02-13 - Secure File Creation in Shell Scripts"] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md022.md
**Vulnerability:** SSH private keys were created with default umask (often 022, resulting in 644/world-readable) before being restricted with `chmod 600`. This created a race condition where the key was briefly readable by other users.

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: 235] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md
**Learning:** Shell redirection (`>`) and `mkdir` adhere to the process's `umask` at the time of execution. `chmod` after creation leaves a window of vulnerability.

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

View workflow job for this annotation

GitHub Actions / Lint Documentation

Line length

.jules/sentinel.md:5:81 MD013/line-length Line length [Expected: 80; Actual: 164] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md
**Prevention:** Use `(umask 077 && mkdir ...)` for directories and `(umask 077; command > file)` for files to ensure atomic secure permissions. Remove existing files before writing if sensitive to ensure new inode creation with correct permissions.

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

View workflow job for this annotation

GitHub Actions / Lint Documentation

Line length

.jules/sentinel.md:6:81 MD013/line-length Line length [Expected: 80; Actual: 248] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md
Comment on lines +3 to +6
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 markdown lint failures flagged by CI.

The documentation lint check is failing with:

  1. MD022 (Line 3): Missing blank line below the ## heading.
  2. MD013 (Lines 4–6): Lines exceed the 80-character limit.

Also, the date reads 2025-02-13 β€” should this be 2026-02-13 to match the PR date?

Proposed fix
-## 2025-02-13 - Secure File Creation in Shell Scripts
-**Vulnerability:** SSH private keys were created with default umask (often 022, resulting in 644/world-readable) before being restricted with `chmod 600`. This created a race condition where the key was briefly readable by other users.
-**Learning:** Shell redirection (`>`) and `mkdir` adhere to the process's `umask` at the time of execution. `chmod` after creation leaves a window of vulnerability.
-**Prevention:** Use `(umask 077 && mkdir ...)` for directories and `(umask 077; command > file)` for files to ensure atomic secure permissions. Remove existing files before writing if sensitive to ensure new inode creation with correct permissions.
+## 2026-02-13 - Secure File Creation in Shell Scripts
+
+**Vulnerability:** SSH private keys were created with default umask
+(often 022, resulting in 644/world-readable) before being restricted
+with `chmod 600`. This created a race condition where the key was
+briefly readable by other users.
+
+**Learning:** Shell redirection (`>`) and `mkdir` adhere to the
+process's `umask` at the time of execution. `chmod` after creation
+leaves a window of vulnerability.
+
+**Prevention:** Use `(umask 077 && mkdir ...)` for directories and
+`(umask 077; command > file)` for files to ensure atomic secure
+permissions. Remove existing files before writing if sensitive to
+ensure new inode creation with correct permissions.
πŸ“ 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
## 2025-02-13 - Secure File Creation in Shell Scripts
**Vulnerability:** SSH private keys were created with default umask (often 022, resulting in 644/world-readable) before being restricted with `chmod 600`. This created a race condition where the key was briefly readable by other users.
**Learning:** Shell redirection (`>`) and `mkdir` adhere to the process's `umask` at the time of execution. `chmod` after creation leaves a window of vulnerability.
**Prevention:** Use `(umask 077 && mkdir ...)` for directories and `(umask 077; command > file)` for files to ensure atomic secure permissions. Remove existing files before writing if sensitive to ensure new inode creation with correct permissions.
## 2026-02-13 - Secure File Creation in Shell Scripts
**Vulnerability:** SSH private keys were created with default umask
(often 022, resulting in 644/world-readable) before being restricted
with `chmod 600`. This created a race condition where the key was
briefly readable by other users.
**Learning:** Shell redirection (`>`) and `mkdir` adhere to the
process's `umask` at the time of execution. `chmod` after creation
leaves a window of vulnerability.
**Prevention:** Use `(umask 077 && mkdir ...)` for directories and
`(umask 077; command > file)` for files to ensure atomic secure
permissions. Remove existing files before writing if sensitive to
ensure new inode creation with correct permissions.
🧰 Tools
πŸͺ› GitHub Check: Lint Documentation

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


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


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


[failure] 3-3: Headings should be surrounded by blank lines
.jules/sentinel.md:3 MD022/blanks-around-headings Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "## 2025-02-13 - Secure File Creation in Shell Scripts"] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md022.md

πŸ€– Prompt for AI Agents
In @.jules/sentinel.md around lines 3 - 6, Update the markdown to satisfy lint
rules: change the heading date from "2025-02-13" to "2026-02-13", add a blank
line immediately after the "## 2026-02-13 - Secure File Creation in Shell
Scripts" heading to fix MD022, and reflow the long lines in the three following
bullet paragraphs so no line exceeds 80 characters (split sentences or reorder
phrases) to fix MD013 while preserving the original content about umask,
redirection, mkdir and chmod; ensure the examples `(umask 077 && mkdir ...)` and
`(umask 077; command > file)` remain intact.

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

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

# Create SSH directory
mkdir -p "$SSH_DIR"
# Create SSH directory with secure permissions
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"
# Remove existing files to ensure new files are created with correct permissions
rm -f "$PRIVATE_KEY_FILE" "$PUBLIC_KEY_FILE"

# Read private key from 1Password and save locally with secure permissions
# usage of subshell with umask 077 ensures file is created with 600 permissions
(
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