Skip to content

Commit 97a9b35

Browse files
locus313Copilot
andauthored
Add support for using github api (#2)
* Add support for using github api * remove then * add error check Co-authored-by: Copilot <[email protected]> * update log message * update log message * move curl fetch into helper function * readme updates * add unsupported method error message Co-authored-by: Copilot <[email protected]> * improve error message Co-authored-by: Copilot <[email protected]> * move log_message function --------- Co-authored-by: Copilot <[email protected]>
1 parent f879bb2 commit 97a9b35

File tree

2 files changed

+72
-19
lines changed

2 files changed

+72
-19
lines changed

README.md

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,48 @@
22

33
This Bash script pulls `authorized_keys` files from remote URLs and updates SSH access for multiple local users.
44

5-
## Features
5+
## 🔧 Features
66

7-
- Pull-based, no Git required
7+
- Pull-based (ideal for cron or systemd timer)
88
- Supports multiple users
9-
- Designed for use with cron or systemd
9+
- Works with:
10+
- ✅ Public URLs (method: `raw`)
11+
- ✅ Private GitHub repositories via GitHub API (method: `api`, requires token)
12+
- Safe: Only updates keys if they’ve changed
13+
- Logs activity per user
14+
15+
## ⚙️ Configuration
16+
17+
Edit the `USER_KEYS` associative array in `sync-ssh-keys.sh` to define users and their key sources.
18+
Each entry uses the format:
19+
`["username"]="method:url"`
20+
21+
- **raw:** Fetches directly from a public URL.
22+
- **api:** Fetches from a private GitHub repo using the GitHub API (requires `GITHUB_TOKEN` environment variable).
23+
24+
**Example:**
25+
```bash
26+
declare -A USER_KEYS=(
27+
["ubuntu"]="raw:https://example.com/ssh-keys/ubuntu.authorized_keys"
28+
["devuser"]="api:https://api.github.com/repos/yourorg/ssh-keys/contents/keys/devuser.authorized_keys?ref=main"
29+
)
30+
```
1031

1132
## Usage
1233

1334
1. Edit the `USER_KEYS` array in `sync-ssh-keys.sh` to define users and their key URLs.
14-
2. Add to root's crontab:
35+
2. If using the `api` method, export your GitHub token:
36+
```bash
37+
export GITHUB_TOKEN=your_token_here
38+
```
39+
3. Add to root's crontab:
1540

1641
```cron
1742
*/15 * * * * /usr/local/bin/sync-ssh-keys.sh >> /var/log/ssh-key-sync.log 2>&1
1843
```
1944

45+
## Implementation Notes
46+
47+
- The script uses a helper function `fetch_key_file` to fetch keys using the appropriate method.
48+
- Only updates a user's `authorized_keys` if the remote file has changed.
49+
- Logs all actions with timestamps.

sync-ssh-keys.sh

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ set -euo pipefail
33

44
# === Configuration: user -> remote key file URL ===
55
declare -A USER_KEYS=(
6-
["ubuntu"]="https://example.com/ssh-keys/ubuntu.authorized_keys"
7-
["devuser"]="https://example.com/ssh-keys/devuser.authorized_keys"
8-
["admin"]="https://example.com/ssh-keys/admin.authorized_keys"
6+
["ubuntu"]="raw:https://example.com/ssh-keys/ubuntu.authorized_keys"
7+
["devuser"]="api:https://api.github.com/repos/yourorg/ssh-keys/contents/keys/devuser.authorized_keys?ref=main"
8+
["admin"]="api:https://api.github.com/repos/yourorg/ssh-keys/contents/keys/admin.authorized_keys?ref=main"
99
)
1010

1111
log_message() {
@@ -14,12 +14,34 @@ log_message() {
1414
echo "$TIMESTAMP: $1"
1515
}
1616

17+
fetch_key_file() {
18+
local METHOD="$1"
19+
local URL="$2"
20+
local OUTFILE="$3"
21+
22+
if [[ "$METHOD" == "raw" ]]; then
23+
curl -fsSL "$URL" -o "$OUTFILE"
24+
return $?
25+
elif [[ "$METHOD" == "api" ]]; then
26+
: "${GITHUB_TOKEN:?GITHUB_TOKEN is required for API access}"
27+
curl -fsSL -H "Authorization: token $GITHUB_TOKEN" \
28+
-H "Accept: application/vnd.github.v3.raw" \
29+
"$URL" -o "$OUTFILE"
30+
return $?
31+
else
32+
log_message "Error: Unsupported method '$METHOD' encountered for URL '$URL'. Halting execution."
33+
exit 2
34+
fi
35+
}
36+
1737
TMP_FILES=()
1838
trap 'rm -f "${TMP_FILES[@]}"' EXIT
1939
for USER in "${!USER_KEYS[@]}"; do
2040
TMP_FILE=$(mktemp)
2141
TMP_FILES+=("$TMP_FILE")
22-
URL="${USER_KEYS[$USER]}"
42+
ENTRY="${USER_KEYS[$USER]}"
43+
METHOD="${ENTRY%%:*}"
44+
URL="${ENTRY#*:}"
2345
# Ensure user exists
2446
if ! id "$USER" &>/dev/null; then
2547
log_message "User '$USER' does not exist. Skipping."
@@ -41,17 +63,18 @@ for USER in "${!USER_KEYS[@]}"; do
4163
log_message "Created .ssh directory for user '$USER'"
4264
fi
4365

44-
# Fetch remote key file
45-
if curl -fsSL "$URL" -o "$TMP_FILE"; then
46-
if [ ! -f "$AUTH_KEYS" ] || ! cmp -s "$TMP_FILE" "$AUTH_KEYS"; then
47-
cp "$TMP_FILE" "$AUTH_KEYS"
48-
chown "$USER:$USER" "$AUTH_KEYS"
49-
chmod 600 "$AUTH_KEYS"
50-
log_message "Updated authorized_keys for user '$USER'"
51-
else
52-
log_message "No changes for user '$USER'"
53-
fi
66+
log_message "Fetching key file for $USER from $URL (method: $METHOD)"
67+
if ! fetch_key_file "$METHOD" "$URL" "$TMP_FILE"; then
68+
log_message "Failed to fetch key file for user '$USER' from $URL. Skipping."
69+
continue
70+
fi
71+
72+
if [ ! -f "$AUTH_KEYS" ] || ! cmp -s "$TMP_FILE" "$AUTH_KEYS"; then
73+
cp "$TMP_FILE" "$AUTH_KEYS"
74+
chown "$USER:$USER" "$AUTH_KEYS"
75+
chmod 600 "$AUTH_KEYS"
76+
log_message "Updated authorized_keys for user '$USER'"
5477
else
55-
log_message "Failed to download keys for '$USER' from $URL"
78+
log_message "No changes for user '$USER'"
5679
fi
5780
done

0 commit comments

Comments
 (0)