Canonical laptop configuration for ops team members.
Before starting, ensure you have:
- USB memory stick - 8GB+ for bootable Fedora installer
- GitHub account - create at github.com if needed
- Org membership - ask your team lead to add you to Concurrent-Systems org
- Deskguard access - ask your team lead to grant you access to the deskguard repo
Once you have access, proceed with the setup below.
| Spec | Minimum | Recommended |
|---|---|---|
| RAM | 16GB | 32GB |
| Storage | 256GB SSD | 512GB SSD |
| Display | 14" | 15.6" |
No vendor preference - Linux-friendly laptops work well (ThinkPad, HP ProBook, Dell Latitude).
Fedora Xfce Spin - lightweight, stable, good hardware support.
Why Xfce Spin? Fedora "Spins" are alternative versions with different desktop environments. The default Fedora Workstation uses GNOME (heavier, more RAM). Xfce Spin uses the Xfce desktop - lighter, faster, ideal for ops laptops. Same Fedora underneath, just a different UI.
- Download ISO from Fedora Spins (Fedora 43 as of Jan 2026)
Linux users: Follow steps 2-5 below. Windows/Mac users: Use Fedora Media Writer instead (handles steps 2-5 automatically), then skip to step 6.
-
Verify checksum (from the directory where you downloaded the ISO):
curl -sL https://download.fedoraproject.org/pub/fedora/linux/releases/43/Spins/x86_64/iso/Fedora-Spins-43-1.6-x86_64-CHECKSUM | grep Xfce | sha256sum -c
Should output:
Fedora-Xfce-Live-43-1.6.x86_64.iso: OK -
Find your USB device:
lsblk
Identify your USB (e.g.,
sdborsdc). Careful - wrong device will destroy data! -
Write ISO to USB:
sudo dd if=Fedora-Xfce-Live-43-1.6.x86_64.iso of=/dev/sdX bs=4M status=progress oflag=sync
Replace
sdXwith your USB device (e.g.,sdb). -
Verify USB write:
sudo cmp -n $(stat -c %s Fedora-Xfce-Live-43-1.6.x86_64.iso) Fedora-Xfce-Live-43-1.6.x86_64.iso /dev/sdX && echo "USB verified OK"
Must show
USB verified OKbefore proceeding. -
Boot from USB:
- Reboot and press F9 (HP), F12, or Esc repeatedly for boot menu
- Select USB device
- Media check should pass (we verified the USB)
-
UEFI settings (if needed): Disable Secure Boot, enable virtualization (VT-x/AMD-V).
-
Install Fedora:
- Select "Install to Hard Drive"
- Language: English
- Installation Destination: Select your drive, "Use entire disk" (wipes everything - no dual boot)
- Encryption: Check "Encrypt my data" - enter a strong passphrase (4-5 random words)
- Write this passphrase down immediately - required at every boot
- Store in KeePassXC after setup
- Create user:
{firstname}{lastinit}(e.g.,omaira) with your full name - Set a strong password (remember it!)
- Wait for completion, reboot, remove USB when prompted
-
Set hostname (after first boot into Fedora):
sudo hostnamectl set-hostname {username}-{machinetype} # Example: sudo hostnamectl set-hostname omaira-probook
If boot fails with "media check FAIL": Re-download ISO, verify checksum, try a different USB stick.
If stuck during install: Take a photo of the screen, reboot back to previous OS (remove USB), share photo for help.
Update all packages first. Reboot after this step if kernel was updated:
sudo dnf upgrade -y
sudo rebootNote: First reboot after kernel updates may occasionally kernel panic. If this happens, hard restart - it typically resolves on second boot.
# Enable Docker CE repo (dnf5 syntax for Fedora 41+)
sudo dnf config-manager addrepo --from-repofile=https://download.docker.com/linux/fedora/docker-ce.repo
# Install core tools
sudo dnf install -y git gh docker-ce docker-ce-cli containerd.io \
kubernetes-client vim curl jq keepassxc firefox
# Start Docker
sudo systemctl enable --now docker
sudo usermod -aG docker $USER
# Apply docker group without logging out
newgrp dockerVerify docker works:
docker run hello-world| Secret | Where to Store | Why |
|---|---|---|
| LUKS disk passphrase | Paper in physical safe | If forgotten, can't boot - KeePassXC is on encrypted disk |
| KeePassXC master password | Memory + paper in safe | Same reason - needed to access everything else |
| SSH key passphrases | KeePassXC (local) | If lost, regenerate keys and submit new PR |
Never store LUKS or KeePassXC master password only on the encrypted machine - you won't be able to access it if you forget.
Set up your password manager before generating SSH keys - you'll need it to store passphrases.
mkdir -p ~/.keys
chmod 700 ~/.keys
keepassxc &- File → New Database
- Save as
~/.keys/personal.kdbx - Set a strong master password (memorize this one)
Create this group and entry structure:
personal.kdbx
├── SSH Keys/
│ ├── GitHub (passphrase for ~/.ssh/id_github)
│ ├── CS-Jump (passphrase for ~/.ssh/id_csjump)
│ └── Sites (passphrase for ~/.ssh/id_sites)
└── Sites/
└── Master Secret (your secret suffix for node passwords)
To create:
- Right-click Root → New Group → name it
SSH Keys - Create another group
Sites - Add a
Master Secretentry with a generated passphrase
Every node MUST have a unique password. Never reuse the same password across nodes.
Use a derived pattern so you only need to remember one secret:
{nodename}-{master-secret}
For example, if your master secret is purpleElephant42:
- movtog-cspr01 →
movtog-cspr01-purpleElephant42 - movngr-cspr02 →
movngr-cspr02-purpleElephant42 - movivy-cstst01 →
movivy-cstst01-purpleElephant42
This gives you:
- Unique password per node (security requirement)
- Only one secret to store in KeePassXC
- If one node is compromised, other nodes remain protected
- Easy to construct when prompted
For each SSH key passphrase, use KeePassXC's generator:
- Create new entry in
SSH Keysgroup - Set Title (e.g.,
GitHub) - Click the dice icon next to Password
- Select "Passphrase" tab
- Word count: 4-5 words
- Click "Apply Password"
- Save the entry
You'll use this process for each SSH key you create below.
| Item | Convention | Example |
|---|---|---|
| Username | {firstname}{lastinit} |
omaira |
| Hostname | {username}-{machinetype} |
omaira-probook |
Machine types: probook, thinkpad, latitude, xps, macbook, etc.
Use your username consistently for git commits, SSH keys, and server accounts.
You can either use your existing personal GitHub account or create a new one for work.
Option A: Use your personal account (recommended for most devs)
- Your contributions appear on your profile (career value)
- Add your company email as a secondary email in GitHub Settings → Emails
- Use the company email for git config (commits linked to your account)
- On leaving: company removes org access, you keep your profile
Option B: Create a new work account
- Clean separation between work and personal
- Use company email as the primary email
- On leaving: account can be transferred or removed
- No contribution history carries over
Either option is fine. Most developers prefer Option A to maintain a single profile. GitHub supports multiple emails per account specifically for this use case.
git config --global user.name "Your Full Name"
git config --global user.email "[email protected]"
git config --global init.defaultBranch mainNote: Use your real full name (e.g., "Khurram Shahzad"), not a username or handle. Use your company email regardless of which GitHub account option you choose. This ensures commits are traceable to the organisation.
If you contribute to open source or have personal hobby projects (or contractors working with multiple clients), use Git's conditional includes to automatically switch emails based on directory:
~/.gitconfig:
[user]
name = Your Full Name
email = [email protected]
[includeIf "gitdir:~/g/"]
path = ~/.gitconfig-cs~/.gitconfig-cs:
[user]
email = [email protected]Now any repo under ~/g/ uses your CS email automatically, while personal projects elsewhere use your personal email. Add additional includeIf blocks for other organisations as needed.
First, authenticate with GitHub CLI:
gh auth loginSelect:
- GitHub.com
- HTTPS
- Login with a web browser
This stores an OAuth token in ~/.config/gh/hosts.yml. The gh CLI uses this token for API calls (issues, PRs, etc). Later, you'll set up SSH keys for git operations.
mkdir -p ~/github
gh repo clone Concurrent-Systems/deskguard ~/github/deskguard
cd ~/github/deskguardNow generate all your SSH keys. For each key, use KeePassXC to generate a passphrase and save it.
Replace {username} and {machine} with your values (e.g., omaira and probook):
# GitHub key
ssh-keygen -t ed25519 -C "{username}-{machine}-github" -f ~/.ssh/id_github
# Bastion key
ssh-keygen -t ed25519 -C "{username}-{machine}-csjump" -f ~/.ssh/id_csjump
# Sites key
ssh-keygen -t ed25519 -C "{username}-{machine}-sites" -f ~/.ssh/id_sitesSave each passphrase in KeePassXC under SSH Keys/:
GitHubCS-JumpSites
The script creates your entire ~/.ssh/config with proper permissions:
cd ~/github/deskguard
python3 ssh-config-gen.py {username}Add your GitHub SSH key to your account:
gh ssh-key add ~/.ssh/id_github.pub --title "{username}-{machine}"Add to ~/.bashrc for persistence:
echo '
# Start ssh-agent if not running
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)"
fi' >> ~/.bashrc
source ~/.bashrcAdd your keys (you'll be prompted for passphrases):
ssh-add ~/.ssh/id_github
ssh-add ~/.ssh/id_csjump
ssh-add ~/.ssh/id_sitesmacOS users: Use
ssh-add --apple-use-keychaininstead - see SSH-KEYS.md.
ssh -T [email protected]Should show: Hi {username}! You've successfully authenticated...
Submit your public keys for provisioning on the servers:
cd ~/github/deskguard
python3 ssh-config-gen.py {username} --submit-keysThis validates your keys, copies them to keys/{username}/, and pushes to main.
Wait for your team lead to confirm your keys have been provisioned on the servers.
Once provisioned:
ssh cs-jump echo "Jump host OK"Run the security audit and submit your assessment:
cd ~/github/deskguard
git checkout main
git pull
python3 deskguard.py --username {firstname}-{lastname} --submitThis runs security checks and automatically creates a PR with your report.
After your SSH keys are provisioned, you can clone the main infra repo:
mkdir -p ~/g
git clone [email protected]:Concurrent-Systems/infra.git ~/g/infra
cd ~/g/infra
git submodule update --init software/deskguardYou'll get access to additional submodules as needed for your role.
- No VPN needed - all access via SSH ProxyJump through cs-jump
- Standard toolset: git, docker, kubectl, vim, curl, jq
- For ops CLI tools, use the infra repo (run commands from repo root)